Skip to main content
IBM Quantum Platform

Crear 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
    

Esta página echa un vistazo más de cerca a la clase QuantumCircuit en el SDK de Qiskit, incluyendo algunos métodos más avanzados que puedes utilizar para crear circuitos cuánticos.


¿Qué es un circuito cuántico?

Un circuito cuántico simple es una colección de qubits y una lista de instrucciones que actúan sobre esos qubits. Para demostrarlo, la siguiente celda crea un nuevo circuito con dos nuevos qubits y, a continuación, muestra el atributo qubits del circuito, que es una lista de Qubits en orden desde el bit menos significativo q0q_0 hasta el bit más significativo qnq_n.

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.qubits

Output:

[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]

Se pueden combinar varios objetos QuantumRegister y ClassicalRegister para crear un circuito. Cada QuantumRegister y ClassicalRegister también pueden nombrarse.

from qiskit.circuit import QuantumRegister, ClassicalRegister

qr1 = QuantumRegister(2, "qreg1")  # Create a QuantumRegister with 2 qubits
qr2 = QuantumRegister(1, "qreg2")  # Create a QuantumRegister with 1 qubit
cr1 = ClassicalRegister(3, "creg1")  # Create a ClassicalRegister with 3 cbits

combined_circ = QuantumCircuit(
    qr1, qr2, cr1
)  # Create a quantum circuit with 2 QuantumRegisters and 1 ClassicalRegister
combined_circ.qubits

Output:

[<Qubit register=(2, "qreg1"), index=0>,
 <Qubit register=(2, "qreg1"), index=1>,
 <Qubit register=(1, "qreg2"), index=0>]

Puedes encontrar el índice y el registro de un qubit utilizando el método del circuito find_bit y sus atributos.

desired_qubit = qr2[0]  # Qubit 0 of register 'qreg2'

print("Index:", combined_circ.find_bit(desired_qubit).index)
print("Register:", combined_circ.find_bit(desired_qubit).registers)

Output:

Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]

Al añadir una instrucción al circuito, ésta se añade al atributo data del circuito. La siguiente salida de celda muestra que data es una lista de CircuitInstruction objetos, cada uno de los cuales tiene un atributo operation , y un atributo qubits .

qc.x(0)  # Add X-gate to qubit 0
qc.data

Output:

[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]

La forma más sencilla de ver esta información es mediante el draw método, que devuelve una visualización del circuito. Consulte «Visualizar circuitos» para ver diferentes formas de representar circuitos cuánticos.

qc.draw("mpl")

Output:

Output of the previous code cell

Los objetos de instrucción de circuito pueden contener circuitos de "definición" que describen la instrucción en términos de instrucciones más fundamentales. Por ejemplo, la puerta X se define como un caso específico de la puerta U3-gate una puerta más general de un solo qubit.

# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")

Output:

Output of the previous code cell

Las instrucciones y los circuitos se parecen en que ambos describen operaciones con bits y qubits, pero tienen propósitos diferentes:

  • Las instrucciones se tratan como fijas, y sus métodos suelen devolver nuevas instrucciones (sin mutar el objeto original).
  • Los circuitos están diseñados para ser construidos sobre muchas líneas de código, y QuantumCircuit los métodos a menudo mutan el objeto existente.

¿Qué es la profundidad del circuito?

La profundidad() de un circuito cuántico es una medida del número de "capas" de puertas cuánticas, ejecutadas en paralelo, que se necesitan para completar el cálculo definido por el circuito. Dado que las puertas cuánticas tardan tiempo en implementarse, la profundidad de un circuito corresponde aproximadamente a la cantidad de tiempo que tarda el ordenador cuántico en ejecutar el circuito. Así, la profundidad de un circuito es una magnitud importante para medir si un circuito cuántico puede funcionar en un dispositivo.

El resto de esta página ilustra cómo manipular circuitos cuánticos.


Construir circuitos

Métodos como QuantumCircuit.h y QuantumCircuit.cx añaden instrucciones específicas a los circuitos. Para añadir instrucciones a un circuito de forma más general, utilice el método append método. Toma una instrucción y una lista de qubits a los que aplicar la instrucción. Consulte la documentación de la API Circuit Library para obtener una lista de las instrucciones compatibles.

from qiskit.circuit.library import HGate

qc = QuantumCircuit(1)
qc.append(
    HGate(),  # New HGate instruction
    [0],  # Apply to qubit 0
)
qc.draw("mpl")

Output:

Output of the previous code cell

