wavefunction_analysis.spins package

Submodules

wavefunction_analysis.spins.circuit module

beta_layer(qubits, beta)[source]

Define the beta layer of the circuit.

create_circuit(qubits, gamma=None, beta=None, **kwargs)[source]

Create a quantum circuit with Hadamard gates on each qubit for equal superposition as real initial state. gamma: 𝛾 symbol holder as a parameter for U(gamma, C) operator beta: ß symbol holder as a parameter for U(beta, B) operator h: 2D array of magnetic field values return: cirq.Circuit object

create_qubits_2d(nrow, ncol)[source]

Initialize qubits in a 2D grid.

gamma_layer(qubits, gamma, h)[source]

Define the gamma layer of the circuit.

wavefunction_analysis.spins.infinite_mps_block module

apply_gate_on_mps(gate_ab, s_ab, s_ba, mps_a, mps_b, chi, tol=1e-07)[source]

apply a gate from left to AB dimer MPSs (bra side) for time evolution use conjugate of evolution operator for the bra state gate_ab: e^{1j*t*ham_ab} for real-time or e^{-tau*ham_ab} for imaginary-time

—1—ss_{BA}—1—A—3—s_{AB}—3—B—5—ss_{BA}—5—
2——-\ /——–4

—–6—–U_{AB}—–7—–

above contraction gives a matrix whose indices in order 1675,

first and last are weight dimensions, while the middle two are the physical dimensions

subjected to svd to form new MPSs and weights s_ab gate_ba: switch A and B indices when calling this function

so that update MPSs and s_ba

build_evolution_gate(ham, tau, itype='imag')[source]
contract_from_left(mu_ba, s_ab, s_ba, mps_a, mps_b, pick_eig='LM')[source]
update the environment density matrix at left by contracting it

with one more 2-sites (A and B) unit cell

mu_ba: density matrix from the left connects A site via s_ba bond,

bottom-up indexed

mu_ab: also obtained from updated mu_ba and A site s_ab: weight vector connects site A (left) to B (right) s_ba: weight vector connects site B (left) to A (right) mps_a: MPS state at site A, bra at top mps_b: MPS state at site B, bra at top

/—–2—s_{BA}—4—At—7—s_{AB}—-9—Bt—12— | | |

mu_{BA} 5 10
| |

\—–1—s_{BA}—6—Ab—3—s_{AB}—11—Bb—-8—

it is equivalent to

/—–2—s_{BA}—4—A—-7—s_{AB}—9—B—-12— | | |

mu_{BA} 5 10
| |

\—–1—s_{BA}—3—A*—6—s_{AB}—8—B*—11—

we use the following summation as weigths are vectors (or diagonal)

/—–2-j–s_{BA}—j—A—5-m—s_{AB}—m—B—-8-p— | | |

mu_{BA} 3-k 6-n
| |

\—–1-i–s_{BA}—i—A*–4-l—s_{AB}—l—B*—7-o—

contract_from_right(nu_ab, s_ab, s_ba, mps_a, mps_b, pick_eig='LM')[source]
update the environment density matrix at right by contracting it

with one more 2-sites (A and B) unit cell

nu_ab: density matrix from the right connects A site via s_ab bond,

top-down indexed

nu_ba: also obtained from B site and updated nu_ab s_ab: weight vector connects site A (left) to B (right) s_ba: weight vector connects site B (left) to A (right) mps_a: MPS state at site A, bra at top mps_b: MPS state at site B, bra at top

—-8—Bt—11—s_{BA}—3—At—6—s_{AB}—1—-\
| |

10 5 nu_{AB} | | |

—12—Bb—-9—s_{BA}—7—Ab—4—s_{AB}—2—–/

it is equivalent to
—11—BT—-8—s_{BA}—6—AT—-3—s_{AB}—1—-\
| |

10 5 nu_{AB} | | |

—12—B*T—9—s_{BA}—7—A*T—4—s_{AB}—2—–/

we use the following summation as weigths are vectors (or diagonal)
—o-7—At—l—s_{BA}—l-4—At—i—s_{AB}—i-1—-\
| |

6-n 3-k nu_{AB} | | |

—p-8—Ab—m—s_{BA}—m-5—Ab—j—s_{AB}—j-2—–/

evaluate_energy_mps(mpo_ab, mpo_ba, s_ab, s_ba, mps_a, mps_b)[source]

get energy of the two sites A and B use MPS and weights directly rather than build four-index density matrices E_AB:

/—1—s_{BA}—1—A—-4-l—s_{AB}—4—B—-8—s_{BA}—8—\ | | | | | 2-j——–\ /——–6-n | | | | | 1-i H_{AB} 8-p | | | | | 3-k——–/ \——–7-o | | | | |

\—1—s_{BA}—1—A*—5-m—s_{AB}—5—B*—8—s_{BA}—8—/

E_BA: switch A and B

evaluate_energy_rdm(mpo_ab, mpo_ba, rho_ab, rho_ba)[source]

use the density matrix from get_mps_2rdm function

