Biblioteca de circuitos
A biblioteca de circuitos do Qiskit contém funções e blocos de construção de nível superior para a criação de circuitos quânticos comumente utilizados.
Tipos de dados
QkPauliProductRotation
struct QkPauliProductRotation
Uma representação dos dados de rotação do produto de Pauli.
Uma rotação do produto de Pauli implementa uma rotação de um angle em torno de um eixo definido pelo produto de Pauli em len qubits. O Pauli é aqui representado no formato ZX, com duas matrizes booleanas que representam as componentes Z e X.
bool *z
Ponteiro para uma matriz de len comprimento fixo contendo componentes do tipo Z.
bool *x
Ponteiro para uma matriz len de comprimento X com X componentes.
size_t len
O número de termos de Pauli.
QkParam *ângulo
O ângulo de rotação.
QkPauliProductMeasurement
struct QkPauliProductMeasurement
Uma representação dos dados de medição do produto Pauli.
Uma medição do produto de Pauli implementa uma projeção no espaço próprio do produto de Pauli definido sobre len os qubits. O vetor Pauli é representado aqui no formato ZX, com duas matrizes booleanas representando as componentes Z e X, e pode incluir um sinal de menos, indicado por flip_outcome.
bool *z
Ponteiro para uma matriz de len comprimento fixo contendo componentes do tipo Z.
bool *x
Ponteiro para uma matriz len de comprimento X com X componentes.
size_t len
O número de termos de Pauli.
bool resultado_da_virada
Se o resultado da medição tem sinal negativo.
Funções
qk_circuit_library_iqp
QkCircuit *qk_circuit_library_iqp(uint32_t num_qubits, const int64_t *interactions, bool check_input)
Gerar um circuito de polinômio quântico instantâneo (IQP) a partir de uma matriz de interação inteira.
A interactions matriz é interpretada como uma matriz n × n orientada por linhas de inteiros de 64 bits, onde n = num_qubits. Os elementos diagonais definem potências de fase do tipo T, e o triângulo superior codifica interações CPhase de dois qubits.
Segurança
Se num_qubits > 0, interactions deve ser um ponteiro válido e diferente de nulo para pelo menos valores num_qubits * num_qubits int64_t contíguos na ordem de prioridade de linha. A memória apontada por interactions deve estar devidamente alinhada, ser legível durante toda a duração desta chamada e não ter aliases mutáveis. Passar um ponteiro inválido ou um buffer muito pequeno resulta em comportamento indefinido.
Parâmetros
- num_qubits – Número de qubits lógicos (
n). Deve corresponder à dimensão dainteractionsmatriz. - interações – Ponteiro para uma matriz
n × ncom disposição por linhas do tipoint64_t. Só pode ser NULL senum_qubits == 0. - check_input – Quando
truechamada, esta função verifica se a matriz é simétrica e retornaNULLcaso não seja. Nesse casofalse, não é realizada nenhuma validação adicional.
Retorna
Uma matriz recém-alocada QkCircuit* em caso de sucesso (o chamador deve liberá-la com qk_circuit_free), ou NULL se num_qubits > 0 e interactions for NULL, ou se check_input for true e a matriz não for simétrica.
qk_circuit_library_random_iqp
QkCircuit *qk_circuit_library_random_iqp(uint32_t num_qubits, int64_t seed)
Gerar um circuito aleatório de polinômio quântico instantâneo (IQP).
Isso cria internamente uma matriz de interação inteira simétrica aleatória e a utiliza para construir um circuito IQP, espelhando o construtor qiskit.circuit.library.IQP Python.
Parâmetros
- num_qubits – Número de qubits.
- semente – semente do RNG. Se for negativo, a entropia é obtida do sistema operacional; caso contrário, o valor fornecido é usado como semente determinística.
Retorna
Uma variável recém-alocada QkCircuit* (o chamador deve liberá-la com qk_circuit_free).
qk_pauli_product_rotation_clear
void qk_pauli_product_rotation_clear(QkPauliProductRotation *inst)
Limpar os dados internos dos arquivos alocados pelo Rust QkPauliProductRotation.
Isso libera a memória das matrizes z``x e e libera o angle. Essa função só deve ser chamada para QkPauliProductRotation objetos cujos dados tenham sido preenchidos pelo Rust.
Exemplo
// let `circuit` be a QkCircuit* and `index` a size_t at the position of a QkPauliProductRotation
QkPauliProductRotation inst;
// query the QkPauliProductRotation data
assert(qk_circuit_operation_kind(circuit, index) == QkOperationKind_PauliProductRotation);
qk_circuit_inst_pauli_product_rotation(circuit, index, &inst);
// do something with `inst`, and then clear the Rust-allocated data
qk_pauli_product_rotation_clear(&inst);Por outro lado, essa função não deve ser chamada se o C já se encarregar de limpar os dados.
bool z[4] = {false, false, true, true};
bool x[4] = {false, true, true, false};
QkParam *angle = qk_param_from_double(1.0);
QkPauliProductRotation rotation = {z, x, 4, angle};
// since this data is allocated by C, we do not call `qk_pauli_product_rotation_clear(&rotation)`!
qk_param_free(angle);Segurança
O comportamento é indefinido se não inst for um ponteiro válido e diferente de nulo para um QkPauliProductRotation, ou se os dados internos de QkPauliProductRotation estiverem incoerentes.
Parâmetros
- inst – Um ponteiro para o elemento
QkPauliProductRotationa ser apagado.
qk_pauli_product_measurement_clear
void qk_pauli_product_measurement_clear(QkPauliProductMeasurement *inst)
Limpar os dados internos dos arquivos alocados pelo Rust QkPauliProductMeasurement.
Isso libera a memória das matrizes z``x e. Essa função só deve ser chamada para QkPauliProductMeasurement objetos cujos dados tenham sido preenchidos pelo Rust.
Exemplo
// let `circuit` be a QkCircuit* and `index` a size_t at the position
// of a QkPauliProductMeasurement
QkPauliProductMeasurement inst;
// query the QkPauliProductMeasurement data
assert(qk_circuit_operation_kind(circuit, index) == QkOperationKind_PauliProductMeasurement);
qk_circuit_inst_pauli_product_measurement(circuit, index, &inst);
// do something with `inst`, and then clear the Rust-allocated data
qk_pauli_product_measurement_clear(&inst);Por outro lado, essa função não deve ser chamada se o C já se encarregar de limpar os dados.
bool z[4] = {false, false, true, true};
bool x[4] = {false, true, true, false};
QkPauliProductMeasurement inst = {z, x, 4, true};
// since this data is allocated by C, we do not call `qk_pauli_product_measurement_clear(&inst)`Segurança
O comportamento é indefinido se não inst for um ponteiro válido e diferente de nulo para um QkPauliProductMeasurement, ou se os dados internos de QkPauliProductMeasurement estiverem incoerentes.
Parâmetros
- inst – Um ponteiro para o elemento
QkPauliProductMeasurementa ser apagado.
qk_circuit_library_quantum_volume
QkCircuit *qk_circuit_library_quantum_volume(uint32_t num_qubits, size_t depth, int64_t seed)
Gerar um circuito modelo Quantum Volume
Os circuitos modelo são instâncias aleatórias de circuitos usados para medir a métrica do Volume Quântico, conforme apresentado em [1]. Os circuitos modelo consistem em camadas de elementos aleatórios de Haar de SU(4) aplicados entre pares correspondentes de qubits em uma bipartição aleatória.
Esta função é multithreaded e iniciará um pool de threads com threads iguais ao número de CPUs por padrão. Você pode ajustar o número de threads com a variável de ambiente RAYON_NUM_THREADS. Por exemplo, definir RAYON_NUM_THREADS=4 limitaria o pool de threads a 4 threads.
[1] A. Cross e outros. Validação de computadores quânticos usando circuitos de modelos aleatórios, Phys. Rev. A 100, 032328 (2019). arXiv:1811.12926
Exemplo
QkCircuit *qc = qk_circuit_library_quantum_volume(10, 10, -1)Parâmetros
- num_qubits – O número de qubits a ser usado para o circuito gerado.
- profundidade – O número de camadas do circuito gerado.
- semente – Uma semente RNG usada para gerar as matrizes SU(4) aleatórias usadas no circuito de saída. Se o número fornecido for negativo, a semente utilizada será obtida a partir da entropia do sistema.
Retorna
Um indicador para o circuito de volume quântico.
qk_circuit_library_suzuki_trotter
QkCircuit *qk_circuit_library_suzuki_trotter(const QkObs *op, uint32_t order, uint32_t reps, double time, bool preserve_order, bool insert_barriers)
Gerar um circuito utilizando a fórmula do produto de Suzuki-Trotter de ordem superior a partir de uma observável.
As fórmulas de Suzuki-Trotter melhoram o erro da aproximação de Lie-Trotter. Nesta implementação, os operadores são apresentados como termos de soma de um operador de Pauli. As decomposições de ordem superior baseiam-se em recursões; ver Ref. [1] para mais detalhes.
Exemplo
QkObs *obs = qk_obs_zero(1);
QkBitTerm op1_bits[1] = {QkBitTerm_X};
QkObsTerm term1 = {(QkComplex64){1.0, 0.0}, 1, op1_bits, (uint32_t[1]){0}, 1};
qk_obs_add_term(obs, &term1);
QkBitTerm op2_bits[1] = {QkBitTerm_Y};
QkObsTerm term2 = {(QkComplex64){1.0, 0.0}, 1, op2_bits, (uint32_t[1]){0}, 1};
qk_obs_add_term(obs, &term2);
QkCircuit *qc = qk_circuit_library_suzuki_trotter(obs, 2, 1, 0.1, true, false);
qk_obs_free(obs);
qk_circuit_free(qc);Segurança
O comportamento é indefinido; não op é um ponteiro válido e diferente de nulo para um QkObs.
Referências
[1] : D. Berry, G., Ahokas, R., Cleve e B. Sanders, “Algoritmos quânticos eficientes para simular hamiltonianos esparsos” (2006). arXiv:quant-ph/0508139
[2] : N. Hatano e M. Suzuki, “Encontrando fórmulas de produtos exponenciais de ordens superiores” (2005). arXiv:math-ph/0506007
Parâmetros
- op – O
QkObsque contém a soma dos termos de Pauli. - ordem – A ordem da fórmula do produto.
- reps – O número de intervalos de tempo.
- tempo – O tempo de evolução.
- preserve_order – Se ativado
false, permite reordenar os termos do operador para, potencialmente, gerar um circuito de evolução mais simples. Não é relevante ao sintetizar um observável com um único termo. - insert_barriers – Se deve inserir separadores entre as evoluções dos termos.
Retorna
Um ponteiro para o circuito gerado.