QkCircuit
typedef struct QkCircuit QkCircuitEl elemento fundamental de la informática cuántica es el circuito cuántico. Se trata de una rutina computacional que puede ejecutarse, disparo a disparo, en una unidad de procesamiento cuántico (QPU). Un circuito actuará sobre una cantidad predefinida de datos cuánticos (en Qiskit, sólo admitimos qubits directamente) con operaciones unitarias (puertas), mediciones y reinicios. Además, un circuito cuántico puede contener operaciones sobre datos clásicos, incluidos cálculos en tiempo real y construcciones de flujo de control, que son ejecutadas por los controladores de la QPU. La estructura QkCircuit expone una interfaz de bajo nivel a la estructura de datos del circuito cuántico de Qiskit y expone sólo lo que se define en el modelo de datos interno de Qiskit. Por lo tanto, le falta alguna funcionalidad que está disponible en el nivel superior Python QuantumCircuit superior.
A continuación se muestra un ejemplo de circuito cuántico que realiza un estado Greenberger-Horne-Zeilinger (GHZ) de tres qubits definido como:
#include <qiskit.h>
// Create a circuit with three qubits and 3 classical bits
QkCircuit *qc = qk_circuit_new(3, 0);
// H gate on qubit 0, putting this qubit in a superposition of |0> + |1>.
qk_circuit_gate(qc, QkGate_H, (uint32_t[]){0}, NULL);
// A CX (CNOT) gate on control qubit 0 and target qubit 1 generating a Bell state.
qk_circuit_gate(qc, QkGate_CX, (uint32_t[]){0, 1}, NULL);
// A CX (CNOT) gate on control qubit 0 and target qubit 2 generating a GHZ state.
qk_circuit_gate(qc, QkGate_CX, (uint32_t[]){0, 2}, NULL);
// Free the created circuit.
qk_circuit_free(qc);Actualmente, la API C de circuitos sólo admite la creación de circuitos que contengan operaciones definidas en el modelo de datos Rust interno de Qiskit. Por lo general, sólo se incluyen las compuertas de la biblioteca de compuertas estándar, las operaciones estándar no unitarias (actualmente Barrier, Measure, Resety Delay) y UnitaryGate. Esta funcionalidad se ampliará con el tiempo a medida que el modelo de datos de Rust se amplíe para soportar de forma nativa más funcionalidades.
Tipos de datos
QkOpCount
struct QkOpCount
Un recuento de operaciones individuales representado por el nombre de la operación y el número de instancias en el circuito.
const char *nombre
Una cadena terminada en nul que representa el nombre de la operación
tamaño_t recuento
El número de instancias de esta operación en el circuito
QkOpCounts
struct QkOpCounts
Matriz de objetos OpCount que representa el recuento total de todos los tipos de operaciones de un circuito.
QkOpCount *datos
Una matriz de tamaño len que contiene objetos OpCount para cada tipo de operación en el circuito
tamaño_t longitud
El número de elementos en data
QkCircuitInstruction
struct QkCircuitInstruction
Una representación de instrucciones de circuito.
Esta estructura representa los datos contenidos en una instrucción individual en QkCircuit. No es un puntero al objeto subyacente, sino que contiene una copia de las propiedades de la instrucción para su inspección.
carácter *nombre
El nombre de la instrucción
uint32_t *qubits
Un puntero a una matriz de índices de qubits sobre los que opera esta instrucción.
uint32_t *clbits
Un puntero a una matriz de índices clbit sobre los que opera esta instrucción.
QkParam **parámetros
Un puntero a una matriz de valores de parámetros para esta instrucción.
uint32_t número_de_qubits
El número de qubits para esta instrucción.
uint32_t num_clbits
El número de clbits para esta instrucción.
uint32_t número_de_parámetros
El número de parámetros para esta instrucción.
QkCircuitDrawerConfig
struct QkCircuitDrawerConfig
Las opciones de configuración de la qk_circuit_draw función.
bool paquete_cregs
Si true, agrupa los registros clásicos en un solo cable.
bool fusionar_cables
Si true, une las líneas inferiores y superiores de los cables adyacentes.
tamaño_t plegado
Establece la longitud de línea para el ajuste de texto del texto renderizado. Utiliza el valor 0 para detectar automáticamente el ancho de la consola. Utiliza SIZE_MAX para evitar por completo el ajuste de línea.
Funciones
QkDelayUnit
enum QkDelayUnit
Unidades para retardos de circuito.
Valores:
enumerador QkDelayUnit_S
Segundos.
enumerador QkDelayUnit_MS
milliseconds.
enumerador QkDelayUnit_US
Microsegundos.
enumerador QkDelayUnit_NS
Nanosegundos.
enumerador QkDelayUnit_PS
Picosegundos.
QkVarsMode
enum QkVarsMode
El modo para copiar las variables clásicas, para operaciones que crean un nuevo circuito basado en uno ya existente.
Valores:
enumerador QkVarsMode_Alike
Cada variable tiene el mismo tipo que tenía en la entrada.
enumerador QkVarsMode_Captures
Cada variable se convierte en una «captura».
enumerador QkVarsMode_Drop
No copie los datos variables.
QkBlocksMode
enum QkBlocksMode
El modo que se debe utilizar para copiar bloques en instrucciones de flujo de control, para operaciones que crean un nuevo circuito basado en uno ya existente.
Valores:
enumerador QkBlocksMode_Drop
Suelta los bloques.
enumerador QkBlocksMode_Keep
Guarda los bloques.
qk_circuit_new
QkCircuit *qk_circuit_new(uint32_t num_qubits, uint32_t num_clbits)
Construye un nuevo circuito con el número dado de qubits y clbits.
Ejemplo
QkCircuit *empty = qk_circuit_new(100, 100);Parámetros
- num_qubits - El número de qubits que contiene el circuito.
- num_clbits - El número de clbits que contiene el circuito.
Vuelve
Un puntero al circuito creado.
qk_circuit_add_quantum_register
void qk_circuit_add_quantum_register(QkCircuit *circuit, const QkQuantumRegister *reg)
Añadir un registro cuántico a un circuito cuántico dado
Ejemplo
QkCircuit *qc = qk_circuit_new(0, 0);
QkQuantumRegister *qr = qk_quantum_register_new(1024, "my_little_register");
qk_circuit_add_quantum_register(qc, qr);
qk_quantum_register_free(qr);
qk_circuit_free(qc);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a un QkCircuit y si reg no es un puntero válido y no nulo a un QkQuantumRegister.
Parámetros
- circuito - Un puntero al circuito.
- reg - Un puntero al registro cuántico
qk_circuit_add_classical_register
void qk_circuit_add_classical_register(QkCircuit *circuit, const QkClassicalRegister *reg)
Añadir un registro clásico a un circuito cuántico dado
Ejemplo
QkCircuit *qc = qk_circuit_new(0, 0);
QkClassicalRegister *cr = qk_classical_register_new(24, "my_big_register");
qk_circuit_add_classical_register(qc, cr);
qk_classical_register_free(cr);
qk_circuit_free(qc);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a un QkCircuit y si reg no es un puntero válido y no nulo a un QkClassicalRegister.
Parámetros
- circuito - Un puntero al circuito.
- reg - Puntero al registro clásico
qk_circuit_copy
QkCircuit *qk_circuit_copy(const QkCircuit *circuit)
Crear una copia de un QkCircuit.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 100);
QkCircuit *copy = qk_circuit_copy(qc);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito a copiar.
Vuelve
Un nuevo puntero a una copia de la entrada circuit.
qk_circuit_num_qubits
uint32_t qk_circuit_num_qubits(const QkCircuit *circuit)
Obtiene el número de qubits que contiene el circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 100);
uint32_t num_qubits = qk_circuit_num_qubits(qc); // num_qubits==100Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito.
Vuelve
Número de qubits en los que se define el circuito.
qk_circuit_num_clbits
uint32_t qk_circuit_num_clbits(const QkCircuit *circuit)
Obtiene el número de clbits que contiene el circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 50);
uint32_t num_clbits = qk_circuit_num_clbits(qc); // num_clbits==50Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito.
Vuelve
Número de qubits en los que se define el circuito.
qk_circuit_num_param_symbols
size_t qk_circuit_num_param_symbols(const QkCircuit *circuit)
Obtén el número de símbolos sin asignar en QkParam los objetos del circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(2, 0);
QkParam *x = qk_param_new_symbol("x");
QkParam *y = qk_param_new_symbol("y");
uint32_t q0[1] = {0};
const QkParam *rx_param[1] = {x};
const QkParam *ry_param[1] = {y};
qk_circuit_parameterized_gate(qc, QkGate_RX, q0, rx_param);
qk_circuit_parameterized_gate(qc, QkGate_RY, q0, ry_param);
// check the number of QkParam symbols
size_t num_symbols = qk_circuit_num_param_symbols(qc); // == 2
qk_param_free(x);
qk_param_free(y);
qk_circuit_free(qc);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito.
Vuelve
El número de símbolos QkParam sin asignar en el circuito.
qk_circuit_free
void qk_circuit_free(QkCircuit *circuit)
Libera el circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 100);
qk_circuit_free(qc);Seguridad
El comportamiento es indefinido si circuit no es null o un puntero válido a QkCircuit.
Parámetros
- circuito - Un puntero al circuito a liberar.
qk_circuit_gate
QkExitCode qk_circuit_gate(QkCircuit *circuit, QkGate gate, const uint32_t *qubits, const double *params)
Añade un QkGate al circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);Seguridad
Se espera que los tipos qubits y params sean un puntero a una matriz de uint32_t y double respectivamente cuya longitud coincida con las expectativas de la puerta estándar. Si el array no es suficientemente largo, el comportamiento de esta función es indefinido, ya que leerá fuera de los límites del array. Puede ser un puntero nulo si no hay qubits o parámetros para una puerta determinada. Puede consultar qk_gate_num_qubits y qk_gate_num_params para determinar cuántos qubits y parámetros son necesarios para una puerta determinada.
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuit - Un puntero al circuito al que añadir la puerta.
- puerta - El StandardGate para añadir al circuito.
- qubits - El puntero a la matriz de
uint32_tíndices qubit para añadir la puerta. Puede ser un puntero nulo si no hay qubits paragate(por ejemplo,QkGate_GlobalPhase). - params - El puntero a la matriz de valores
doublea utilizar para los parámetros de la puerta. Puede ser un puntero nulo si no hay parámetros paragate(por ejemplo,QkGate_H).
Vuelve
Un código de salida.
qk_circuit_parameterized_gate
QkExitCode qk_circuit_parameterized_gate(QkCircuit *circuit, QkGate gate, const uint32_t *qubits, const QkParam *const *params)
Añade un QkGate con QkParam* parámetros al circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 0);
QkParam *theta = qk_param_new_symbol("theta");
uint32_t qubit[1] = {0};
const QkParam* params[1] = {theta};
qk_circuit_parameterized_gate(qc, QkGate_RX, qubit, params); // add RX(theta) to the circuitSeguridad
Se espera que los qubits``params tipos y sean un puntero a una matriz de uint32_t y, QkParam* respectivamente, cuya longitud se ajuste a lo previsto para la puerta estándar. Si la matriz no tiene suficiente longitud, el comportamiento de esta función es indefinido, ya que se leerá fuera de los límites de la matriz. Puede ser un puntero nulo si no hay qubits ni parámetros para una puerta determinada. Puedes consultar qk_gate_num_qubits y qk_gate_num_params para determinar cuántos qubits y parámetros se necesitan para una puerta determinada.
El comportamiento es indefinido si no circuit es un puntero válido y no nulo a un QkCircuit, o si alguno de los elementos de la params matriz no es un puntero válido y no nulo a un QkParam.
Parámetros
- circuit - Un puntero al circuito al que añadir la puerta.
- puerta – La
QkGateque hay que añadir al circuito. - qubits - El puntero a la matriz de
uint32_tíndices qubit para añadir la puerta. Puede ser un puntero nulo si no hay qubits paragate(por ejemplo,QkGate_GlobalPhase). - params : el puntero a la matriz de
QkParam*parámetros que se utilizará para los parámetros de la puerta. Esto puede ser un puntero nulo si no hay parámetros (gatepor ejemploQkGate_H).
Vuelve
QkExitCode_Success una vez completada la adición. En caso de error, QkExitCode_ParameterNameConflict indica que un nuevo símbolo de parámetro tiene un conflicto de nombres con uno ya existente. QkExitCode_ParameterError describe otros errores generales que pueden producirse al intentar rastrear los símbolos de los parámetros.
qk_gate_num_qubits
uint32_t qk_gate_num_qubits(QkGate gate)
Obtenga el número de qubits para un QkGate.
Ejemplo
uint32_t num_qubits = qk_gate_num_qubits(QkGate_CCX);Parámetros
- gate - El
QkGatepara obtener el número de qubits.
Vuelve
Número de qubits sobre los que actúa la puerta.
qk_gate_num_params
uint32_t qk_gate_num_params(QkGate gate)
Obtener el número de parámetros para un QkGate.
Ejemplo
uint32_t num_params = qk_gate_num_params(QkGate_R);Parámetros
- gate - El
QkGatepara obtener el número de qubits.
Vuelve
Número de parámetros de la puerta.
qk_circuit_measure
QkExitCode qk_circuit_measure(QkCircuit *circuit, uint32_t qubit, uint32_t clbit)
Añadir una medida al circuito
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 1);
qk_circuit_measure(qc, 0, 0);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito al que añadir la medición
- qubit - El
uint32_tpara el qubit a medir - clbit - El
uint32_tpara el clbit para almacenar el resultado de la medición en
Vuelve
Un código de salida.
qk_circuit_reset
QkExitCode qk_circuit_reset(QkCircuit *circuit, uint32_t qubit)
Añadir un reset al circuito
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 0);
qk_circuit_reset(qc, 0);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuit - Un puntero al circuito al que añadir el reset
- qubit - El
uint32_tpara que el qubit se reinicie
Vuelve
Un código de salida.
qk_circuit_barrier
QkExitCode qk_circuit_barrier(QkCircuit *circuit, const uint32_t *qubits, uint32_t num_qubits)
Añade una barrera al circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 1);
uint32_t qubits[5] = {0, 1, 2, 3, 4};
qk_circuit_barrier(qc, qubits, 5);Seguridad
La longitud de la matriz a la que apunta qubits debe ser num_qubits. Si hay un desajuste, el comportamiento es indefinido.
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuit - Un puntero al circuito al que añadir la barrera.
- num_qubits - El número de qubits de ancho de la barrera.
- qubits - El puntero a la matriz de
uint32_tíndices qubit para añadir la barrera.
Vuelve
Un código de salida.
qk_circuit_unitary
QkExitCode qk_circuit_unitary(QkCircuit *circuit, const QkComplex64 *matrix, const uint32_t *qubits, uint32_t num_qubits, bool check_input)
Añade una matriz unitaria arbitraria al circuito.
Ejemplo
QkComplex64 c0 = {0, 0}; // 0+0i
QkComplex64 c1 = {1, 0}; // 1+0i
const uint32_t num_qubits = 1;
QkComplex64 unitary[2*2] = {c0, c1, // row 0
c1, c0}; // row 1
QkCircuit *circuit = qk_circuit_new(1, 0); // 1 qubit circuit
uint32_t qubit[1] = {0}; // qubit to apply the unitary on
qk_circuit_unitary(circuit, unitary, qubit, num_qubits, true);Seguridad
El comportamiento es indefinido si se incumple alguna de las siguientes condiciones:
circuites un puntero válido y no nulo a un archivoQkCircuitmatrixes un puntero alineado a valores4**num_qubitsQkComplex64inicializadosqubitses un puntero alineado a valoresnum_qubitsuint32_tinicializados
Parámetros
- circuit - Un puntero al circuito al que añadir el unitario.
- matrix - Puntero a la matriz
QkComplex64que representa la matriz unitaria. Debe tratarse de una matriz unitaria mayor de dimensión2 ^ num_qubits x 2 ^ num_qubits. Más explícitamente: el(i, j)-ésimo elemento viene dado pormatrix[i * 2^n + j]. El contenido dematrixse copia dentro de esta función antes de ser añadido al circuito, por lo que el llamante mantiene la propiedad de la memoria original a la que apuntamatrixy puede reutilizarla después de la llamada y el llamante es responsable de liberarla. - qubits - Puntero a una matriz de índices de qubits, de longitud
num_qubits. - num_qubits - El número de qubits sobre los que actúa el unitario.
- check\input - Cuando es verdadero, la función verifica que la matriz es unitaria. Si se establece a False el llamador es responsable de asegurar que la matriz es unitaria, si la matriz no es unitaria este es un comportamiento indefinido y resultará en un circuito corrupto.
Vuelve
Un código de salida.
qk_circuit_inst_unitary
void qk_circuit_inst_unitary(QkCircuit *circuit, size_t index, QkComplex64 *out)
Escribe la matriz unitaria correspondiente a una instrucción determinada del circuito.
Da un error si la instrucción en el índice indicado no es unitaria.
Seguridad
El comportamiento es indefinido si se incumple alguna de las siguientes condiciones: si no circuit es un puntero válido y no nulo a un QkCircuit, si index se sale de los límites del número de instrucciones del circuito, si no out es válido para 4**num_qubits escrituras de QkComplex64.
Parámetros
- circuito : un puntero al circuito del que se va a obtener la función unitaria.
- índice : el índice de la instrucción para la que se desea obtener la unidad.
- out – Puntero asignado y alineado en el que se escribirá la matriz unitaria.
qk_circuit_instruction_kind
QkOperationKind qk_circuit_instruction_kind(const QkCircuit *circuit, size_t index)
Aprende el «tipo» de instrucción de circuito.
Seguridad
El comportamiento es indefinido si no circuit es un puntero válido y distinto de nulo a un QkCircuit y si index excede el límite del número de instrucciones del circuito.
Parámetros
- circuito : un puntero al circuito del que se obtiene el tipo de instrucción.
- índice : el índice de la instrucción cuyo tipo se desea obtener.
Vuelve
Un valor QkOperationKind de enumeración que representa el tipo de instrucción en el índice indicado.
qk_circuit_count_ops
QkOpCounts qk_circuit_count_ops(const QkCircuit *circuit)
Devuelve una lista de nombres de cadena para las instrucciones de un circuito y sus recuentos.
Para liberar correctamente la memoria asignada por la estructura, debe llamar a qk_opcounts_clear. Soltar la estructura QkOpCounts sin hacer esto dejará la matriz almacenada de QkOpCount asignada y producirá una fuga de memoria.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubits[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubits, NULL);
QkOpCounts counts = qk_circuit_count_ops(qc);
// .. once done
qk_opcounts_clear(&counts);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito del que obtener los recuentos.
Vuelve
Una estructura QkOpCounts que contiene los recuentos de operaciones del circuito.
qk_circuit_num_instructions
size_t qk_circuit_num_instructions(const QkCircuit *circuit)
Devuelve el número total de instrucciones del circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);
size_t num = qk_circuit_num_instructions(qc); // 1Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuit - Puntero al circuito del que se desea obtener el número total de instrucciones.
Vuelve
El número total de instrucciones del circuito.
qk_circuit_get_instruction
void qk_circuit_get_instruction(const QkCircuit *circuit, size_t index, QkCircuitInstruction *instruction)
Devuelve los detalles de una instrucción del circuito.
Esta función se utiliza para obtener los detalles de una instrucción dada en el circuito.
Esta función asigna memoria internamente para el QkCircuitInstruction proporcionado y por lo tanto usted es responsable de llamar a qk_circuit_instruction_clear para liberarla.
Ejemplo
QkCircuitInstruction inst;
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);
qk_circuit_get_instruction(qc, 0, &inst);
qk_circuit_instruction_clear(&inst);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit. El valor de index debe ser menor que el valor devuelto por qk_circuit_num_instructions , de lo contrario esta función entrará en pánico. El comportamiento es indefinido si instruction no es un puntero válido y no nulo a una asignación de memoria con espacio suficiente para un QkCircuitInstruction.
Parámetros
- circuit - Un puntero al circuito del que obtener los detalles de la instrucción.
- index - El índice de la instrucción para obtener los detalles de la instrucción.
- un puntero a donde escribir la instrucción
QkCircuitInstruction
qk_circuit_pauli_product_rotation
void qk_circuit_pauli_product_rotation(QkCircuit *circuit, const QkPauliProductRotation *rotation, const uint32_t *qubits)
Aplicar un QkPauliProductRotation a un circuito.
Ejemplo
// build a IXYZ Pauli rotation
bool x[4] = {false, true, true, false};
bool z[4] = {false, false, true, true};
QkParam *angle = qk_param_from_double(1.0);
QkPauliProductRotation rotation = {x, z, 4, angle};
// append it to a circuit
QkCircuit *circuit = qk_circuit_new(10, 1);
uint32_t qubits[4] = {0, 1, 2, 3};
qk_circuit_pauli_product_rotation(circuit, &rotation, qubits);
// do something with the circuit... and then free it
qk_param_free(angle);
qk_circuit_free(circuit);Seguridad
El comportamiento es indefinido si se incumple alguna de las siguientes condiciones:
circuites un puntero válido y no nulo a un archivoQkCircuitrotationes un puntero válido y no nulo a un objeto coherenteQkPauliProductRotation. En concreto, las matrices derotation->zrotation->xdatos y deben poder leerse pararotation->lenelementos.qubitses un puntero alineado a valoresrotation->lenuint32_tinicializados.
Parámetros
- circuito : el circuito al que se aplicará la operación.
- rotación : un puntero a la rotación
QkPauliProductRotationque se va a aplicar. - qubits : un puntero a la matriz de qubits.
qk_circuit_inst_pauli_product_rotation
QkExitCode qk_circuit_inst_pauli_product_rotation(const QkCircuit *circuit, size_t index, QkPauliProductRotation *instruction)
Obtén los QkPauliProductRotation datos de una instrucción de circuito.
En un circuito que contenga una QkPauliProductRotation instrucción en el índice index, esta función asignará al instruction puntero una copia de QkPauliProductRotation los datos. Ten en cuenta que estos datos son independientes del circuito y deben liberarse manualmente con qk_pauli_product_rotation_clear.
Si la instrucción en la dirección indicada **no **index es un QkPauliProductRotation, esta función devolverá QkExitCode_InvalidOperationKind un error. Puedes comprobar que la instrucción es del tipo correcto utilizando qk_circuit_instruction_kind.
Seguridad
El comportamiento es indefinido si no circuit es un puntero válido y no nulo a un QkCircuit. El valor de index debe ser inferior al valor devuelto por; de qk_circuit_num_instructions lo contrario, esta función generará un error. El comportamiento es indefinido si no instruction es un puntero válido y no nulo a una asignación de memoria con espacio suficiente para un QkPauliProductRotation.
Parámetros
- circuito : un puntero al circuito del que se van a recuperar los detalles de la instrucción.
- índice : el índice de instrucciones del circuito.
- instrucción : un puntero a un espacio de memoria asignado
QkPauliProductRotationpara almacenar los datos.
Vuelve
QkExitCode_Success si los datos se escribieron en la instrucción, o QkExitCode_InvalidOperationKind si el índice no apuntaba a un QkPauliProductRotation.
qk_circuit_pauli_product_measurement
void qk_circuit_pauli_product_measurement(QkCircuit *circuit, const QkPauliProductMeasurement *measurement, const uint32_t *qubits, uint32_t clbit)
Aplicar un QkPauliProductMeasurement a un circuito.
Ejemplo
// build a XZ Pauli measurement
bool x[2] = {true, false};
bool z[2] = {false, true};
QkPauliProductMeasurement measure = {x, z, 2, false};
// append it to a circuit
QkCircuit *circuit = qk_circuit_new(10, 1);
uint32_t qubits[2] = {0, 2};
uint32_t clbit = 0;
qk_circuit_pauli_product_measurement(circuit, &measure, qubits, clbit);
// do something with the circuit... and then free it
qk_circuit_free(circuit);Seguridad
El comportamiento es indefinido si se incumple alguna de las siguientes condiciones:
circuites un puntero válido y no nulo a un archivoQkCircuitmeasurementes un puntero válido y no nulo a un objeto coherenteQkPauliProductMeasurement. En concreto, las matrices demeasurement->zmeasurement->xdatos y deben poder leerse parameasurement->lenelementos.qubitses un puntero alineado a valoresrotation->lenuint32_tinicializados.
Parámetros
- circuito : el circuito al que se aplicará la operación.
- medida : un indicador de la medida
QkPauliProductMeasurementque se debe aplicar. - qubits : un puntero a la matriz de qubits.
- clbit : un único
uint32_tque especifica el qubit de medición.
qk_circuit_inst_pauli_product_measurement
QkExitCode qk_circuit_inst_pauli_product_measurement(const QkCircuit *circuit, size_t index, QkPauliProductMeasurement *instruction)
Obtén los QkPauliProductMeasurement datos de una instrucción de circuito.
En un circuito que contenga una QkPauliProductMeasurement instrucción en el índice index, esta función asignará al instruction puntero una copia de QkPauliProductMeasurement los datos. Ten en cuenta que estos datos, que son independientes del circuito, deben liberarse manualmente con qk_pauli_product_measurement_clear.
Si la instrucción en la dirección indicada **no **index es un QkPauliProductMeasurement, esta función devolverá QkExitCode_InvalidOperationKind un error. Comprueba que la instrucción sea del tipo correcto utilizando qk_circuit_instruction_kind.
Seguridad
El comportamiento es indefinido si no circuit es un puntero válido y no nulo a un QkCircuit. El valor de index debe ser inferior al valor devuelto por; de qk_circuit_num_instructions lo contrario, esta función generará un error. El comportamiento es indefinido si no instruction es un puntero válido y no nulo a una asignación de memoria con espacio suficiente para un QkPauliProductMeasurement.
Parámetros
- circuito : un puntero al circuito del que se van a recuperar los detalles de la instrucción.
- índice : el índice de instrucciones del circuito.
- instrucción : un puntero a un espacio de memoria asignado
QkPauliProductMeasurementpara almacenar los datos.
Vuelve
QkExitCode_Success si los datos se escribieron en la instrucción, o QkExitCode_InvalidOperationKind si el índice no apuntaba a un QkPauliProductMeasurement.
qk_circuit_instruction_clear
void qk_circuit_instruction_clear(QkCircuitInstruction *inst)
Borra los datos del objeto de instrucción de circuito.
Esta función no libera la asignación para el puntero QkCircuitInstruction proporcionado, sólo libera las asignaciones internas para los datos contenidos en la instrucción. Usted es responsable de asignar y liberar la asignación real utilizada para almacenar un QkCircuitInstruction.
Ejemplo
QkCircuitInstruction *inst = malloc(sizeof(QkCircuitInstruction));
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t q0[1] = {0};
qk_circuit_gate(qc, QkGate_H, q0, NULL);
qk_circuit_get_instruction(qc, 0, inst);
qk_circuit_instruction_clear(inst); // clear internal allocations
free(inst); // free struct
qk_circuit_free(qc); // free the circuitSeguridad
El comportamiento es indefinido si inst no es un puntero válido y no nulo a QkCircuitInstruction.
Parámetros
- inst - Un puntero a la instrucción a liberar.
qk_opcounts_clear
void qk_opcounts_clear(QkOpCounts *op_counts)
Borrar el contenido de una lista de recuento de operaciones de circuito.
Seguridad
El comportamiento es indefinido si op_counts no es el objeto devuelto por qk_circuit_count_ops.
Parámetros
- op\counts - La lista de recuentos de operaciones devuelta por
qk_circuit_count_ops.
qk_circuit_delay
QkExitCode qk_circuit_delay(QkCircuit *circuit, uint32_t qubit, double duration, QkDelayUnit unit)
Añade una instrucción de retardo al circuito.
Ejemplo
QkCircuit *qc = qk_circuit_new(1, 0);
qk_circuit_delay(qc, 0, 100.0, QkDelayUnit_NS);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuit - Un puntero al circuito al que añadir el retardo.
- qubit - El índice
uint32_tdel qubit al que se aplicará el retardo. - duración - La duración del retraso.
- unidad - Enum que representa la unidad de la duración.
Vuelve
Un código de salida.
qk_circuit_draw
char *qk_circuit_draw(const QkCircuit *circuit, const QkCircuitDrawerConfig *config)
Dibuja el circuito en forma de texto.
Ejemplo
QkCircuit *circuit = qk_circuit_new(2, 1);
qk_circuit_gate(circuit, QkGate_H, (uint32_t[]){0}, NULL);
qk_circuit_gate(circuit, QkGate_CX, (uint32_t[]){0, 1}, NULL);
qk_circuit_measure(circuit, 0, 0);
qk_circuit_measure(circuit, 1, 0);
QkCircuitDrawerConfig config = {false, true, 0};
char *circ_str = qk_circuit_draw(circuit, &config);
printf("%s", circ_str);
qk_str_free(circ_str);
qk_circuit_free(circuit);Seguridad
El comportamiento es indefinido si no circuit es un puntero válido y no nulo a una QkCircuit, o si no config es NULL y es un puntero no válido a una QkCircuitDrawerConfig struct.
Parámetros
-
circuito : un puntero al circuito que se va a dibujar.
-
config : un puntero a la
QkCircuitDrawerConfigestructura o NULL. Si el valor es NULL, el cajón utilizará estos valores predeterminados:bundle_cregs = truemerge_wires = truefold = 0
Vuelve
Un puntero a una cadena terminada en nulo que contiene la representación del circuito. Debes utilizar qk_str_free para liberar la memoria asignada cuando hayas terminado.
qk_circuit_to_dag
QkDag *qk_circuit_to_dag(const QkCircuit *circuit)
Convertir un circuito dado en un DAG.
El nuevo DAG se copia del circuito; la referencia circuit original sigue siendo propiedad del llamante y sigue siendo necesario liberarla con qk_circuit_free. Debe liberar el DAG devuelto con qk_dag_free cuando haya terminado de utilizarlo.
Ejemplo
QkCircuit *qc = qk_circuit_new(0, 0);
QkQuantumRegister *qr = qk_quantum_register_new(3, "qr");
qk_circuit_add_quantum_register(qc, qr);
qk_quantum_register_free(qr);
QkDag *dag = qk_circuit_to_dag(qc);
qk_dag_free(dag);
qk_circuit_free(qc);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito : un puntero al circuito a partir del cual se creará el DAG.
Vuelve
Un puntero al nuevo DAG.
qk_circuit_copy_empty_like
QkCircuit *qk_circuit_copy_empty_like(const QkCircuit *circuit, QkVarsMode vars_mode, QkBlocksMode blocks_mode)
Devuelve una copia de sí mismo con la misma estructura, pero vacía.
Esa estructura incluye:
- fase global
- todos los qubits y clbits, incluidos los registros.
Ejemplo
QkCircuit *qc = qk_circuit_new(10, 10);
for (int i = 0; i < 10; i++) {
qk_circuit_measure(qc, i, i);
uint32_t qubits[1] = {i};
qk_circuit_gate(qc, QkGate_H, qubits, NULL);
}
// As the circuit does not contain any control-flow instructions,
// vars_mode and blocks_mode do not have any effect.
QkCircuit *copy = qk_circuit_copy_empty_like(qc, QkVarsMode_Alike, QkBlocksMode_Drop);
size_t num_copy_instructions = qk_circuit_num_instructions(copy); // 0
// do something with the copy
qk_circuit_free(qc);
qk_circuit_free(copy);Seguridad
El comportamiento es indefinido si circuit no es un puntero válido y no nulo a QkCircuit.
Parámetros
- circuito - Un puntero al circuito a copiar.
- vars_mode : modo para manejar variables clásicas.
- blocks_mode : modo para gestionar bloques.
Vuelve
El puntero al circuito copiado.
qk_circuit_to_python
PyObject *qk_circuit_to_python(QkCircuit *qc)
Pasa la propiedad de un QkCircuit objeto a « Python ».
El objeto Python resultante no es QuantumCircuit, sino el objeto interno CircuitData, al que normalmente se accede como QuantumCircuit._data. Puedes utilizar qk_circuit_to_python_full para crear un objeto QuantumCircuit completo.
No es seguro utilizar el QkCircuit puntero después de llamar a esta función. En particular, no debes intentar borrarlo ni liberarlo. El autor de la llamada debe ser el propietario del objeto QkCircuit, y no tener una referencia prestada (por ejemplo, un objeto QkCircuit * recuperado de no qk_circuit_borrow_from_python es de su propiedad).
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no circuit es un puntero válido y no nulo a un objeto inicializado y del que se tiene propiedad QkCircuit.
Parámetros
- qc – El objeto en cuestión.
Vuelve
Una referencia de tipo « Python » al objeto.
qk_circuit_to_python_full
PyObject *qk_circuit_to_python_full(QkCircuit *qc)
Pasa la propiedad de un QkCircuit objeto a « Python » y crea un completo QuantumCircuit.
Esto incluye una lógica adicional del espacio de Python para obtener el espacio completo QuantumCircuit, ya que QkCircuit corresponde únicamente al campo QuantumCircuit._data interno.
No es seguro utilizar el QkCircuit puntero después de llamar a esta función. En particular, no debes intentar borrarlo ni liberarlo. El autor de la llamada debe ser el propietario del objeto QkCircuit, y no tener una referencia prestada (por ejemplo, un objeto QkCircuit * recuperado de no qk_circuit_borrow_from_python es de su propiedad).
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no circuit es un puntero válido y no nulo a un objeto inicializado y del que se tiene propiedad QkCircuit.
Parámetros
- qc – El objeto en cuestión.
Vuelve
Una referencia de tipo « Python » al objeto.
qk_circuit_borrow_from_python
QkCircuit *qk_circuit_borrow_from_python(PyObject *ob)
Obtener un QkCircuit puntero de un objeto Python.
Ten en cuenta que la entrada de esta función no debe ser QuantumCircuit, sino la salida de QuantumCircuit._data. Esto es necesario para garantizar el correcto funcionamiento de la semántica del recuento de referencias.
Esto toma prestada una referencia de tipo « Python » y extrae el QkCircuit puntero correspondiente, siempre que sea del tipo adecuado. El puntero devuelto se toma prestado del ob puntero. Si el PyObject tipo no es el correcto, el valor de retorno es NULL y se establece el estado de excepción del intérprete de Python.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes utilizar qk_circuit_convert_from_python, que lógicamente es exactamente igual que esta función, pero que se puede emplear directamente como función «convertidora» para la PyArg_Parse* familia de funciones de conversión de Python.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no ob es un puntero válido y no nulo a un objeto Python.
Parámetros
- ob : un objeto de tipo « Python » tomado de otro lenguaje.
Vuelve
Un puntero al objeto nativo, o bien, NULL si el objeto Python es de un tipo incorrecto.
qk_circuit_convert_from_python
int qk_circuit_convert_from_python(PyObject *object, void *address)
Obtener un QkCircuit puntero de un objeto Python.
Ten en cuenta que la entrada de esta función no debe ser QuantumCircuit, sino la salida de QuantumCircuit._data. Esto es necesario para garantizar el correcto funcionamiento de la semántica del recuento de referencias.
Esto toma prestada una referencia de tipo « Python » y extrae el QkCircuit puntero correspondiente a address, siempre que sea del tipo correcto. El puntero devuelto se toma prestado del object puntero. Si no es PyObject del tipo correcto, el valor de retorno es 0, se establece el estado de excepción del intérprete de Python, y address no sufre cambios.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes usar qk_circuit_borrow_from_python, que, lógicamente, es exactamente lo mismo que esto, pero con una sintaxis más natural para su uso directo.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no object es un puntero válido y no nulo a un objeto Python, o si no address es un puntero a datos modificables del tipo correcto.
Parámetros
- objeto : un objeto de tipo
Pythontomado en préstamo. - dirección : la ubicación en la que se escribirá la salida.
Vuelve
1 si se realiza correctamente, 0 si falla.
qk_quantum_register_to_python
PyObject *qk_quantum_register_to_python(QkQuantumRegister *qr)
Pasa la propiedad de un QkQuantumRegister objeto a « Python ».
No es seguro utilizar el QkQuantumRegister puntero después de llamar a esta función. En particular, no debes intentar borrarlo ni liberarlo. El autor de la llamada debe ser el propietario del objeto QkQuantumRegister, y no tener una referencia prestada (por ejemplo, un objeto QkQuantumRegister * recuperado de no qk_quantum_register_borrow_from_python es de su propiedad).
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no qr es un puntero válido y no nulo a un objeto inicializado y del que se tiene propiedad QkQuantumRegister.
Parámetros
- qr – El objeto en cuestión.
Vuelve
Una referencia de tipo « Python » al objeto.
qk_quantum_register_borrow_from_python
const QkQuantumRegister *qk_quantum_register_borrow_from_python(PyObject *ob)
Obtener un QkQuantumRegister puntero de un objeto Python.
Esto toma prestada una referencia de tipo « Python » y extrae el QkQuantumRegister puntero correspondiente, siempre que sea del tipo adecuado. El puntero devuelto se toma prestado del ob puntero. Si el PyObject tipo no es el correcto, el valor de retorno es NULL y se establece el estado de excepción del intérprete de Python.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes utilizar qk_quantum_register_convert_from_python, que lógicamente es exactamente igual que esta función, pero que se puede emplear directamente como función «convertidora» para la PyArg_Parse* familia de funciones de conversión de Python.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no ob es un puntero válido y no nulo a un objeto Python.
Parámetros
- ob : un objeto de tipo « Python » tomado de otro lenguaje.
Vuelve
Un puntero al objeto nativo, o bien, NULL si el objeto Python es de un tipo incorrecto.
qk_quantum_register_convert_from_python
int qk_quantum_register_convert_from_python(PyObject *object, void *address)
Obtener un QkQuantumRegister puntero de un objeto Python.
Esto toma prestada una referencia de tipo « Python » y extrae el QkQuantumRegister puntero correspondiente a address, siempre que sea del tipo correcto. El puntero devuelto se toma prestado del object puntero. Si no es PyObject del tipo correcto, el valor de retorno es 0, se establece el estado de excepción del intérprete de Python, y address no sufre cambios.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes usar qk_quantum_register_borrow_from_python, que, lógicamente, es exactamente lo mismo que esto, pero con una sintaxis más natural para su uso directo.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no object es un puntero válido y no nulo a un objeto Python, o si no address es un puntero a datos modificables del tipo correcto.
Parámetros
- objeto : un objeto de tipo
Pythontomado en préstamo. - dirección : la ubicación en la que se escribirá la salida.
Vuelve
1 si se realiza correctamente, 0 si falla.
qk_classical_register_to_python
PyObject *qk_classical_register_to_python(QkClassicalRegister *cr)
Pasa la propiedad de un QkClassicalRegister objeto a « Python ».
No es seguro utilizar el QkClassicalRegister puntero después de llamar a esta función. En particular, no debes intentar borrarlo ni liberarlo. El autor de la llamada debe ser el propietario del objeto QkClassicalRegister, y no tener una referencia prestada (por ejemplo, un objeto QkClassicalRegister * recuperado de no qk_classical_register_borrow_from_python es de su propiedad).
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no cr es un puntero válido y no nulo a un objeto inicializado y del que se tiene propiedad QkClassicalRegister.
Parámetros
- cr – El objeto en cuestión.
Vuelve
Una referencia de tipo « Python » al objeto.
qk_classical_register_borrow_from_python
const QkClassicalRegister *qk_classical_register_borrow_from_python(PyObject *ob)
Obtener un QkClassicalRegister puntero de un objeto Python.
Esto toma prestada una referencia de tipo « Python » y extrae el QkClassicalRegister puntero correspondiente, siempre que sea del tipo adecuado. El puntero devuelto se toma prestado del ob puntero. Si el PyObject tipo no es el correcto, el valor de retorno es NULL y se establece el estado de excepción del intérprete de Python.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes utilizar qk_classical_register_convert_from_python, que lógicamente es exactamente igual que esta función, pero que se puede emplear directamente como función «convertidora» para la PyArg_Parse* familia de funciones de conversión de Python.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no ob es un puntero válido y no nulo a un objeto Python.
Parámetros
- ob : un objeto de tipo « Python » tomado de otro lenguaje.
Vuelve
Un puntero al objeto nativo, o bien, NULL si el objeto Python es de un tipo incorrecto.
qk_classical_register_convert_from_python
int qk_classical_register_convert_from_python(PyObject *object, void *address)
Obtener un QkClassicalRegister puntero de un objeto Python.
Esto toma prestada una referencia de tipo « Python » y extrae el QkClassicalRegister puntero correspondiente a address, siempre que sea del tipo correcto. El puntero devuelto se toma prestado del object puntero. Si no es PyObject del tipo correcto, el valor de retorno es 0, se establece el estado de excepción del intérprete de Python, y address no sufre cambios.
Para llamar a esta función, debes estar conectado a un intérprete de Python.
También puedes usar qk_classical_register_borrow_from_python, que, lógicamente, es exactamente lo mismo que esto, pero con una sintaxis más natural para su uso directo.
Seguridad
La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no object es un puntero válido y no nulo a un objeto Python, o si no address es un puntero a datos modificables del tipo correcto.
Parámetros
- objeto : un objeto de tipo
Pythontomado en préstamo. - dirección : la ubicación en la que se escribirá la salida.
Vuelve
1 si se realiza correctamente, 0 si falla.