get_mps_2rdm(s_ab, s_ba, mps_a, mps_b)[source]

calculate the density matrix of the two-sites in a unit cell MPS is assumed in canoncial form (orthonormal) rho: ketbra{ket}{bra} = ketbra{Mb}{Mt} = ketbra{26}{37} rho_AB:

2-j 6-n | |

/—1—s_{BA}—1—A*—4-l—s_{AB}—4—B*—8—s_{BA}—8—| | 1-i 8-p | | /—1—s_{BA}—1—A—-5-m—s_{AB}—5—B—-8—s_{BA}—8—/

3-k 7-o

rho_BA: switch A and B when calling the function

normalize_mps(s_left, s_right, mps)[source]
normalize the MPS at A or B site

/—1—s_{BA}—2—At—5—s_{AB}—7–\ | | | 1 4 7 | | |

\—1—s_{BA}—6—Ab—3—s_{AB}—7—/

since weight vectors are diagonal, it reduces to /—1—s_{BA}—1—A—-3—s_{AB}—3–\ | | | 1 2 3 | | |

\—1—s_{BA}—1—A*—3—s_{AB}—3—/

s_left and s_right are switched for site B

normalize_mps_2(s_ab, s_ba, mps_a, mps_b)[source]

normalize mps_a and mps_b at same time same functionality as the previous normalize_mps()

run_tebd(ham_ab, ham_ba, mps_a, mps_b, s_ab, s_ba, mu_ba=None, nu_ab=None, tau=0.1, itype='imag', nmax=1000, midstep=10)[source]

run time evolving block decimation based on MPS of infinite two-site unit cells refer: https://doi.org/10.1103/PhysRevLett.93.040502

update_ortho_mps(rho_left, rho_right, weight, mps_left, mps_right, tol=1e-12)[source]

set the dimer AB or BA linker to cononical form update the weight connecting A and B sites and the MPSs the left and right rho and weight should have same order:

mu_ab, nu_ab, s_ab; or mu_ba, nu_ba, s_ba

/—–s_{AB}—-\ /—–s_{BA}—-\ | | | |

mu_{AB}^T nu_{AB} or mu_{BA} nu_{BA}^T
| | |

\—–s_{AB}—–/ \—–s_{BA}—–/

/—4-l—s_{AB}—l-4–\ | |

—1-i—At—3-k— mu_{AB} nu_{AB}—5-m—Bt—7-o—

2-j 6-n | |

left rho is bottom-up indexed while right rho is top-down indexed first step: orthogonalize density matrices and form new weight second step: svd of new weight and construct new MPSs A * mu * s * nu * B = A * l_U * (l_e * l_U^T * s * r_U * r_e) * r_U^T * B

= (A * l_U /l_e * U_s) * tilde{s} * (Vt_s /r_e * r_U^T * B)

the third dimension of A and first dimension of B might be reduced

wavefunction_analysis.spins.matrix_product_state module

dmrg_opt_gs(h_mpo, mps=None, Tzip=None, nbond=None, pick_eig='SA', nmax=10)[source]
dmrg_sweep(h_mpo, mps, Tzip, pick_eig='SA')[source]

Tzip is given as the right zipper with indecies ordering from top to bottom at every site so that we continue in this function

1). sweep from left to right first 2). and then from right to left 3). return the right zipper in the end

| |

3-l 3-m 1-n | | | T—2-p-1—O—2-q-2—T | | | 1-i 4-j 3-k | | |

get_hamil_from_mpo(h_mpo)[source]
mpo_hamil_disordered(nsite, j=None, hz=None, model=None, spin_j=0.5, sigma=None)[source]
mpo_hamil_uniform(nsite, j=None, hz=None, Hl=None, model=None, spin_j=0.5, sigma=None)[source]
mpo_spin_correlation(mps, sigma=None, ns=None)[source]

expval{sigma_{l}^{+} sigma_{l+1}^{-}}

mps_canonical(ndims, nsite, rand_seed=True, normalize='both')[source]

random bra MPS wavefunction matries at top order of legs: left-bottom-right ket MPS at bottom is the transpose with legs in right-top-left order —1—Mt—3— |

2

2 | | —3—Mb—1—

the left and right legs are virtual bounds to be contracted to adjacent MPS the bottom or top legs are physical bounds (spins) to be contracted to MPO ndims: an array of leg dimensions [nd,ns,nd] in the order [left, bottom, right]

such that the first and third numbers should be same

mps_canonical_left(mps, debug=0)[source]

normalize MPS matrices from the left treat the first two dimensions as a vector to reduce the right leg numbers M1 * M2 = U*s*V^T * M2 = U * (s*V^T*M2) such that M1 is replaced by a smaller U

mps_canonical_right(mps)[source]

normalize MPS matrices from the right treat the last two dimensions as a vector to reduce the left leg numbers M1 * M2 = M1 * U*s*V^T = (M1*U*s) * V^T such that M2 is replaced by a smaller V^T

zipper_from_left(Mt, O, Mb, Tl=array([[[1.]]]))[source]

