def return_mpo(N, hamParams, periodic=True): # Extract Hamiltonian Parameters (J, hx, hz) = hamParams # List to hold all mpos mpoL = [] # Mainmpo mpo = [None] * N for site in range(N): if (site == 0): mpo[site] = array([[-J * hx * X - J * hz * Z, -J * X, I]]) elif (site == N - 1): mpo[site] = array([[I], [X], [-J * hx * X - J * hz * Z]]) else: mpo[site] = array([[I, z, z], [X, z, z], [-J * hx * X - J * hz * Z, -J * X, I]]) # Add mpo to mpo list mpoL.append(mpo) # Add periodic interaction if needed mpo = [None] * N mpo[0] = array([[-J * X]]) mpo[-1] = array([[X]]) mpoL.append(mpo) # Reorder the bonds mpoL = reorder_bonds(mpoL) # Return results return mpoL
def return_mpo(N, hamParams): # Extract Parameter Values Omega = hamParams[0] Delta = hamParams[1] V = hamParams[2] # Create the main mpo mpo = [] for site in range(N): # Create the generic local operator local_op = Omega * Sx - Delta * v # First Site (row mpo) if (site == 0): # Create the MPO tensor ten = array([[local_op, v, I]]) mpo.append(ten) # Last site (column mpo) elif (site == N - 1): # Creat the mpo tensor ten = zeros((N + 1, 1, 2, 2), dtype=float_) # Fill in column ten[0, 0, :, :] = I for site2 in range(N - 1): coef = V * (N - site2 - 1)**(-6.) ten[site2 + 1, 0, :, :] = coef * v ten[N, 0, :, :] = local_op mpo.append(ten) # Interior Sites (full mpo) else: # Create the mpo tensor ten = zeros((site + 2, site + 3, 2, 2), dtype=float_) # Fill in first column ten[0, 0, :, :] = I for site2 in range(site): coef = V * (site - site2)**(-6.) ten[site2 + 1, 0, :, :] = coef * v ten[site + 1, 0, :, :] = local_op # Fill in bottom row ten[site + 1, site + 1] = v ten[site + 1, site + 2] = I # Fill in interior with identities for site2 in range(site): ten[site2 + 1, site2 + 1] = I mpo.append(ten) mpo = [mpo] mpo = reorder_bonds(mpo) return mpo
def return_mpo(N, hamParams, periodic=False, hermitian=False): if not isinstance(hamParams[0], (collections.Sequence)): hamParams = val2vecParams(N, hamParams) else: hamParams = extractParams(N, hamParams) if periodic: mpo = periodic_mpo(N, hamParams, hermitian=hermitian) else: mpo = open_mpo(N, hamParams, hermitian=hermitian) mpo = reorder_bonds(mpo) return mpo
def return_mpo(N, hamParams, hermitian=False): if hasattr(N, '__len__'): Nx = N[0] Ny = N[1] else: Nx = N Ny = N # Generate MPO mpo = open_mpo(Nx, Ny, hamParams, hermitian=hermitian) # Reorder bonds to match mps mpo = reorder_bonds(mpo) return mpo
def act_mpo(N, hamParams, periodic=False, singleBond=False, bond=None): if not isinstance(hamParams[0], (collections.Sequence, npndarray)): hamParams = val2vecParams(N, hamParams) else: hamParams = extractParams(N, hamParams) if singleBond: mpo = single_bond_act(N, hamParams, bond=bond) else: if periodic: mpo = periodic_act(N, hamParams) else: mpo = open_act(N, hamParams) mpo = reorder_bonds(mpo) return mpo
def return_mpo(N,hamParams): h = hamParams[0] print('h = {}'.format(h)) # List to hold all mpos mpoL = [] # Mainmpo mpo = [None]*N for site in range(N): if (site == 0): mpo[site] = array([[h*Z, X, I]]) elif (site == N-1): mpo[site] = array([[I],[X],[h*Z]]) else: mpo[site] = array([[I, z, z], [X, z, z], [h*Z, X, I]]) # Add mpo to mpo list mpoL.append(mpo) # Reorder the bonds mpoL = reorder_bonds(mpoL) # Return results return mpoL
# Run diagonalization ----------------------- H = mpo2mat(mpo) E0, vl, vr = ed(mpo, left=True) vr0 = vr[:, 0] vl0 = vl[:, 0] print('E0 = {}'.format(E0[0].real)) # Evaluate random parameters --------------- # Local Density density = zeros((Nx, Ny)) for x in range(Nx): for y in range(Ny): rho_mpo = [array([[I]])] * (Nx * Ny) rho_mpo[x * Nx + y] = array([[n]]) rho_mpo = [rho_mpo] rho_mpo = reorder_bonds(rho_mpo) rho = mpo2mat(rho_mpo) density[x, y] = dot(vl0.conj(), dot(rho, vr0)).real print('Density({},{}) = {}'.format(x, y, density[x, y])) print('Total Density = {}'.format(summ(density))) # Local Vertical Current ycurr = 0. for x in range(Nx): for y in ['bottom'] + range(Ny - 1) + ['top']: cmpo = curr_mpo((Nx, Ny), hamParams, periodicx=False, periodicy=False, singleBond=True, orientation='vert', xbond=x,
def return_mpo(N, hamParams, D=100, const=0.): # Extract Parameter Values Omega = hamParams[0] Delta = hamParams[1] V = hamParams[2] # Make Interaction Matrix V_{n,n'} (Eq. B1 & B4 Vnn_ = zeros((N, N), dtype=float_) for n1 in range(N): for n2 in range(n1 + 1, N): Vnn_[n1, n2] = V * (n2 - n1)**(-6) # Get upper blocks Vp = [] for p in range(N): Vp.append(Vnn_[0:p + 1, p:]) if True: # Explicit SVDs ################################################## Up = [] Sp = [] Wp = [] for p in range(N): U, S, W = svd(Vp[p]) # Do Truncation if len(S) > D: U = U[:, :D] S = S[:D] W = W[:D, :] # Save results Up.append(U) Sp.append(S) Wp.append(W) # Now Calculate X tensors Xp = [] Xp.append(Up[0]) for p in range(1, N): Upm1 = add_row_col(Up[p - 1]) _Upm1 = pinv(Upm1) X = einsum('ij,jk->ik', _Upm1, Up[p]) Xp.append(X) # Now Calculate Omega tensors Op = [] for p in range(N): Op.append(einsum('ij,j,jk->ik', Xp[p], Sp[p], Wp[p])) else: # Recursive SVDs ################################################## Up = [] Sp = [] Wp = [] Xp = [] Op = [] # Do SVD of Vp[0] U, S, W = svd(Vp[0]) Up.append(U) Xp.append(U) Sp.append(S) Wp.append(W) Op.append(einsum('ij,j,jk->ik', Xp[0], Sp[0], Wp[0])) # Now move on to second (and remaining) site(s) for p in range(1, N): # Calculate Omega SW = einsum('i,ij->ij', S, W[:, 1:]) (n1, n2) = Vp[p].shape O = add_row(SW, Vp[p][n1 - 1, :]) X, S, W = svd(O) # Do Truncation if len(S) > D: X = X[:, :D] S = S[:D] W = W[:D, :] U = einsum('ij,jk->ik', add_row_col(U), X) Up.append(U) Xp.append(X) Sp.append(S) Wp.append(W) Op.append(O) # Put compressed operators into an MPO mpo = [] for site in range(N): # Create the generic local operator local_op = -Omega * Sx - Delta * v if site == 0: # Create the MPO Tensor local_op += const * I ten = array([[local_op, Xp[0][0, 0] * v, I]]) mpo.append(-ten) elif site == N - 1: # Create an empty tensor (n1, n2) = Xp[site].shape ten_size = (n1 + 1, 1, 2, 2) ten = zeros(ten_size, dtype=float_) # Insert left column for om_iter in range(n1 - 1): ten[om_iter + 1, 0, :, :] = Op[site][om_iter, 0] * v # Insert identity at top ten[0, 0, :, :] = I # Insert local op at bottom ten[n1, 0, :, :] = local_op mpo.append(ten) else: # Create an empty tensor (n1, n2) = Xp[site].shape ten_size = (n1 + 1, n2 + 2, 2, 2) ten = zeros(ten_size, dtype=float_) # Insert identities ten[0, 0, :, :] = I ten[n1, n2 + 1, :, :] = I # Insert left column for om_iter in range(n1 - 1): ten[om_iter + 1, 0, :, :] = Op[site][om_iter, 0] * v # PH - Might be swapped? # Insert central X tensors (n1, n2) = Xp[site].shape for xi1 in range(n1): for xi2 in range(n2): if xi1 == n1 - 1: ten[xi1 + 1, xi2 + 1, :, :] = Xp[site][ xi1, xi2] * v # PH - Might be swapped again... else: ten[xi1 + 1, xi2 + 1, :, :] = Xp[site][ xi1, xi2] * I # PH - Might be swapped again... # Insert local operators ten[ten_size[0] - 1, 0, :, :] = local_op # Put the tensor into the MPO mpo.append(ten) # Reshape MPO mpo = [mpo] mpo = reorder_bonds(mpo) return mpo