QkCircuit
typedef struct QkCircuit QkCircuitO elemento fundamental da computação quântica é o circuito quântico. Essa é uma rotina de computação que pode ser executada, uma tentativa por vez, em uma unidade de processamento quântico (QPU). Um circuito atuará em uma quantidade predefinida de dados quânticos (no Qiskit, só oferecemos suporte direto a qubits) com operações unitárias (portas), medições e redefinições. Além disso, um circuito quântico pode conter operações em dados clássicos, incluindo computações em tempo real e construções de fluxo de controle, que são executadas pelos controladores da QPU. A estrutura QkCircuit expõe uma interface de baixo nível para a estrutura de dados do circuito quântico do Qiskit e expõe somente o que está definido no modelo de dados interno do Qiskit. Portanto, faltam algumas funcionalidades que estão disponíveis na classe de nível superior Python QuantumCircuit classe.
Abaixo está um exemplo de um circuito quântico que produz um estado Greenberger-Horne-Zeilinger (GHZ) de três 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);Atualmente, a API do circuito C só oferece suporte à criação de circuitos que contenham operações definidas no modelo de dados Rust interno do Qiskit. Em geral, isso inclui apenas portas na biblioteca de portas padrão, operações não unitárias padrão (atualmente Barrier, Measure, Reset, e Delay) e UnitaryGate. Essa funcionalidade será ampliada com o tempo, à medida que o modelo de dados do Rust for expandido para oferecer suporte nativo a mais funcionalidades.
Tipos de dados
QkOpCount
struct QkOpCount
Uma contagem de operação individual representada pelo nome da operação e o número de instâncias no circuito.
const char *nome
Uma cadeia de caracteres com terminação nula que representa o nome da operação
tamanho_t contagem
O número de instâncias dessa operação no circuito
QkOpCounts
struct QkOpCounts
Uma matriz de objetos OpCount que representa as contagens totais de todos os tipos de operação em um circuito.
QkOpCount *dados
Uma matriz de tamanho len contendo objetos OpCount para cada tipo de operação no circuito
tamanho_t comprimento
O número de elementos em data
QkCircuitInstruction
struct QkCircuitInstruction
Uma representação de instruções de circuito.
Essa estrutura representa os dados contidos em uma instrução individual em um site QkCircuit. Não é um ponteiro para o objeto subjacente, mas contém uma cópia das propriedades da instrução para inspeção.
char *nome
O nome da instrução
uint32_t *qubits
Um ponteiro para uma matriz de índices de qubit em que essa instrução opera.
uint32_t *clbits
Um ponteiro para uma matriz de índices de clbit em que essa instrução opera.
QkParam **parâmetros
Um ponteiro para uma matriz de valores de parâmetros para essa instrução.
uint32_t número de qubits
O número de qubits para essa instrução.
uint32_t num_clbits
O número de clbits para essa instrução.
uint32_t num_parâmetros
O número de parâmetros para essa instrução.
QkCircuitDrawerConfig
struct QkCircuitDrawerConfig
As opções de configuração da qk_circuit_draw função.
bool bundle_cregs
Se true, agrupa os registros clássicos em fios individuais.
bool merge_wires
Se true, une as linhas inferior e superior dos fios adjacentes.
size_t fold
Define o comprimento da linha para o quebra automático do texto renderizado. Use 0 para detectar automaticamente a largura do console. Use SIZE_MAX para evitar completamente o quebra automático de linha.
Funções
QkDelayUnit
enum QkDelayUnit
Unidades para atrasos de circuitos.
Valores:
enumerador QkDelayUnit_S
Segundos.
enumerador QkDelayUnit_MS
Milissegundos.
enumerador QkDelayUnit_US
Microssegundos.
enumerador QkDelayUnit_NS
Nanossegundos.
enumerador QkDelayUnit_PS
Picossegundos.
QkVarsMode
enum QkVarsMode
O modo para copiar as variáveis clássicas, para operações que criam um novo circuito com base em um já existente.
Valores:
enumerador QkVarsMode_Alike
Cada variável tem o mesmo tipo que tinha na entrada.
enumerador QkVarsMode_Captures
Cada variável se torna uma “captura”.
enumerador QkVarsMode_Drop
Não copie os dados variáveis.
QkBlocksMode
enum QkBlocksMode
O modo a ser usado para copiar blocos em instruções de fluxo de controle, para operações que criam um novo circuito com base em um já existente.
Valores:
enumerador QkBlocksMode_Drop
Solte os blocos.
enumerador QkBlocksMode_Keep
Guarde os blocos.
qk_circuit_new
QkCircuit *qk_circuit_new(uint32_t num_qubits, uint32_t num_clbits)
Construa um novo circuito com o número dado de qubits e clbits.
Exemplo
QkCircuit *empty = qk_circuit_new(100, 100);Parâmetros
- num_qubits - O número de qubits que o circuito contém.
- num_clbits - O número de clbits que o circuito contém.
**Retornos
Um ponteiro para o circuito criado.
qk_circuit_add_quantum_register
void qk_circuit_add_quantum_register(QkCircuit *circuit, const QkQuantumRegister *reg)
Adicione um registro quântico a um determinado circuito quântico
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para QkCircuit e se reg não for um ponteiro válido e não nulo para QkQuantumRegister.
Parâmetros
- circuito - Um ponteiro para o circuito.
- reg - Um ponteiro para o registro quântico
qk_circuit_add_classical_register
void qk_circuit_add_classical_register(QkCircuit *circuit, const QkClassicalRegister *reg)
Adicione um registro clássico a um determinado circuito quântico
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para QkCircuit e se reg não for um ponteiro válido e não nulo para QkClassicalRegister.
Parâmetros
- circuito - Um ponteiro para o circuito.
- reg - Um ponteiro para o registro clássico
qk_circuit_copy
QkCircuit *qk_circuit_copy(const QkCircuit *circuit)
Criar uma cópia de um QkCircuit.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 100);
QkCircuit *copy = qk_circuit_copy(qc);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito a ser copiado.
**Retornos
Um novo ponteiro para uma cópia da entrada circuit.
qk_circuit_num_qubits
uint32_t qk_circuit_num_qubits(const QkCircuit *circuit)
Obtenha o número de qubits que o circuito contém.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 100);
uint32_t num_qubits = qk_circuit_num_qubits(qc); // num_qubits==100Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito.
**Retornos
O número de qubits em que o circuito é definido.
qk_circuit_num_clbits
uint32_t qk_circuit_num_clbits(const QkCircuit *circuit)
Obtém o número de clbits que o circuito contém.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 50);
uint32_t num_clbits = qk_circuit_num_clbits(qc); // num_clbits==50Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito.
**Retornos
O número de qubits em que o circuito é definido.
qk_circuit_num_param_symbols
size_t qk_circuit_num_param_symbols(const QkCircuit *circuit)
Obtenha o número de símbolos não vinculados nos QkParam objetos do circuito.
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito.
**Retornos
O número de símbolos não QkParam vinculados no circuito.
qk_circuit_free
void qk_circuit_free(QkCircuit *circuit)
Libere o circuito.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 100);
qk_circuit_free(qc);Segurança
O comportamento é indefinido se circuit não for nulo ou um ponteiro válido para QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito a ser liberado.
qk_circuit_gate
QkExitCode qk_circuit_gate(QkCircuit *circuit, QkGate gate, const uint32_t *qubits, const double *params)
Acrescente um QkGate ao circuito.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 0);
uint32_t qubit[1] = {0};
qk_circuit_gate(qc, QkGate_H, qubit, NULL);Segurança
Espera-se que os tipos qubits e params sejam um ponteiro para uma matriz de uint32_t e double , respectivamente, em que o comprimento corresponda às expectativas da porta padrão. Se a matriz for insuficientemente longa, o comportamento dessa função é indefinido, pois ela lerá fora dos limites da matriz. Pode ser um ponteiro nulo se não houver qubits ou parâmetros para uma determinada porta. Você pode consultar qk_gate_num_qubits e qk_gate_num_params para determinar quantos qubits e parâmetros são necessários para uma determinada porta.
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual adicionar a porta.
- gate - O StandardGate a ser adicionado ao circuito.
- qubits - O ponteiro para a matriz de
uint32_tíndices de qubit para adicionar a porta. Pode ser um ponteiro nulo se não houver qubits paragate(por exemplo,QkGate_GlobalPhase). - params - O ponteiro para a matriz de valores
doublea serem usados para os parâmetros da porta. Pode ser um ponteiro nulo se não houver parâmetros paragate(por exemplo,QkGate_H).
**Retornos
Um código de saída.
qk_circuit_parameterized_gate
QkExitCode qk_circuit_parameterized_gate(QkCircuit *circuit, QkGate gate, const uint32_t *qubits, const QkParam *const *params)
Adicione um QkGate com QkParam* parâmetros ao circuito.
Exemplo
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 circuitSegurança
Espera-se que os qubits``params tipos e sejam, respectivamente, um ponteiro QkParam* para uma matriz de uint32_t e, em que o comprimento corresponda às especificações da porta padrão. Se o comprimento da matriz for insuficiente, o comportamento desta função é indefinido, pois ela lerá além dos limites da matriz. Pode ser um ponteiro nulo se não houver qubits ou parâmetros para uma determinada porta lógica. Você pode consultar qk_gate_num_qubits e qk_gate_num_params para determinar quantos qubits e parâmetros são necessários para uma determinada porta lógica.
O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um QkCircuit, ou se qualquer um dos elementos da params matriz não for um ponteiro válido e diferente de nulo para um QkParam.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual adicionar a porta.
- porta – A
QkGatea ser adicionada ao circuito. - qubits - O ponteiro para a matriz de
uint32_tíndices de qubit para adicionar a porta. Pode ser um ponteiro nulo se não houver qubits paragate(por exemplo,QkGate_GlobalPhase). - params – O ponteiro para a matriz de
QkParam*parâmetros a ser usada para os parâmetros da porta. Isso pode ser um ponteiro nulo se não houver parâmetros paragate(por exemplo,QkGate_H).
**Retornos
QkExitCode_Success após a adição bem-sucedida. Em caso de falha, QkExitCode_ParameterNameConflict indica que um novo símbolo de parâmetro apresenta um conflito de nome com um já existente. QkExitCode_ParameterError descreve outras falhas genéricas que podem ocorrer ao tentar rastrear os símbolos dos parâmetros.
qk_gate_num_qubits
uint32_t qk_gate_num_qubits(QkGate gate)
Obtenha o número de qubits para um QkGate.
Exemplo
uint32_t num_qubits = qk_gate_num_qubits(QkGate_CCX);Parâmetros
- gate - O endereço
QkGatepara obter o número de qubits.
**Retornos
O número de qubits em que a porta atua.
qk_gate_num_params
uint32_t qk_gate_num_params(QkGate gate)
Obtenha o número de parâmetros para um QkGate.
Exemplo
uint32_t num_params = qk_gate_num_params(QkGate_R);Parâmetros
- gate - O endereço
QkGatepara obter o número de qubits.
**Retornos
O número de parâmetros que a porta possui.
qk_circuit_measure
QkExitCode qk_circuit_measure(QkCircuit *circuit, uint32_t qubit, uint32_t clbit)
Anexar uma medição ao circuito
Exemplo
QkCircuit *qc = qk_circuit_new(100, 1);
qk_circuit_measure(qc, 0, 0);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual adicionar a medição
- qubit - O endereço
uint32_tpara o qubit a ser medido - clbit - O endereço
uint32_tpara o clbit para armazenar o resultado da medição em
**Retornos
Um código de saída.
qk_circuit_reset
QkExitCode qk_circuit_reset(QkCircuit *circuit, uint32_t qubit)
Anexar uma reinicialização ao circuito
Exemplo
QkCircuit *qc = qk_circuit_new(100, 0);
qk_circuit_reset(qc, 0);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual adicionar a reinicialização
- qubit - O endereço
uint32_tpara que o qubit seja redefinido
**Retornos
Um código de saída.
qk_circuit_barrier
QkExitCode qk_circuit_barrier(QkCircuit *circuit, const uint32_t *qubits, uint32_t num_qubits)
Acrescente uma barreira ao circuito.
Exemplo
QkCircuit *qc = qk_circuit_new(100, 1);
uint32_t qubits[5] = {0, 1, 2, 3, 4};
qk_circuit_barrier(qc, qubits, 5);Segurança
O comprimento da matriz para a qual qubits aponta deve ser num_qubits. Se houver uma incompatibilidade, o comportamento será indefinido.
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual adicionar a barreira.
- num_qubits - O número de qubits de largura da barreira.
- qubits - O ponteiro para a matriz de
uint32_tíndices de qubit para adicionar a barreira.
**Retornos
Um código de saída.
qk_circuit_unitary
QkExitCode qk_circuit_unitary(QkCircuit *circuit, const QkComplex64 *matrix, const uint32_t *qubits, uint32_t num_qubits, bool check_input)
Acrescente uma matriz unitária arbitrária ao circuito.
Exemplo
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);Segurança
O comportamento é indefinido se qualquer um dos itens a seguir for violado:
circuité um ponteiro válido e não nulo para umQkCircuitmatrixé um ponteiro alinhado para valores4**num_qubitsQkComplex64inicializadosqubitsé um ponteiro alinhado para valoresnum_qubitsuint32_tinicializados
Parâmetros
- circuito - Um ponteiro para o circuito ao qual anexar a unidade.
- matrix - Um ponteiro para a matriz
QkComplex64que representa a matriz unitária. Essa deve ser uma matriz unitária de dimensão2 ^ num_qubits x 2 ^ num_qubits. Mais explicitamente: o(i, j)-ésimo elemento é dado pormatrix[i * 2^n + j]. O conteúdo dematrixé copiado dentro dessa função antes de ser adicionado ao circuito, de modo que o chamador mantém a propriedade da memória original para a qualmatrixaponta e pode reutilizá-la após a chamada, e o chamador é responsável por liberá-la. - qubits - Um ponteiro para a matriz de índices de qubit, de comprimento
num_qubits. - num_qubits - O número de qubits em que o unitário atua.
- check_input - Quando verdadeira, a função verifica se a matriz é unitária. Se definido como False, o chamador será responsável por garantir que a matriz seja unitária; se a matriz não for unitária, esse será um comportamento indefinido e resultará em um circuito corrompido.
**Retornos
Um código de saída.
qk_circuit_inst_unitary
void qk_circuit_inst_unitary(QkCircuit *circuit, size_t index, QkComplex64 *out)
Copie a matriz unitária correspondente a uma determinada instrução no circuito.
Gera um erro se a instrução no índice especificado não for unitária.
Segurança
O comportamento é indefinido se qualquer uma das seguintes condições for violada: se não circuit for um ponteiro válido e diferente de nulo para um QkCircuit, se index estiver fora dos limites para o número de instruções no circuito, se não out for válido para 4**num_qubits gravações em QkComplex64.
Parâmetros
- circuito – Um ponteiro para o circuito do qual se deseja obter a função unitária.
- índice – O índice da instrução para a qual se deseja obter a função unitária.
- out – Ponteiro alocado e alinhado para o qual a matriz unitária será gravada.
qk_circuit_instruction_kind
QkOperationKind qk_circuit_instruction_kind(const QkCircuit *circuit, size_t index)
Obtenha o “tipo” de instrução de circuito.
Segurança
O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um QkCircuit e se index estiver fora dos limites do número de instruções no circuito.
Parâmetros
- circuito – Um ponteiro para o circuito do qual se deseja obter o tipo de instrução.
- índice – O índice da instrução cujo tipo se deseja obter.
**Retornos
Um valor QkOperationKind de enumeração que representa o tipo de instrução no índice especificado.
qk_circuit_count_ops
QkOpCounts qk_circuit_count_ops(const QkCircuit *circuit)
Retorna uma lista de nomes de strings para instruções em um circuito e suas contagens.
Para liberar corretamente a memória alocada pelo struct, você deve chamar qk_opcounts_clear. A eliminação da estrutura QkOpCounts sem fazer isso deixará a matriz armazenada de QkOpCount alocada e produzirá um vazamento de memória.
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito para obter as contagens.
**Retornos
Uma estrutura QkOpCounts que contém as contagens de operação do circuito.
qk_circuit_num_instructions
size_t qk_circuit_num_instructions(const QkCircuit *circuit)
Retorna o número total de instruções no circuito.
Exemplo
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); // 1Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito para obter o número total de instruções.
**Retornos
O número total de instruções no circuito.
qk_circuit_get_instruction
void qk_circuit_get_instruction(const QkCircuit *circuit, size_t index, QkCircuitInstruction *instruction)
Retorna os detalhes da instrução para uma instrução no circuito.
Essa função é usada para obter os detalhes da instrução para uma determinada instrução no circuito.
Essa função aloca memória internamente para o site QkCircuitInstruction fornecido e, portanto, você é responsável por chamar qk_circuit_instruction_clear para liberá-la.
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit. O valor de index deve ser menor que o valor retornado por qk_circuit_num_instructions , caso contrário, essa função entrará em pânico. O comportamento é indefinido se instruction não for um ponteiro válido e não nulo para uma alocação de memória com espaço suficiente para um QkCircuitInstruction.
Parâmetros
- circuito - Um ponteiro para o circuito para obter os detalhes da instrução.
- index - O índice da instrução para obter os detalhes da instrução.
- instrução - Um ponteiro para onde escrever o
QkCircuitInstruction
qk_circuit_pauli_product_rotation
void qk_circuit_pauli_product_rotation(QkCircuit *circuit, const QkPauliProductRotation *rotation, const uint32_t *qubits)
Aplicar um QkPauliProductRotation a um circuito.
Exemplo
// 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);Segurança
O comportamento é indefinido se qualquer um dos itens a seguir for violado:
circuité um ponteiro válido e não nulo para umQkCircuitrotationé um ponteiro válido e não nulo para um objeto coerenteQkPauliProductRotation. Especificamente, as matrizes derotation->zrotation->xdados e devem conterrotation->lenelementos.qubitsé um ponteiro alinhado a valoresrotation->lenuint32_tinicializados.
Parâmetros
- circuito – O circuito ao qual a operação será aplicada.
- rotação – Um ponteiro para a rotação
QkPauliProductRotationa ser aplicada. - qubits – Um ponteiro para a matriz de qubits.
qk_circuit_inst_pauli_product_rotation
QkExitCode qk_circuit_inst_pauli_product_rotation(const QkCircuit *circuit, size_t index, QkPauliProductRotation *instruction)
Obter os QkPauliProductRotation dados de uma instrução de circuito.
Para um circuito com uma QkPauliProductRotation instrução no índice index, esta função preencherá o instruction ponteiro com uma cópia dos QkPauliProductRotation dados. Observe que esses dados são independentes do circuito e devem ser liberados manualmente com qk_pauli_product_rotation_clear.
Se a instrução no endereço fornecido **não **index for um QkPauliProductRotation, esta função retornará QkExitCode_InvalidOperationKind um erro. Você pode verificar se a instrução é do tipo correto usando qk_circuit_instruction_kind.
Segurança
O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um QkCircuit. O valor de index deve ser menor que o valor retornado por; qk_circuit_num_instructions caso contrário, esta função entrará em pânico. O comportamento é indefinido se não instruction for um ponteiro válido e diferente de nulo para uma alocação de memória com espaço suficiente para um QkPauliProductRotation.
Parâmetros
- circuito – Um ponteiro para o circuito do qual se deseja recuperar os detalhes da instrução.
- índice – O índice da instrução do circuito.
- instrução – Um ponteiro para uma área de memória alocada
QkPauliProductRotationpara armazenar os dados.
**Retornos
QkExitCode_Success se os dados foram gravados na instrução, ou QkExitCode_InvalidOperationKind se o índice não apontava para um 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 um QkPauliProductMeasurement a um circuito.
Exemplo
// 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);Segurança
O comportamento é indefinido se qualquer um dos itens a seguir for violado:
circuité um ponteiro válido e não nulo para umQkCircuitmeasurementé um ponteiro válido e não nulo para um objeto coerenteQkPauliProductMeasurement. Especificamente, as matrizes demeasurement->zmeasurement->xdados e devem contermeasurement->lenelementos.qubitsé um ponteiro alinhado a valoresrotation->lenuint32_tinicializados.
Parâmetros
- circuito – O circuito ao qual a operação será aplicada.
- medição – Um ponteiro para a
QkPauliProductMeasurementa ser aplicada. - qubits – Um ponteiro para a matriz de qubits.
- clbit – Um único qubit
uint32_tque especifica a medida.
qk_circuit_inst_pauli_product_measurement
QkExitCode qk_circuit_inst_pauli_product_measurement(const QkCircuit *circuit, size_t index, QkPauliProductMeasurement *instruction)
Obter os QkPauliProductMeasurement dados de uma instrução de circuito.
Para um circuito com uma QkPauliProductMeasurement instrução no índice index, esta função preencherá o instruction ponteiro com uma cópia dos QkPauliProductMeasurement dados. Observe que esses dados são independentes do circuito e devem ser liberados manualmente com qk_pauli_product_measurement_clear.
Se a instrução no endereço fornecido **não **index for um QkPauliProductMeasurement, esta função retornará QkExitCode_InvalidOperationKind um erro. Verifique se a instrução é do tipo correto usando qk_circuit_instruction_kind.
Segurança
O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um QkCircuit. O valor de index deve ser menor que o valor retornado por; qk_circuit_num_instructions caso contrário, esta função entrará em pânico. O comportamento é indefinido se não instruction for um ponteiro válido e diferente de nulo para uma alocação de memória com espaço suficiente para um QkPauliProductMeasurement.
Parâmetros
- circuito – Um ponteiro para o circuito do qual se deseja recuperar os detalhes da instrução.
- índice – O índice da instrução do circuito.
- instrução – Um ponteiro para uma área de memória alocada
QkPauliProductMeasurementpara armazenar os dados.
**Retornos
QkExitCode_Success se os dados foram gravados na instrução, ou QkExitCode_InvalidOperationKind se o índice não apontava para um QkPauliProductMeasurement.
qk_circuit_instruction_clear
void qk_circuit_instruction_clear(QkCircuitInstruction *inst)
Limpar os dados no objeto de instrução do circuito.
Essa função não libera a alocação para o ponteiro QkCircuitInstruction fornecido, apenas libera as alocações internas para os dados contidos na instrução. Você é responsável por alocar e liberar a alocação real usada para armazenar um QkCircuitInstruction.
Exemplo
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 circuitSegurança
O comportamento é indefinido se inst não for um ponteiro válido e não nulo para um QkCircuitInstruction.
Parâmetros
- inst - Um ponteiro para a instrução a ser liberada.
qk_opcounts_clear
void qk_opcounts_clear(QkOpCounts *op_counts)
Limpar o conteúdo de uma lista de contagem de operações de circuito.
Segurança
O comportamento é indefinido se op_counts não for o objeto retornado por qk_circuit_count_ops.
Parâmetros
- op_counts - A lista de contagem de operações retornada de
qk_circuit_count_ops.
qk_circuit_delay
QkExitCode qk_circuit_delay(QkCircuit *circuit, uint32_t qubit, double duration, QkDelayUnit unit)
Acrescentar uma instrução de atraso ao circuito.
Exemplo
QkCircuit *qc = qk_circuit_new(1, 0);
qk_circuit_delay(qc, 0, 100.0, QkDelayUnit_NS);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito ao qual será adicionado o atraso.
- qubit - O índice
uint32_tdo qubit ao qual aplicar o atraso. - duração - A duração do atraso.
- unit - Um enum que representa a unidade da duração.
**Retornos
Um código de saída.
qk_circuit_draw
char *qk_circuit_draw(const QkCircuit *circuit, const QkCircuitDrawerConfig *config)
Desenhe o circuito como texto.
Exemplo
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);Segurança
O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para uma QkCircuit, ou se não config for NULL e for um ponteiro inválido para uma QkCircuitDrawerConfig struct.
Parâmetros
-
circuito – Um ponteiro para o circuito a ser desenhado.
-
config – Um ponteiro para a
QkCircuitDrawerConfigestrutura ou NULL. Se for NULL, o aplicativo utilizará estes valores padrão:bundle_cregs = truemerge_wires = truefold = 0
**Retornos
Um ponteiro para uma string terminada em null que contém a representação do circuito. Você deve usar qk_str_free para liberar a memória alocada quando terminar.
qk_circuit_to_dag
QkDag *qk_circuit_to_dag(const QkCircuit *circuit)
Converta um determinado circuito em um DAG.
O novo DAG é copiado do circuito; a referência circuit original ainda pertence ao chamador e ainda precisa ser liberada com qk_circuit_free. Você deve liberar o DAG retornado com qk_dag_free quando terminar de usá-lo.
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito – Um ponteiro para o circuito a partir do qual criar o DAG.
**Retornos
Um ponteiro para o novo DAG.
qk_circuit_copy_empty_like
QkCircuit *qk_circuit_copy_empty_like(const QkCircuit *circuit, QkVarsMode vars_mode, QkBlocksMode blocks_mode)
Retorna uma cópia de si mesmo com a mesma estrutura, mas vazia.
Essa estrutura inclui:
- fase global
- todos os qubits e clbits, incluindo os registros.
Exemplo
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);Segurança
O comportamento é indefinido se circuit não for um ponteiro válido e não nulo para um QkCircuit.
Parâmetros
- circuito - Um ponteiro para o circuito a ser copiado.
- vars_mode – O modo para lidar com variáveis clássicas.
- blocks_mode – O modo para lidar com blocos.
**Retornos
O ponteiro para o circuito copiado.
qk_circuit_to_python
PyObject *qk_circuit_to_python(QkCircuit *qc)
Passe a propriedade de um QkCircuit objeto para Python.
O objeto Python resultante não é QuantumCircuito próprio objeto, mas sim o objeto interno CircuitData, que normalmente é acessado como QuantumCircuit._data. Você pode usar qk_circuit_to_python_full para criar um objeto QuantumCircuit completo.
Não é seguro usar o QkCircuit ponteiro após chamar esta função. Em particular, você não deve tentar apagá-lo ou liberá-lo. O chamador deve ser o proprietário do objeto QkCircuit, e não possuir uma referência emprestada (por exemplo, um objeto QkCircuit * recuperado de um retrieved from não qk_circuit_borrow_from_python é de sua propriedade).
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um objeto inicializado e de propriedade do usuário QkCircuit.
Parâmetros
- qc – O objeto em questão.
**Retornos
Uma referência de propriedade do tipo Python ao objeto.
qk_circuit_to_python_full
PyObject *qk_circuit_to_python_full(QkCircuit *qc)
Passe a propriedade de um QkCircuit objeto para Python e crie um . completo QuantumCircuit.
Isso inclui uma lógica adicional no espaço de Python para produzir o completo QuantumCircuit, uma vez que QkCircuit corresponde apenas ao campo QuantumCircuit._data interno.
Não é seguro usar o QkCircuit ponteiro após chamar esta função. Em particular, você não deve tentar apagá-lo ou liberá-lo. O chamador deve ser o proprietário do objeto QkCircuit, e não possuir uma referência emprestada (por exemplo, um objeto QkCircuit * recuperado de um retrieved from não qk_circuit_borrow_from_python é de sua propriedade).
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não circuit for um ponteiro válido e diferente de nulo para um objeto inicializado e de propriedade do usuário QkCircuit.
Parâmetros
- qc – O objeto em questão.
**Retornos
Uma referência de propriedade do tipo Python ao objeto.
qk_circuit_borrow_from_python
QkCircuit *qk_circuit_borrow_from_python(PyObject *ob)
Recuperar um QkCircuit ponteiro de um objeto Python.
Observe que a entrada desta função não deve ser QuantumCircuit, mas sim a saída de QuantumCircuit._data. Isso é necessário para garantir a semântica correta da contagem de referências.
Isso utiliza uma referência de tipo Python e extrai o QkCircuit ponteiro correspondente, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro ob . Se o não PyObject for do tipo correto, o valor de retorno é NULL e o estado de exceção do interpretador do Python é definido.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_circuit_convert_from_python, que é, em termos lógicos, exatamente igual a esta função, mas pode ser usada diretamente como uma função “conversora” para a PyArg_Parse* família de funções conversoras do Python.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não ob for um ponteiro válido e diferente de nulo para um objeto Python.
Parâmetros
- ob – Um objeto de empréstimo do tipo
Python.
**Retornos
Um ponteiro para o objeto nativo, ou NULL se o objeto Python for do tipo incorreto.
qk_circuit_convert_from_python
int qk_circuit_convert_from_python(PyObject *object, void *address)
Recuperar um QkCircuit ponteiro de um objeto Python.
Observe que a entrada desta função não deve ser QuantumCircuit, mas sim a saída de QuantumCircuit._data. Isso é necessário para garantir a semântica correta da contagem de referências.
Isso utiliza uma referência do tipo Python e extrai o QkCircuit ponteiro correspondente para address``,, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro object . Se o não PyObject for do tipo correto, o valor de retorno é 0, o estado de exceção do interpretador do Python é definido e address permanece inalterado.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_circuit_borrow_from_python, que é, na prática, exatamente o mesmo que isto, mas com uma sintaxe mais natural para uso direto.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não object for um ponteiro válido e diferente de nulo para um objeto Python, ou se não address for um ponteiro para dados graváveis do tipo correto.
Parâmetros
- objeto – Um objeto
Pythonobtido por empréstimo. - endereço – O local onde a saída deve ser gravada.
**Retornos
1 em caso de sucesso, 0 em caso de falha.
qk_quantum_register_to_python
PyObject *qk_quantum_register_to_python(QkQuantumRegister *qr)
Passe a propriedade de um QkQuantumRegister objeto para Python.
Não é seguro usar o QkQuantumRegister ponteiro após chamar esta função. Em particular, você não deve tentar apagá-lo ou liberá-lo. O chamador deve ser o proprietário do objeto QkQuantumRegister, e não possuir uma referência emprestada (por exemplo, um objeto QkQuantumRegister * recuperado de um retrieved from não qk_quantum_register_borrow_from_python é de sua propriedade).
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não qr for um ponteiro válido e diferente de nulo para um objeto inicializado e de propriedade do usuário QkQuantumRegister.
Parâmetros
- qr – O objeto em questão.
**Retornos
Uma referência de propriedade do tipo Python ao objeto.
qk_quantum_register_borrow_from_python
const QkQuantumRegister *qk_quantum_register_borrow_from_python(PyObject *ob)
Recuperar um QkQuantumRegister ponteiro de um objeto Python.
Isso utiliza uma referência de tipo Python e extrai o QkQuantumRegister ponteiro correspondente, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro ob . Se o não PyObject for do tipo correto, o valor de retorno é NULL e o estado de exceção do interpretador do Python é definido.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_quantum_register_convert_from_python, que é, em termos lógicos, exatamente igual a esta função, mas pode ser usada diretamente como uma função “conversora” para a PyArg_Parse* família de funções conversoras do Python.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não ob for um ponteiro válido e diferente de nulo para um objeto Python.
Parâmetros
- ob – Um objeto de empréstimo do tipo
Python.
**Retornos
Um ponteiro para o objeto nativo, ou NULL se o objeto Python for do tipo incorreto.
qk_quantum_register_convert_from_python
int qk_quantum_register_convert_from_python(PyObject *object, void *address)
Recuperar um QkQuantumRegister ponteiro de um objeto Python.
Isso utiliza uma referência do tipo Python e extrai o QkQuantumRegister ponteiro correspondente para address``,, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro object . Se o não PyObject for do tipo correto, o valor de retorno é 0, o estado de exceção do interpretador do Python é definido e address permanece inalterado.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_quantum_register_borrow_from_python, que é, na prática, exatamente o mesmo que isto, mas com uma sintaxe mais natural para uso direto.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não object for um ponteiro válido e diferente de nulo para um objeto Python, ou se não address for um ponteiro para dados graváveis do tipo correto.
Parâmetros
- objeto – Um objeto
Pythonobtido por empréstimo. - endereço – O local onde a saída deve ser gravada.
**Retornos
1 em caso de sucesso, 0 em caso de falha.
qk_classical_register_to_python
PyObject *qk_classical_register_to_python(QkClassicalRegister *cr)
Passe a propriedade de um QkClassicalRegister objeto para Python.
Não é seguro usar o QkClassicalRegister ponteiro após chamar esta função. Em particular, você não deve tentar apagá-lo ou liberá-lo. O chamador deve ser o proprietário do objeto QkClassicalRegister, e não possuir uma referência emprestada (por exemplo, um objeto QkClassicalRegister * recuperado de um retrieved from não qk_classical_register_borrow_from_python é de sua propriedade).
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não cr for um ponteiro válido e diferente de nulo para um objeto inicializado e de propriedade do usuário QkClassicalRegister.
Parâmetros
- cr – O objeto em questão.
**Retornos
Uma referência de propriedade do tipo Python ao objeto.
qk_classical_register_borrow_from_python
const QkClassicalRegister *qk_classical_register_borrow_from_python(PyObject *ob)
Recuperar um QkClassicalRegister ponteiro de um objeto Python.
Isso utiliza uma referência de tipo Python e extrai o QkClassicalRegister ponteiro correspondente, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro ob . Se o não PyObject for do tipo correto, o valor de retorno é NULL e o estado de exceção do interpretador do Python é definido.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_classical_register_convert_from_python, que é, em termos lógicos, exatamente igual a esta função, mas pode ser usada diretamente como uma função “conversora” para a PyArg_Parse* família de funções conversoras do Python.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não ob for um ponteiro válido e diferente de nulo para um objeto Python.
Parâmetros
- ob – Um objeto de empréstimo do tipo
Python.
**Retornos
Um ponteiro para o objeto nativo, ou NULL se o objeto Python for do tipo incorreto.
qk_classical_register_convert_from_python
int qk_classical_register_convert_from_python(PyObject *object, void *address)
Recuperar um QkClassicalRegister ponteiro de um objeto Python.
Isso utiliza uma referência do tipo Python e extrai o QkClassicalRegister ponteiro correspondente para address``,, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro object . Se o não PyObject for do tipo correto, o valor de retorno é 0, o estado de exceção do interpretador do Python é definido e address permanece inalterado.
Você deve estar conectado a um interpretador Python para chamar esta função.
Você também pode usar qk_classical_register_borrow_from_python, que é, na prática, exatamente o mesmo que isto, mas com uma sintaxe mais natural para uso direto.
Segurança
O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não object for um ponteiro válido e diferente de nulo para um objeto Python, ou se não address for um ponteiro para dados graváveis do tipo correto.
Parâmetros
- objeto – Um objeto
Pythonobtido por empréstimo. - endereço – O local onde a saída deve ser gravada.
**Retornos
1 em caso de sucesso, 0 em caso de falha.