<jupyter_start><jupyter_text>Supersymmetric harmonic oscillatorAs a warmup, lets go through the steps to get from the Hamiltonian of this system to a quantum circuit that lets us evolve states according to the time evolution operator.The superpotential is \begin{equation}    W(\hat{q}) = \frac{1}{2}m \hat{q}^2\end{equation}which leads to the following Hamiltonian,\begin{equation}    H = \frac{1}{2}\left(H_B+H_F\right), \quad         H_B=\hat{p}^2+m^2\hat{q}^2, \quad H_F=m\left[\hat{b}^{\dagger},\hat{b}\right].\end{equation}This contains two terms, a bosonic piece and a fermionic piece.  For the bosonic part, we could work in the position or momentum basis, but this is just the Hamiltonian for a harmonic oscillator, so lets convert to the number basis.<jupyter_code>import sys
sys.path.append('..')
from src.sympy_utilities import *
from src.BinaryEncodings import *
from src.MatrixToPauliString import *

import sympy as sp

h_b = 0.5*(p*p + m*m*q*q)

print('Original H = ' + str(h_b))
h_b = sp.expand(h_b.subs(qp_to_ada))
h_f = -0.5*m#[bdag,b]
print('Using creation/annihlation operators\nH_B = ' + str(h_b))
print('H_F = ' + str(h_f))<jupyter_output>Original H = 0.5*(m**2*q**2 + p**2)
Using creation/annihlation operators
H_B = 0.5*m*a*ad + 0.5*m*ad*a
H_F = -0.5*m<jupyter_text>And we know the matrix elements of $A$ and $A^{\dagger}$, they are defined in HamiltonianTerms.  We of course must impose a cutoff at this point, truncating the allowed excitations of the harmonic oscillator<jupyter_code>hamHO = Hamiltonian(h_b, h_f, {m:1, g:1},
                     2, standard_encode)
print('done')
print()
print(hamHO.bmatrix)
print(np.kron(np.eye(2),hamHO.bmatrix))
print(hamHO.bosonPauliStrings)
print()
print(hamHO.fermionic)
print(hamHO.fmatrix)
print(sp.simplify(hamHO.fermionPauliStrings))
print()

print(hamHO.pauliStrings)
print(hamHO.hamMatrix)
hamHO = Hamiltonian(h_b, h_f, {m:1, g:1},
                     3, standard_encode)

print('boson matrix')
print(hamHO.bmatrix)
print('boson matrix as pauli strings')
print(hamHO.bosonPauliStrings)
print('boson pauli strings as matrix')
print(getMatrix(sp.expand(hamHO.bosonPauliStrings)))
print()
print('boson matrix in full hilbert space')
tmpMat=np.kron(np.eye(2),hamHO.bmatrix)
print(tmpMat)
print('boson pauli strings in full hilbert space')
tmpPS=sp.expand(sp.N(mps.matrix_to_pauli_strings(tmpMat, standard_encode)))
print(tmpPS)
print('back to matrix')
print(getMatrix(sp.expand(tmpPS)))
print()
print('fermionic coef')
print(hamHO.fermionic)
print('fermionic matrix')
print(hamHO.fmatrix)
print('fermionic pauli strings')
print(sp.simplify(hamHO.fermionPauliStrings))
print()
print('fermionic pauli strings as Matrix')
print(getMatrix(sp.expand(hamHO.fermionPauliStrings)))

print('Hamiltonian pauli strings')
print(hamHO.pauliStrings)
print('Expected to get...')
tstHam=tmpMat+hamHO.fmatrix
tstPS=sp.expand(mps.matrix_to_pauli_strings(tstHam,standard_encode))
print(tstPS)
print()
print('Ham matrix is')
print(hamHO.hamMatrix)
print('But I would expect it has the same spectrum as')
print(getMatrix(tstPS))<jupyter_output>boson matrix
[[0.500000000000000 0 0]
 [0 1.50000000000000 0]
 [0 0 2.50000000000000]]
