Write Hamiltonian Algebraically#

This tutorial explains how to create a Qamomile Hamiltonian using an algebraic modeler jijmodeling.

Using this functionality will allow you to create Hamiltonians in a more intuitive way.

import jijmodeling as jm
import qamomile.core.modeler as qm_m

Write Algebraic Hamiltonian#

Let us write Heisenberg model without the external field with periodic boundary condition by using qamomile modeler in this tutorial.

To define Pauli Operator Expression we need to use qm_m.PauliExpr. In the Heisenberg model, there are \(X\), \(Y\) and \(Z\) Pauli Operator, so let us define them first.

N = jm.Placeholder("N")
Z = qm_m.PauliExpr.z(shape=(N,))
X = qm_m.PauliExpr.x(shape=(N,))
Y = qm_m.PauliExpr.y(shape=(N,))
Y
\[\displaystyle \hat{Y}\]

Next, let us define the Hamiltonian which is

\[ \hat{H} = - \sum_{i = 0}^{N-1} J_x X_i X_{i+1} + J_y Y_i Y_{i+1} + J_z Z_i Z_{i+1} \]

Here we assume periodic boundary condition ( \(X_N = X_0\) ).

We can define this by using jijmodeling.

i = jm.Element("i", belong_to = (0,N))
J_x = jm.Placeholder("J_x")
J_y = jm.Placeholder("J_y")
J_z = jm.Placeholder("J_z")
expr = -jm.sum(i, J_x * X[i] * X[(i+1) % N] + J_y * Y[i] * Y[(i+1) % N] + J_z * Z[i] * Z[(i+1) % N])
h_expr = qm_m.HamiltonianExpr(expr)
h_expr
\[\displaystyle - \sum_{i = 0}^{N - 1} \left(J_x \cdot \hat{X}_{i} \cdot \hat{X}_{\left(i + 1\right) \bmod N} + J_y \cdot \hat{Y}_{i} \cdot \hat{Y}_{\left(i + 1\right) \bmod N} + J_z \cdot \hat{Z}_{i} \cdot \hat{Z}_{\left(i + 1\right) \bmod N}\right)\]

Build Qamomile Hamiltonian from Algebraic Hamiltonian Expression#

We can build qamomile Hamiltonian by inserting the value into HamiltonianExpr.

Let us create some data to insert first. We can provide the data as dict.

To make it easier to see whether the output of the results is correct, let’s create some unusual data.

instance_data = {"N":10, "J_x":1.0, "J_y":-1.0, "J_z":2.0}

We can use HamiltonianBuilder to insert the instance data into HamiltonianExpr.

builder = qm_m.hamiltonian_expr.HamiltonianBuilder(h_expr,instance_data)
h = builder.build()
h
Hamiltonian((X0, X1): -1.0, (Y0, Y1): 1.0, (Z0, Z1): -2.0, (X1, X2): -1.0, (Y1, Y2): 1.0, (Z1, Z2): -2.0, (X2, X3): -1.0, (Y2, Y3): 1.0, (Z2, Z3): -2.0, (X3, X4): -1.0, (Y3, Y4): 1.0, (Z3, Z4): -2.0, (X4, X5): -1.0, (Y4, Y5): 1.0, (Z4, Z5): -2.0, (X5, X6): -1.0, (Y5, Y6): 1.0, (Z5, Z6): -2.0, (X6, X7): -1.0, (Y6, Y7): 1.0, (Z6, Z7): -2.0, (X7, X8): -1.0, (Y7, Y8): 1.0, (Z7, Z8): -2.0, (X8, X9): -1.0, (Y8, Y9): 1.0, (Z8, Z9): -2.0, (X0, X9): -1.0, (Y0, Y9): 1.0, (Z0, Z9): -2.0)

If you also want to check the Hamiltonian in LaTex, you can do it as follows.

import IPython.display as ipd

ipd.display(ipd.Latex("$" + h.to_latex() + "$"))
\[-X_{0}X_{1}+Y_{0}Y_{1}-2.0Z_{0}Z_{1}-X_{1}X_{2}+Y_{1}Y_{2}-2.0Z_{1}Z_{2}-X_{2}X_{3}+Y_{2}Y_{3}-2.0Z_{2}Z_{3}-X_{3}X_{4}+Y_{3}Y_{4}-2.0Z_{3}Z_{4}-X_{4}X_{5}+Y_{4}Y_{5}-2.0Z_{4}Z_{5}-X_{5}X_{6}+Y_{5}Y_{6}-2.0Z_{5}Z_{6}-X_{6}X_{7}+Y_{6}Y_{7}-2.0Z_{6}Z_{7}-X_{7}X_{8}+Y_{7}Y_{8}-2.0Z_{7}Z_{8}-X_{8}X_{9}+Y_{8}Y_{9}-2.0Z_{8}Z_{9}-X_{0}X_{9}+Y_{0}Y_{9}-2.0Z_{0}Z_{9}\]