Biblioteca de circuitos
O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos o uso dessas versões ou de versões mais recentes.
qiskit[all]~=2.5.0
O Qiskit SDK inclui uma biblioteca de circuitos populares para usar como blocos de construção em seus próprios programas. O uso de circuitos predefinidos economiza tempo de pesquisa, escrita de código e depuração. A biblioteca inclui circuitos populares em computação quântica, circuitos que são difíceis de simular classicamente e circuitos úteis para benchmarking de hardware quântico.
Esta página lista as diferentes categorias de circuitos que a biblioteca oferece. Para obter uma lista completa de circuitos, consulte a documentação da API da biblioteca de circuitos.
Portões padrão
A biblioteca de circuitos também inclui portas quânticas padrão. Algumas são portas mais fundamentais (como a UGate), e outras são portas de vários qubits que geralmente precisam ser construídas a partir de portas de um e dois qubits. Para adicionar portas importadas ao seu circuito, use o método append ; o primeiro argumento é a porta e o argumento seguinte é uma lista de qubits aos quais aplicar a porta.
Por exemplo, a célula de código a seguir cria um circuito com uma porta Hadamard e uma porta X multicontrolada.
from qiskit import QuantumCircuit
from qiskit.circuit.library import HGate, MCXGate
mcx_gate = MCXGate(3)
hadamard_gate = HGate()
qc = QuantumCircuit(4)
qc.append(hadamard_gate, [0])
qc.append(mcx_gate, [0, 1, 2, 3])
qc.draw("mpl")Output:
Consulte Portas padrão na documentação da API da biblioteca de circuitos.
Circuitos locais N
Esses circuitos alternam camadas de portas de rotação de um único qubit com camadas de portas de emaranhamento de vários qubits.
Essa família de circuitos é popular em algoritmos quânticos variacionais porque pode produzir uma ampla gama de estados quânticos. Os algoritmos variacionais ajustam os parâmetros da porta para encontrar estados que tenham determinadas propriedades (como estados que representem uma boa solução para um problema de otimização). Para essa finalidade, muitos circuitos da biblioteca são parametrizados, o que significa que você pode defini-los sem valores fixos.
A célula de código a seguir importa um circuito n_local , no qual as portas de entrelaçamento são portas de dois qubits. Esse circuito intercala blocos de portas parametrizadas de um único qubit, seguidos por blocos emaranhados de portas de dois qubits. O código a seguir cria um circuito de três qubits, com portas RX de um qubit e portas CZ de dois qubits.
from qiskit.circuit.library import n_local
two_local = n_local(3, "rx", "cz")
two_local.draw("mpl")Output:
Você pode obter um objeto semelhante a uma lista dos parâmetros do circuito com o atributo parameters .
two_local.parametersOutput:
ParameterView([ParameterVectorElement(θ[0]), ParameterVectorElement(θ[1]), ParameterVectorElement(θ[2]), ParameterVectorElement(θ[3]), ParameterVectorElement(θ[4]), ParameterVectorElement(θ[5]), ParameterVectorElement(θ[6]), ParameterVectorElement(θ[7]), ParameterVectorElement(θ[8]), ParameterVectorElement(θ[9]), ParameterVectorElement(θ[10]), ParameterVectorElement(θ[11])])
Você também pode usá-lo para atribuir esses parâmetros a valores reais usando um dicionário no formato { Parameter: number }. Para demonstrar, a célula de código a seguir atribui cada parâmetro do circuito a 0.
bound_circuit = two_local.assign_parameters(
{p: 0 for p in two_local.parameters}
)
bound_circuit.decompose().draw("mpl")Output:
Para obter mais informações, consulte N-local gates na documentação da API da biblioteca de circuitos ou faça o curso de design de algoritmo variacional em IBM Quantum Learning.
Circuitos de codificação de dados
Esses circuitos parametrizados codificam dados em estados quânticos para processamento por algoritmos de aprendizado de máquina quânticos. Alguns circuitos suportados pelo Qiskit são:
- Codificação de amplitude, que codifica cada número na amplitude de um estado básico. Isso pode armazenar números em um único estado, mas sua implementação pode ser cara.
- Codificação de base, que codifica um número inteiro preparando o estado de base correspondente .
- Codificação de ângulo, que define cada número nos dados como um ângulo de rotação em um circuito parametrizado.
A melhor abordagem depende das especificidades de seu aplicativo. No entanto, nos computadores quânticos atuais, geralmente usamos circuitos de codificação de ângulo, como o zz_feature_map.
from qiskit.circuit.library import zz_feature_map
features = [0.2, 0.4, 0.8]
feature_map = zz_feature_map(feature_dimension=len(features))
encoded = feature_map.assign_parameters(features)
encoded.draw("mpl")Output:
Consulte Circuitos de codificação de dados na documentação da API da biblioteca de circuitos.
Circuitos de evolução temporal
Esses circuitos simulam um estado quântico que evolui no tempo. Use circuitos de evolução temporal para investigar efeitos físicos, como transferência de calor ou transições de fase em um sistema. Os circuitos de evolução temporal também são um bloco de construção fundamental das funções de onda química (como estados de teste de cluster acoplado unitário) e do algoritmo QAOA que usamos para problemas de otimização.
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
# Prepare an initial state with a Hadamard on the middle qubit
state = QuantumCircuit(3)
state.h(1)
hamiltonian = SparsePauliOp(["ZZI", "IZZ"])
evolution = PauliEvolutionGate(hamiltonian, time=1)
# Evolve state by appending the evolution gate
state.compose(evolution, inplace=True)
state.draw("mpl")Output:
Leia a documentação da API PauliEvolutionGate .
Benchmarking e circuitos da teoria da complexidade
Os circuitos de benchmarking nos dão uma noção de quão bem nosso hardware está realmente funcionando, e os circuitos de teoria da complexidade nos ajudam a entender a dificuldade dos problemas que queremos resolver.
Por exemplo, o benchmark "volume quântico" mede a precisão com que um computador quântico executa um tipo de circuito quântico aleatório. A pontuação do computador quântico aumenta com o tamanho do circuito que ele pode executar de forma confiável. Isso leva em conta todos os aspectos do computador, inclusive a contagem de qubits, a fidelidade das instruções, a conectividade dos qubits e os resultados de transpilação e pós-processamento da pilha de software. Leia mais sobre volume quântico no artigo original sobre volume quântico.
O código a seguir mostra um exemplo de um circuito de volume quântico criado no Qiskit que é executado em quatro qubits (os blocos unitary são portas aleatórias de dois qubits).
from qiskit.circuit.library import quantum_volume
quantum_volume(4).draw("mpl")Output:
A biblioteca de circuitos também inclui circuitos que se acredita serem difíceis de simular classicamente, como os circuitos polinomiais quânticos instantâneos (iqp). Esses circuitos intercalam determinadas portas diagonais (na base computacional) entre blocos de portas Hadamard.
Outros circuitos incluem grover_operator para uso no algoritmo de Grover e o circuito fourier_checking para o problema de verificação de Fourier. Veja esses circuitos em Circuitos quânticos particulares na documentação da API da biblioteca de circuitos.
Circuitos aritméticos
As operações aritméticas são funções clássicas, como a adição de números inteiros e operações de bit a bit. Eles podem ser úteis em algoritmos como a estimativa de amplitude para aplicativos financeiros e em algoritmos como o algoritmo HHL, que resolve sistemas lineares de equações.
Como exemplo, vamos tentar adicionar dois números de três bits usando um circuito "ripple-carry" para realizar a adição in-place (FullAdderGate). Esse somador adiciona dois números (vamos chamá-los de "A" e "B") e grava o resultado no registro que continha B. No exemplo a seguir, A=2 e B=3.
from qiskit.circuit.library import FullAdderGate
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
adder = FullAdderGate(3) # Adder of 3-bit numbers
# Create the number A=2
reg_a = QuantumRegister(3, "a")
number_a = QuantumCircuit(reg_a)
number_a.initialize(2) # Number 2; |010>
# Create the number B=3
reg_b = QuantumRegister(3, "b")
number_b = QuantumCircuit(reg_b)
number_b.initialize(3) # Number 3; |011>
# Create a circuit to hold everything, including a classical register for
# the result
qregs = [
QuantumRegister(1, "cin"),
QuantumRegister(3, "a"),
QuantumRegister(3, "b"),
QuantumRegister(1, "cout"),
]
reg_result = ClassicalRegister(3)
circuit = QuantumCircuit(*qregs, reg_result)
# Compose number initializers with the adder. Adder stores the result to
# register B, so we'll measure those qubits.
circuit = (
circuit.compose(number_a, qubits=reg_a)
.compose(number_b, qubits=reg_b)
.compose(adder)
)
circuit.measure(reg_b, reg_result)
circuit.draw("mpl")Output:
A simulação do circuito mostra que ele produz 5 para todos os disparos 1024 (ou seja, é medido com probabilidade 1.0).
from qiskit.primitives import StatevectorSampler
result = StatevectorSampler().run([circuit]).result()
print(f"Count data:\n {result[0].data.c0.get_int_counts()}")Output:
Count data:
{5: 1024}
Consulte Aritmética na documentação da API da biblioteca de circuitos.
Próximas etapas
- Aprenda métodos avançados para criar circuitos no tópico “Circuitos no Construct ”.
- Veja um exemplo de circuitos sendo usados no tutorial do Algoritmo de Grover.
- Examine a referência da API da biblioteca de circuitos.