Hamiltoniano

La clase Hamiltonian representa un Hamiltoniano simbólico como una suma de operadores de Pauli ponderados. Se pueden crear Hamiltonianos utilizando los operadores de Pauli integrados y combinarlos con operaciones aritméticas estándar.

Construcción

Para construir un Hamiltoniano con un único Pauli, se pueden usar los constructores X(i), Y(i), Z(i), I(i). A partir de estos operadores de un qubit, se pueden construir Hamiltonianos de múltiples qubits mediante operaciones aritméticas. Las operaciones siguen la sintaxis de Python; por ejemplo: 2 * Z(0) + Z(1) y Z(0) * Z(1) construyen un Hamiltoniano de múltiples qubits.

Hamiltonianos comunes

De forma alternativa, para los modelos más habituales existen constructores con nombre propio:

Constructor

Hamiltoniano

transverse_field()

\(\sum_i h_x X_i\)

longitudinal_field()

\(\sum_i h_z Z_i\)

ising()

\(\sum_{i<j} J Z_i Z_j + \sum_i h_z Z_i\)

ising_chain()

\(\sum_i J Z_i Z_{i+1} + \sum_i h_z Z_i\)

ising_grid()

\(\sum_{\langle i, j \rangle} J Z_i Z_j + \sum_i h_z Z_i\) en una red cuadrada

transverse_field_ising()

\(\sum_{i<j} J Z_i Z_j + \sum_i h_x X_i + \sum_i h_z Z_i\)

heisenberg()

\(\sum_{i<j} \left( J_x X_i X_j + J_y Y_i Y_j + J_z Z_i Z_j \right) + \sum_i h_z Z_i\)

from qilisdk.analog import Hamiltonian

H = Hamiltonian.transverse_field_ising(nqubits=2, x_coefficient=1.3, zz_coefficient=-2)
print(H)

Salida:

1.3 X(0) + 1.3 X(1) - 2 Z(0) Z(1)

Todos los argumentos de coeficiente aceptan tanto un único valor, compartido por todos los términos a los que da peso, como una lista con un valor por término, de modo que cualquiera de los constructores anteriores puede construir un modelo no uniforme simplemente pasando una lista en lugar de un número. Los valores se toman en el orden en que se generan los términos, que cada constructor documenta.

from qilisdk.analog import Hamiltonian

H = Hamiltonian.transverse_field_ising(nqubits=2, x_coefficient=[1.3, -0.7], zz_coefficient=[-2])
print(H)

Salida:

1.3 X(0) - 0.7 X(1) - 2 Z(0) Z(1)

Lista de operaciones

Operaciones aritméticas:

  • Suma: H1 + H2

  • Multiplicación escalar: 5 * H

  • Multiplicación: H0 * H1

  • Resta: H1 - H2

  • División por escalar: H / 5

  • Negación: -H

Operadores Simbólicos Adicionales:

Exportación de Hamiltonianos:

Importación de Hamiltonianos:

Hamiltonianos comunes:

Ejemplo: Hamiltoniano de Ising

Para definir un Hamiltoniano de Ising de la forma:

\[H_{\text{Ising}} = - \sum_{\langle i, j \rangle} J_{ij} \sigma^Z_i \sigma^Z_j - \sum_j h_j \sigma^Z_j\]

puede utilizar los operadores de Pauli Z de la biblioteca:

from qilisdk.analog import Z

nqubits = 3
J = {(0, 1): 1, (0, 2): 2, (1, 2): 4}
h = {0: 1, 1: 2, 2: 3}

coupling = sum(weight * Z(i) * Z(j) for (i, j), weight in J.items())
fields = sum(weight * Z(i) for i, weight in h.items())

H = -(coupling + fields)
print(H)

Salida:

- Z(0) Z(1) - 2 Z(0) Z(2) - 4 Z(1) Z(2) - Z(0) - 2 Z(1) - 3 Z(2)

Visualización

H.draw() dibuja un Hamiltoniano como un grafo de interacciones:

  • Cada cúbit es un nodo, cuyo disco se divide en un sector por cada campo local que actúa sobre él, etiquetado con su tipo de Pauli.

  • Cada término de dos cúbits es una arista entre los cúbits que acopla, dibujada con un estilo de línea por cada tipo de acoplamiento (véase la leyenda).

  • Cada término que actúa sobre tres o más cúbits es una hiperarista en forma de estrella unida en el centroide de los cúbits implicados.

  • Los colores de los sectores y de las aristas codifican el coeficiente del término correspondiente, tal como describe la barra de color.

  • Un término constante (identidad) se anota debajo del grafo como un desplazamiento de energía.

from qilisdk.analog import X, Z

nqubits = 3
J = {(0, 1): 1, (0, 2): 2, (1, 2): 4}

H = sum(weight * Z(i) * Z(j) for (i, j), weight in J.items()) + sum(X(i) for i in range(nqubits))
H.draw()

La apariencia se controla con HamiltonianStyle, que comparte los temas de los renderizadores de circuitos y de schedules. Selecciona la disposición de rustworkx empleada para colocar los cúbits ("spring", "circular", "shell", "spiral" o "random", o positions explícitas), si los campos locales y los acoplamientos comparten una única escala de color, y qué anotaciones se dibujan:

from qilisdk.analog import X, Z
from qilisdk.utils.visualization.style import HamiltonianStyle
from qilisdk.utils.visualization.themes import dark

H = 5 * X(0) - 3 * Z(0) + X(1) + 0.1 * Z(0) * Z(1) + 0.05 * X(0) * X(1)

H.draw(
    HamiltonianStyle(
        theme=dark,
        layout="circular",
        title="My Hamiltonian",
        # Local fields and couplings live on very different scales here, so give each its own colour bar.
        separate_color_scales=True,
    )
)

Para guardar la figura en lugar de mostrarla, pase un filepath (el formato se deduce de la extensión):

from qilisdk.analog import X, Z

H = X(0) + Z(0) * Z(1)
H.draw(filepath="hamiltonian.png")