Biblioteca de circuitos
El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o versiones más recientes.
qiskit[all]~=2.5.0
El SDK de Qiskit incluye una biblioteca de circuitos populares para utilizarlos como bloques de construcción en tus propios programas. El uso de circuitos predefinidos ahorra tiempo de investigación, escritura de código y depuración. La biblioteca incluye circuitos populares en computación cuántica, circuitos difíciles de simular clásicamente y circuitos útiles para la evaluación comparativa del hardware cuántico.
Esta página enumera las diferentes categorías de circuitos que ofrece la biblioteca. Para obtener una lista completa de circuitos, consulte la documentación de la API de la biblioteca de circuitos.
Puertas estándar
La biblioteca de circuitos también incluye puertas cuánticas estándar. Algunas son puertas más fundamentales (como la UGate), y otras son puertas multi-qubit que normalmente necesitan construirse a partir de puertas de uno y dos qubits. Para añadir puertas importadas a tu circuito, utiliza el método append ; el primer argumento es la puerta, y el siguiente es una lista de qubits a los que aplicar la puerta.
Por ejemplo, la siguiente celda de código crea un circuito con una puerta Hadamard y una puerta 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 Puertas estándar en la documentación de la API de la biblioteca de circuitos.
Circuitos N-locales
Estos circuitos alternan capas de puertas de rotación de un solo qubit con capas de puertas de enredo de varios qubits.
Esta familia de circuitos es popular en los algoritmos cuánticos variacionales porque pueden producir una amplia gama de estados cuánticos. Los algoritmos variacionales ajustan los parámetros de la puerta para encontrar estados que tengan ciertas propiedades (como los estados que representan una buena solución a un problema de optimización). Para ello, muchos circuitos de la biblioteca están parametrizados, lo que significa que puede definirlos sin valores fijos.
La siguiente celda de código importa un circuito n_local , en el que las puertas de enredo son puertas de dos qubits. Este circuito intercala bloques de puertas parametrizadas de un solo qubit, seguidos de bloques entrelazados de puertas de dos qubits. El siguiente código crea un circuito de tres qubits, con puertas RX de un qubit y puertas CZ de dos qubits.
from qiskit.circuit.library import n_local
two_local = n_local(3, "rx", "cz")
two_local.draw("mpl")Output:
El atributo parameters permite obtener una lista de los parámetros del circuito.
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])])
También puede utilizarlo para asignar estos parámetros a valores reales utilizando un diccionario de la forma { Parameter: number }. Para demostrarlo, la siguiente celda de código asigna cada parámetro del circuito a 0.
bound_circuit = two_local.assign_parameters(
{p: 0 for p in two_local.parameters}
)
bound_circuit.decompose().draw("mpl")Output:
Para obtener más información, consulte Puertas N-locales en la documentación de la API de la biblioteca de circuitos o realice el curso de diseño de algoritmos variacionales en IBM Quantum Learning.
Circuitos de codificación de datos
Estos circuitos parametrizados codifican datos en estados cuánticos para su procesamiento mediante algoritmos de aprendizaje de máquinas cuánticas. Algunos circuitos compatibles con Qiskit son:
- Codificación de amplitud, que codifica cada número en la amplitud de un estado base. Esto puede almacenar números en un solo estado, pero puede ser costoso de implementar.
- Codificación de base, que codifica un entero preparando el estado de base correspondiente .
- Codificación angular, que establece cada número de los datos como un ángulo de rotación en un circuito parametrizado.
El mejor enfoque depende de las características específicas de su aplicación. En los ordenadores cuánticos actuales, sin embargo, solemos utilizar circuitos de codificación angular como el 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 codificación de datos en la documentación de la API de la biblioteca de circuitos.
Circuitos de evolución temporal
Estos circuitos simulan un estado cuántico que evoluciona en el tiempo. Utilizar circuitos de evolución temporal para investigar efectos físicos como la transferencia de calor o las transiciones de fase en un sistema. Los circuitos de evolución temporal también son un componente fundamental de las funciones de onda de la química (como los estados de prueba unitarios de clústeres acoplados) y del algoritmo QAOA que utilizamos para los problemas de optimización.
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:
Lea la documentación de la API PauliEvolutionGate .
Circuitos de benchmarking y teoría de la complejidad
Los circuitos de evaluación comparativa nos dan una idea de lo bien que funciona realmente nuestro hardware, y los circuitos de teoría de la complejidad nos ayudan a entender lo difíciles que son los problemas que queremos resolver.
Por ejemplo, la referencia "volumen cuántico" mide la precisión con la que un ordenador cuántico ejecuta un tipo de circuito cuántico aleatorio. La puntuación del ordenador cuántico aumenta con el tamaño del circuito que puede ejecutar de forma fiable. Esto tiene en cuenta todos los aspectos del ordenador, incluido el recuento de qubits, la fidelidad de las instrucciones, la conectividad de los qubits y la pila de software que transpila y postprocesa los resultados. Lea más sobre el volumen cuántico en el artículo original sobre el volumen cuántico.
El siguiente código muestra un ejemplo de un circuito de volumen cuántico construido en Qiskit que funciona con cuatro qubits (los bloques unitary son puertas aleatorias de dos qubits).
from qiskit.circuit.library import quantum_volume
quantum_volume(4).draw("mpl")Output:
La biblioteca de circuitos también incluye circuitos considerados difíciles de simular clásicamente, como los circuitos polinómicos cuánticos instantáneos (iqp). Estos circuitos intercalan ciertas puertas diagonales (en la base computacional) entre bloques de puertas Hadamard.
Otros circuitos son grover_operator para el algoritmo de Grover y el circuito fourier_checking para el problema de comprobación de Fourier. Consulte estos circuitos en Circuitos cuánticos particulares en la documentación de la API de la biblioteca de circuitos.
Circuitos aritméticos
Las operaciones aritméticas son funciones clásicas, como la suma de enteros y las operaciones con bits. Pueden ser útiles con algoritmos como la estimación de amplitud para aplicaciones financieras, y en algoritmos como el algoritmo HHL, que resuelve sistemas lineales de ecuaciones.
Como ejemplo, intentemos sumar dos números de tres bits utilizando un circuito "ripple-carry" para realizar la suma en el lugar (FullAdderGate). Este sumador suma dos números (los llamaremos "A" y "B") y escribe el resultado en el registro que contenía B. En el siguiente ejemplo, A=2 y 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:
La simulación del circuito muestra que éste emite 5 para todos los disparos de 1024 (es decir, se mide con probabilidad 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 en la documentación de la API de la biblioteca de circuitos.
Próximos pasos
- Aprende métodos avanzados para crear circuitos en el tema «Circuitos» de Construct.
- Vea un ejemplo de circuitos utilizados en el tutorial del Algoritmo de Grover.
- Revise la referencia API de la biblioteca de circuitos.