Tl legs order from bottom to top, default np.ones((1,1,1)) for boundary site Contract Tl from the left with 1). bra Mt at top,

2). operator O at middle, 3). ket Mt at bottom.

/—3—q—1—Mt—3-k– | | | 2 | | | l | | | 3 /—3-k– | | | Tl–2—*p—1—O—-2-j– = Tf–2-j– | | | | 4 \—1-i– | | | *m | | | 2 | |

\—1—n—3—Mb—1-i—

zipper_from_right(Mt, O, Mb, Tr=array([[[1.]]]))[source]

Tr legs order from top to bottom, default np.ones((1,1,1)) for boundary site Contract Tl from the right with 1). bra Mt at top,

2). operator O at middle, 3). ket Mt at bottom.

–i-1—Mt—3—q—1–\

2 | | | *l | | | 3 | –1-i-\ | | |

–j-1—O—-2—p—2—Tr = –2-j–Tf
| |

4 | –3-k–/ | | *m | | | 2 | | |

–k-3—Mb—1—n—3—/

wavefunction_analysis.spins.qaoa module

class QAOA(nsite, **kwargs)[source]

Bases: object

Quantum Approximate Optimization Algorithm class.

property draw_circuit

Draw the quantum circuit.

energy_evaluation(gamma, beta)[source]

Evaluate the energy expectation value for given gamma and beta on circuit.

energy_expectation(wf, **kwargs)[source]

Calculate the energy expectation value for a given wavefunction. wf: wavefunction is an array of size 2**(nrow*ncol)

fd_gradient_evaluation(gamma, beta, eps=0.001)[source]
optimizer(gamma, beta, eps=0.001, max_steps=150, thresh=1e-05)[source]
resolve_circuit_params(**kwargs)[source]

Define the circuit parameters.

class QAOA_Ising(nsite, **kwargs)[source]

Bases: QAOA

E = - sum_{ij} sigma_i sigma_j - h_i sigma_i h is the magnetic field on each spin

energy_expectation(wf, **kwargs)[source]

wf: wavefunction is an array of size 2**(nrow*ncol)

resolve_circuit_params(**kwargs)[source]

Define the circuit parameters for Ising model.

wavefunction_analysis.spins.spin_hamil module

get_prod_spin_list(n, xs='all', j=0.5, np_matrix=True)[source]
the actual sigma_{ix} matrix:

loop over n spins set i-th spin with spin matrices while the rest are identity matrices return n*d supermatrices as Hilbert space operators or basis

the use of these matrices gives exact Hamiltonian in rather huge dimension

get_spin(x, j=0.5)[source]

spin matrices from qutip package

get_spin_mat(x, j=0.5)[source]

reload get_spin() but return numpy matrix by qutip full() function

get_spins(xs='all', j=0.5, np_matrix=True)[source]
hamil_heisenberg_1d(n, j, hz, np_matrix=True, spin_j=0.5, boundary='open')[source]

build xxz 1d-chain spin model hamiltonian H in Hilbert space H = sum_{i}^{n} ( j_{i,x} * sigma_{i,x} sigma_{i+1,x}

  • j_{i,y} * sigma_{i,y} sigma_{i+1,y}

  • j_{i,z} * sigma_{i,z} sigma_{i+1,z})

  • sum_{i}^{n} hz_{i} * sigma_{i,z}

note that when j_{x} = j_{y}

sigma_x sigma_x + sigma_y sigma_y = .5 * (sigma_p sigma_m + sigma_m sigma_p) using ladder operators such that the matrices are real

n: number of 1/2 spins j: spin coupling constant of xx, yy, zz sigma hz: magnetic field strength along z axis for each spin boundary condition: open or periodic

hamil_x_1d(n, j, np_matrix=True, spin_j=0.5, sigma=None, direction='x', boundary='open')[source]

separate one direction for efficiency

hamil_xxz_1d(n, j, delta, hz, np_matrix=True, spin_j=0.5, sigma=None, boundary='open')[source]

j * (xx + yy + zz * delta) reimplement for efficiency using ladder operator by defalut

hamil_xyz_1d(n, j, hz, np_matrix=True, spin_j=0.5, boundary='open')

build xxz 1d-chain spin model hamiltonian H in Hilbert space H = sum_{i}^{n} ( j_{i,x} * sigma_{i,x} sigma_{i+1,x}

  • j_{i,y} * sigma_{i,y} sigma_{i+1,y}

  • j_{i,z} * sigma_{i,z} sigma_{i+1,z})

  • sum_{i}^{n} hz_{i} * sigma_{i,z}

note that when j_{x} = j_{y}

sigma_x sigma_x + sigma_y sigma_y = .5 * (sigma_p sigma_m + sigma_m sigma_p) using ladder operators such that the matrices are real

n: number of 1/2 spins j: spin coupling constant of xx, yy, zz sigma hz: magnetic field strength along z axis for each spin boundary condition: open or periodic

hamil_zeeman_1d(n, hz, np_matrix=True, spin_j=0.5, sigma=None)[source]

separate the magnetic field part for efficiency

Module contents