Para combinar dos circuitos, utilice el método compose método. Este acepta otro QuantumCircuit y una lista opcional de asignaciones de qubits.

Note

El método compose devuelve un circuito nuevo y no muta ninguno de los circuitos sobre los que actúa. Para mutar el circuito sobre el que se llama al método compose utilice el argumento inplace=True.

qc_a = QuantumCircuit(4)
qc_a.x(0)

qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)

# compose qubits (0, 1) of qc_a to qubits (1, 3) of qc_b respectively
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")

Output:

Output of the previous code cell

También puedes compilar los circuitos en instrucciones para mantenerlos organizados. Puede convertir un circuito en una instrucción utilizando el método to_instruction y añadirla a otro circuito como lo haría con cualquier otra instrucción. El circuito dibujado en la celda siguiente es funcionalmente equivalente al circuito dibujado en la celda anterior.

inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

Si tu circuito es unitario, puedes convertirlo en un Gate utilizando el método to_gate método. Gate son tipos específicos de instrucciones que tienen algunas características adicionales, como el control que añade un control cuántico.

gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

Para ver lo que está pasando, puede utilizar el método decompose para expandir cada instrucción en su definición.

Note

El método decompose devuelve un nuevo circuito y no muta el circuito sobre el que actúa.

qc_a.decompose().draw("mpl")

Output:

Output of the previous code cell

Medir qubits

Las mediciones se utilizan para tomar muestras de los estados de los qubits individuales y transferir los resultados a un registro clásico. Ten en cuenta que, si envías circuitos a una primitiva Sampler, es obligatorio incluir las medidas. Sin embargo, los circuitos que se envían a una primitiva Estimator no deben contener medidas.

Los qubits se pueden medir mediante tres métodos: measure, measure_all y measure_active. Para saber cómo visualizar los resultados de las mediciones, consulta la página «Visualizar resultados ».

  1. QuantumCircuit.measure mide cada qubit en el primer argumento sobre el bit clásico dado como segundo argumento. Este método permite controlar totalmente dónde se almacena el resultado de la medición.

  2. QuantumCircuit.measure_all no necesita argumento y puede utilizarse para circuitos cuánticos sin bits clásicos predefinidos. Crea hilos clásicos y almacena por orden los resultados de las mediciones. Por ejemplo, la medición del qubit qiq_i se almacena en el cbit measimeas_i ). También añade una barrera antes de la medición.

  3. QuantumCircuit.measure_active : similar a measure_all, pero sólo mide los qubits que tienen operaciones.

qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell

Circuitos parametrizados

Muchos algoritmos cuánticos a corto plazo implican la ejecución de muchas variaciones de un circuito cuántico. Dado que la construcción y optimización de circuitos de gran tamaño puede resultar costosa desde el punto de vista informático, Qiskit admite circuitos parametrizados. Estos circuitos tienen parámetros indefinidos, y no es necesario definir sus valores hasta justo antes de ejecutar el circuito. Esto le permite mover la construcción del circuito y la optimización fuera del bucle principal del programa. La siguiente celda crea y muestra un circuito parametrizado.

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit import Parameter

angle = Parameter("angle")  # undefined number

# Create and optimize circuit once
qc = QuantumCircuit(1)
qc.rx(angle, 0)
qc = generate_preset_pass_manager(
    optimization_level=3, basis_gates=["u", "cx"]
).run(qc)

qc.draw("mpl")

Output:

Output of the previous code cell

La siguiente celda crea muchas variaciones de este circuito y muestra una de las variaciones.

circuits = []
for value in range(100):
    circuits.append(qc.assign_parameters({angle: value}))

circuits[0].draw("mpl")

Output:

Output of the previous code cell

Encontrará una lista de los parámetros no definidos de un circuito en su atributo parameters .

qc.parameters

Output:

ParameterView([Parameter(angle)])

Cambiar el nombre de un parámetro

Por defecto, los nombres de los parámetros de un circuito parametrizado llevan el prefijo x-, por ejemplo, x[0]. Puede cambiar los nombres después de haberlos definido, como se muestra en el siguiente ejemplo.

from qiskit.circuit.library import z_feature_map
from qiskit.circuit import ParameterVector

# Define a parameterized circuit with default names
# For example, x[0]
circuit = z_feature_map(2)

# Set new parameter names
# They will now be prefixed by `hi` instead
# For example, hi[0]
training_params = ParameterVector("hi", 2)

# Assign parameter names to the quantum circuit
circuit = circuit.assign_parameters(parameters=training_params)

Próximos pasos

Recomendaciones
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.