boson matrix as pauli strings
1.125*I^0*I^1 - 0.125*I^0*Z^1 + 0.375*I^1*Z^0 - 0.875*Z^0*Z^1
boson pauli strings as matrix
[[ 5.00000000e-01+0.j  0.00000000e+00+0.j  0.00000000e+00+0.j
   0.00000000e+00+0.j]
 [ 0.00000000e+00+0.j  1.50000000e+00+0.j  0.00000000e+00+0.j
   0.00000000e+00+0.j]
 [ 0.00000000e+00+0.j  0.00000000e+00+0.j  2.50000000e+00+0.j
   0.00000000e+00+0.j]
 [ 0.00000000e+00+0.j  0.00000000e+00+0.j  0.00000000e+00+0.j
  -5.55111512e-17+0.j]]

boson matrix in full hilbert space
[[0.500000000000000 0 0 0 0 0]
 [0 1.50000000000000 0 0 0 0]
 [0 0 2.50000000000000 0 0 0]
 [0 0 0 0.500000000000000 0 0]
 [0 0 0 0 1.50000000000000 0]
 [0 0 0 0 0 2.50000000000000]]
boson pauli strings in full hilbert space
1.125*I^0*I^1*I^2 + 0.125*I^0*I^1*Z^2 + 0.375*I^0*I^2*Z^1 - 0.625*I^0*Z^1*Z^2 + 0.25*I^1*Z^0*Z^2 - 0.5*I^2*Z^0*Z^1 - 0.25*Z^0*Z^1*Z^2
back to matrix
[[ 5.00000000e-01+0.j  0.00000000e+00+0.[...]<jupyter_text>Supersymmetric Anharmonic OscillatorThe superpotential is \begin{equation}    W(\hat{q}) = \frac{1}{2}m\hat{q}^2 + \frac{1}{4}g\hat{q}^4\end{equation}The full Hamiltonian is\begin{equation}    H=\frac{1}{2}\left[\hat{p}^2 + m^2\hat{q}^2 + 2mg\hat{q}^4 + g^2\hat{q}^6 - (m+3g\hat{q}^2)\left[b^{\dagger},b\right]\right]\end{equation}<jupyter_code>import sys
sys.path.append('..')
from src.sympy_utilities import *
from src.BinaryEncodings import *

import sympy as sp

h_b = 0.5*(p*p + m*m*q*q + 2.*m*g*q*q*q*q + g*g*q*q*q*q*q*q)
h_f = -0.5*(m+3*g*q*q)#[bdag,b]


n=3
hamAHO = Hamiltonian(h_b, h_f, {m:1, g:1},
                    n, standard_encode)
print('boson matrix')
print(hamAHO.bmatrix)
print('boson matrix as pauli strings')
print(hamAHO.bosonPauliStrings)
print('boson pauli strings as matrix')
print(getMatrix(sp.expand(hamAHO.bosonPauliStrings)))
print()
print('boson matrix in full hilbert space')
tmpMat=np.kron(np.eye(2),hamAHO.bmatrix)
print(tmpMat)
print('boson pauli strings in full hilbert space')
tmpPS=sp.expand(sp.N(mps.matrix_to_pauli_strings(tmpMat, standard_encode)))
tmpPS=tmpPS.xreplace(dict([(n,0) for n in tmpPS.atoms(sp.Float) if abs(n) < 1e-12]))
print(tmpPS)
print('back to matrix')
print(getMatrix(sp.expand(tmpPS)))
print()
print('fermionic coef')
print(hamAHO.fermionic)
print('fermionic matrix')
print(hamAHO.fmatrix)
print('fermionic pauli strings')
print(sp.simplify(hamAHO.fermionPauliStrings))
print()
print('fermionic pauli strings as Matrix')
print(getMatrix(sp.expand(hamAHO.fermionPauliStrings)))

print('Hamiltonian pauli strings')
print(hamAHO.pauliStrings)
print('Expected to get...')
tstHam=tmpMat+hamAHO.fmatrix
tstPS=sp.expand(mps.matrix_to_pauli_strings(tstHam,standard_encode))
tstPS=tstPS.xreplace(dict([(n,0) for n in tstPS.atoms(sp.Float) if abs(n) < 1e-12]))
print(tstPS)
print()
print('Ham matrix is')
print(hamAHO.hamMatrix)
print('But I would expect it has the same spectrum as')
print(getMatrix(tstPS))
print(np.linalg.eig(np.array(hamAHO.hamMatrix,dtype=float))[0])
print(np.linalg.eig(np.array(getMatrix(tstPS),dtype=complex))[0])
h_b = 0.5*(p*p + m*m*q*q + 2.*m*g*q*q*q*q + g*g*q*q*q*q*q*q)
h_f = -0.5*(m+3*g*q*q)#[bdag,b]


n=2
hamAHO = Hamiltonian(h_b, h_f, {m:1, g:0},
                    n, standard_encode)
hamAHO.pauliStrings
h_b = 0.5*(p*p + m*m*q*q + 2.*m*g*q*q*q*q + g*g*q*q*q*q*q*q)
h_f = 0.5*(m+3*g*q*q)#[bdag,b]


n=4
hamAHO = Hamiltonian(h_b, h_f, {m:1, g:1},
                    n, standard_encode)
hamAHO.pauliStrings
hamAHO.hamMatrix
h_b = 0.5*(p*p + m*m*q*q + 2.*m*g*q*q*q*q + g*g*q*q*q*q*q*q)
h_f = 0.5*(m+3*g*q*q)#[bdag,b]


n=16
hamAHO = Hamiltonian(h_b, h_f, {m:1, g:1},
                    n, standard_encode)
hamAHO.hamMatrix
np.linalg.eig(np.array(hamAHO.hamMatrix,dtype=float))<jupyter_output><empty_output><jupyter_text>Double Well Potential<jupyter_code>h_b_DW = 0.5*(p*p + (m*q + g*(q*q + mu*mu))**2)
h_f_DW = -0.5*(m+2*g*q)#[bdag,b]
from src.BinaryEncodings import *

hamDW = Hamiltonian(h_b_DW, h_f_DW, {m:1, g:1, mu:1},
                     2, standard_encode)
print('boson matrix')
print(hamDW.bmatrix)
print('boson matrix as pauli strings')
print(hamDW.bosonPauliStrings)
print('boson pauli strings as matrix')
print(getMatrix(sp.expand(hamDW.bosonPauliStrings)))
print()
print('boson matrix in full hilbert space')
tmpMat=np.kron(np.eye(2),hamDW.bmatrix)
print(tmpMat)
print('boson pauli strings in full hilbert space')
tmpPS=sp.expand(sp.N(mps.matrix_to_pauli_strings(tmpMat, standard_encode)))
tmpPS=tmpPS.xreplace(dict([(n,0) for n in tmpPS.atoms(sp.Float) if abs(n) < 1e-12]))
print(tmpPS)
print('back to matrix')
print(getMatrix(sp.expand(tmpPS)))
print()
print('fermionic coef')
print(hamDW.fermionic)
print('fermionic matrix')
print(hamDW.fmatrix)
print('fermionic pauli strings')
print(sp.simplify(hamDW.fermionPauliStrings))
print()
print('fermionic pauli strings as Matrix')
print(getMatrix(sp.expand(hamDW.fermionPauliStrings)))

print('Hamiltonian pauli strings')
print(hamDW.pauliStrings)
print('Expected to get...')
tstHam=tmpMat+hamDW.fmatrix
tstPS=sp.expand(mps.matrix_to_pauli_strings(tstHam,standard_encode))
tstPS=sp.N(tstPS.xreplace(dict([(n,0) for n in tstPS.atoms(sp.Float) if abs(n) < 1e-12])))
print(tstPS)
print()
print('Ham matrix is')
print(hamDW.hamMatrix)
print('But I would expect it has the same spectrum as')
print(getMatrix(tstPS))
import math
1.75*math.sqrt(2)
0.75*math.sqrt(2)<jupyter_output><empty_output><jupyter_text>Compare to QISKIT MatrixOp??<jupyter_code>import qiskit
from qiskit.opflow import MatrixOp
hamHO.pauliStrings
getMatrix(hamHO.pauliStrings)
hamHO.hamMatrix
MatrixOp(hamHO.hamMatrix)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1653372835004558, 'fraction_numerical': 0.0663172288058341, 'mean_word_length': 5.85703125, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 26, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '472132', 'license': 'MIT', 'n_tokens_mistral': 4154, 'n_tokens_neox': 3667, 'n_words': 698, 'path': 'tutorials/SusyHamiltonians.ipynb', 'repo_name': 'chrisculver/SUSY_QuantumComputing', 'size': '8776'}