Circuits

Els circuits quàntics es poden construir utilitzant la classe Circuit. Podeu afegir portes seqüencialment per definir el circuit:

Inicialització

from qilisdk.digital import Circuit

# Create a 3-qubit circuit
circuit = Circuit(nqubits=3)

Afegir portes

from qilisdk.digital import H, CNOT

circuit.add(H(0))  # Hadamard on qubit 0
circuit.add(CNOT(0, 1))  # CNOT: control 0 → target 2
circuit.draw()

També podeu afegir o inserir múltiples portes alhora:

from qilisdk.digital import X, RX
import numpy as np

circuit.add([X(0), RX(1, theta=np.pi / 2)])
circuit.insert([H(2), CNOT(2, 1)], index=1)
circuit.insert(X(0), 0)

Els circuits es poden annexar o anteposar, i l’operador + reprodueix aquests comportaments:

left = Circuit(2)
left.add(H(0))

right = Circuit(2)
right.add(CNOT(0, 1))

left.append(right)
# Equivalent: left = left + right

extra = X(1)
# Equivalent to left.insert(extra, index=0)
left = extra + left

Generació de circuits aleatoris

També podeu inicialitzar un circuit aleatori amb un nombre especificat de portes utilitzant el mètode random():

from qilisdk.digital import Circuit, X, H, CNOT
c = Circuit.random(
    nqubits=3,
    single_qubit_gates=[X, H],
    two_qubit_gates=[CNOT],
    ngates=10,
)
circuit.draw()

Circuits parametritzats

Els circuits poden incloure portes parametritzades. Afegir-les és similar a les portes regulars:

from qilisdk.digital import Circuit, RX
import numpy as np

circuit = Circuit(1)
circuit.add(RX(0, theta=np.pi))

Podeu recuperar el paràmetre actual utilitzant:

print("Initial Parameters:", circuit.get_parameters())

Sortida:

Initial Parameters: {'RX(0)_theta_0': 3.141592653589793}

També podeu recuperar una llista que contingui només els valors actuals dels paràmetres:

print("Initial parameter values:", circuit.get_parameter_values())

Sortida:

Initial parameter values: [3.141592653589793]

Per actualitzar els paràmetres per les seves claus:

circuit.set_parameters({"RX(0)_theta_0": 2 * np.pi})

Per actualitzar tots els paràmetres amb nous valors:

circuit.set_parameter_values([2 * np.pi])

Avís

L’ordre dels paràmetres a la llista passada a set_parameter_values ha de coincidir amb l’ordre en què les portes van ser afegides al circuit.

Visualització

Utilitzeu draw() per renderitzar un circuit amb Matplotlib. Per defecte, el renderitzador aplica l’estil integrat de la biblioteca (inclosa la font predeterminada inclosa si està disponible). Podeu ometre tots els valors predeterminats passant un CircuitStyle personalitzat, que limita l’estil a la crida específica sense modificar la configuració global de Matplotlib.

from qilisdk.digital import Circuit, H, CNOT

circuit = Circuit(3)
circuit.add(H(0))
circuit.add(CNOT(0, 2))

# Render in a window
circuit.draw()

Sortida

Exemple de circuit digital renderitzat amb Circuit.draw

Exemple de circuit produït per circuit.draw().

The plot can also be saved to a file by providing a filepath to the draw method:

# Save as SVG (use .png, .pdf, etc. as needed)
circuit.draw(filepath="my_circuit.svg")

Estil personalitzat amb CircuitStyle

Creeu un objecte d’estil per controlar el tema, les fonts, l’espaiat, el DPI, les etiquetes i molt més. Passar aquest objecte a draw() substitueix els valors predeterminats de la biblioteca per a aquesta crida. També podeu canviar si l’ordre del dibuix segueix l’ordre en què s’afegeixen o si compacta les capes tant com sigui possible canviant el paràmetre layout a «normal» (predeterminat) o «compact» respectivament.

from qilisdk.digital import Circuit, H, CNOT
from qilisdk.utils.visualization import CircuitStyle, light, dark

circuit = Circuit(3)
circuit.add(H(0))
circuit.add(CNOT(0, 2))

# Example 1: dark theme, larger text, higher DPI
style_dark = CircuitStyle(
    theme=dark,
    dpi=200,
    fontsize=12,
    title="Teleportation (fragment)",
)
circuit.draw(style=style_dark)

# Example 2: use a system font family and bypass the bundled font
style_font = CircuitStyle(
    theme=light,
    fontfname=None,                         # do not force a specific TTF file
    fontfamily=["DejaVu Sans", "Arial"],    # fallback list
    fontsize=11,
)
circuit.draw(style=style_font, filepath="circuit_custom_font.png")

# Example 3: adjust layout spacing
compact = CircuitStyle(
    theme=dark,
    wire_sep=0.45,      # vertical distance between wires (inches)
    layer_sep=0.45,     # horizontal distance between layers (inches)
    gate_margin=0.10,   # side margin inside each layer cell (inches)
    label_pad=0.08,     # left padding for wire labels (inches)
    layout="compact",   # compresses the circuit whenever possible
    title="Compact layout",
)
circuit.draw(style=compact)

Nota

Els camps de CircuitStyle es mapegen directament a la configuració de disposició i fonts del renderitzador. En particular, podeu canviar les fonts de dues maneres: (1) proporcioneu un fitxer de font específic via fontfname="/path/to/MyFont.ttf"; o (2) establiu fontfname=None i trieu una llista de famílies amb fontfamily=[...] per usar fonts resoltes pel sistema. Ambdós enfocaments afecten únicament la crida de dibuix actual.

Utilitats de paràmetres

Els circuits recopilen els paràmetres simbòlics aportats per cada porta. Més enllà dels exemples ràpids anteriors, podeu consultar noms, valors actuals i límits, o actualitzar-los de manera selectiva:

import numpy as np

from qilisdk.core.variables import Parameter
from qilisdk.digital import Circuit, RX, RZ

circuit = Circuit(nqubits=2)
theta = Parameter("theta", value=np.pi / 4, bounds=(0.0, np.pi))

circuit.add(RX(0, theta=theta))
circuit.add(RZ(1, phi=np.pi / 2))

print(circuit.get_parameter_names())   # ['RX(0)_theta_0', 'RZ(1)_phi_1']
print(circuit.get_parameters())        # {'RX(0)_theta_0': 0.785..., 'RZ(1)_phi_1': 1.570...}
print(circuit.get_parameter_bounds())  # {'RX(0)_theta_0': (0.0, 3.1415...), 'RZ(1)_phi_1': (None, None)}

circuit.set_parameter_bounds({"RX(0)_theta_0": (0.1, np.pi / 2)})
circuit.set_parameters({"RX(0)_theta_0": np.pi / 3})
circuit.set_parameter_values([np.pi / 3, np.pi / 2])

Aquests assistents permeten integrar fàcilment el circuit en bucles d’optimització clàssics mantenint els metadades dels paràmetres sincronitzats.

Nota

Les portes i els circuits parametritzats exposen la informació dels paràmetres mitjançant get_parameter_names, get_parameters, get_parameter_values, i els mètodes set_* corresponents.