def get_C2y_symmetry_map_chiral_jastrow(config): mapping = np.zeros((config.total_dof // 2, config.total_dof // 2)) for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) orbit_image = 1 - orbit_preimage r_preimage = np.array( models.lattice_to_physical( [x_preimage, y_preimage, sublattice_preimage], 'hexagonal')) r_preimage -= np.array([1. / np.sqrt(3) / 2, 0.0]) r_image = np.array([-r_preimage[0], r_preimage[1]]) + np.array( [1. / np.sqrt(3) / 2, 0.0]) x_image, y_image, sublattice_image = models.physical_to_lattice( r_image, 'hexagonal') x_image = int(np.rint(x_image)) y_image = int(np.rint(y_image)) x_image = (x_image % config.Ls) y_image = (y_image % config.Ls) index = models.to_linearized_index(x_image, y_image, sublattice_image, orbit_image, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] += 1. assert np.sum(np.abs(mapping.dot(mapping) - np.eye(mapping.shape[0]))) < 1e-12 # C_2y^2 = I return mapping
def get_C4z_symmetry_map(config): assert config.n_sublattices == 1 geometry = 'square' mapping = np.zeros((config.total_dof // 2, config.total_dof // 2)) + 0.0j # trivial mapping rotation_matrix = np.array([[np.cos(2 * np.pi / 4.), np.sin(2 * np.pi / 4.)], \ [-np.sin(2 * np.pi / 4.), np.cos(2 * np.pi / 4.)]]) if config.n_orbitals == 2: rotation_matrix_orbital = rotation_matrix else: rotation_matrix_orbital = np.eye(1) for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) orbit_preimage_vector = np.zeros(config.n_orbitals); orbit_preimage_vector[orbit_preimage] = 1. r_preimage = models.lattice_to_physical([x_preimage, y_preimage, sublattice_preimage], geometry) orbit_image_vector = np.einsum('ij,j->i', rotation_matrix_orbital, orbit_preimage_vector) r_image = np.einsum('ij,j->i', rotation_matrix, r_preimage) x_image, y_image, sublattice_image = models.physical_to_lattice(r_image, geometry) x_image = int(np.rint(x_image)); y_image = int(np.rint(y_image)) x_image = (x_image % config.Ls); y_image = (y_image % config.Ls) for orbit_image in range(config.n_orbitals): coefficient = orbit_image_vector[orbit_image] index = models.to_linearized_index(x_image, y_image, sublattice_image, orbit_image, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] += coefficient assert np.sum(np.abs(mapping.dot(mapping).dot(mapping).dot(mapping) - np.eye(mapping.shape[0]))) < 1e-5 # C_4z^4 = I return mapping + 0.0j
def get_TRS_symmetry_map_chiral_jastrow(config): assert config.n_sublattices == 2 geometry = 'hexagonal' mapping = np.zeros( (config.total_dof // 2, config.total_dof // 2)) # trivial mapping for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) r_preimage = models.lattice_to_physical( [x_preimage, y_preimage, sublattice_preimage], geometry) r_image = r_preimage x_image, y_image, sublattice_image = models.physical_to_lattice( r_image, geometry) x_image = int(np.rint(x_image)) y_image = int(np.rint(y_image)) x_image = (x_image % config.Ls) y_image = (y_image % config.Ls) index = models.to_linearized_index(x_image, y_image, sublattice_image, 1 - orbit_preimage, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] = 1. assert np.sum(np.abs(mapping.dot(mapping) - np.eye(mapping.shape[0]))) < 1e-12 # T^2 = I return mapping
def get_C3z_symmetry_map_chiral_jastrow(config): assert config.n_sublattices == 2 geometry = 'hexagonal' mapping = np.zeros( (config.total_dof // 2, config.total_dof // 2)) # trivial mapping rotation_matrix = np.array([[np.cos(2 * np.pi / 3.), np.sin(2 * np.pi / 3.)], \ [-np.sin(2 * np.pi / 3.), np.cos(2 * np.pi / 3.)]]) for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) r_preimage = models.lattice_to_physical( [x_preimage, y_preimage, sublattice_preimage], geometry) r_image = np.einsum('ij,j->i', rotation_matrix, r_preimage) x_image, y_image, sublattice_image = models.physical_to_lattice( r_image, geometry) x_image = int(np.rint(x_image)) y_image = int(np.rint(y_image)) x_image = (x_image % config.Ls) y_image = (y_image % config.Ls) index = models.to_linearized_index(x_image, y_image, sublattice_image, orbit_preimage, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] = 1. assert np.sum( np.abs( mapping.dot(mapping).dot(mapping) - np.eye(mapping.shape[0]))) < 1e-12 # C_3z^3 = I return mapping
def K_FT(k, K, config, R, spin_dof=1): L = config.Ls n_internal = config.n_sublattices * config.n_orbitals * spin_dof result = np.zeros((n_internal, n_internal)) * 1.0j #result = np.zeros((n_internal // 2, n_internal // 2)) * 1.0j x1, y1 = 0, 0 # rely on translational invariance for sublattice_orbit_spin1 in range(n_internal): ### parse mega-index into components ### spin1 = sublattice_orbit_spin1 % spin_dof sublattice1 = (sublattice_orbit_spin1 // spin_dof) % config.n_sublattices orbit1 = ((sublattice_orbit_spin1 // spin_dof) // config.n_sublattices) % config.n_orbitals first = models.to_linearized_index(x1, y1, sublattice1, orbit1, L, \ config.n_orbitals, config.n_sublattices) + spin1 * (K.shape[0] // spin_dof) for second in range(K.shape[0]): spin2 = second // (K.shape[0] // spin_dof) orbit2, sublattice2, x2, y2 = models.from_linearized_index(second % (K.shape[0] // spin_dof), L, \ config.n_orbitals, config.n_sublattices) element = K[first, second] r2_real = np.einsum('j,jk->k', np.array([x2 - x1, y2 - y1]), R) ft_factor = np.exp(1.0j * np.einsum('i,i', r2_real, k)) result[(orbit1 + config.n_orbitals * sublattice1) + spin1 * result.shape[0] // 2, \ (orbit2 + config.n_orbitals * sublattice2) + spin2 * result.shape[0] // 2] += ft_factor * element #if spin1 == 0 and spin2 == 0: # result[orbit1 + config.n_orbitals * sublattice1, \ # orbit2 + config.n_orbitals * sublattice2] += ft_factor * element return result
def get_Ty_symmetry_map(config, chiral = False): mapping = np.zeros((config.total_dof // 2, config.total_dof // 2)) + 0.0j # trivial mapping for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) index = models.to_linearized_index(x_preimage, (y_preimage + 1) % config.Ls, sublattice_preimage, orbit_preimage, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] += 1. trivial = np.eye(config.total_dof // 2) for i in range(config.Ls): trivial = trivial.dot(mapping) assert np.allclose(trivial, np.eye(config.total_dof // 2)) return mapping + 0.0j
def get_C2y_symmetry_map(config, chiral = False): if config.n_sublattices == 2: geometry = 'hexagonal' else: geometry = 'square' mapping = np.zeros((config.total_dof // 2, config.total_dof // 2)) + 0.0j # trivial mapping for preindex in range(config.total_dof // 2): orbit_preimage, sublattice_preimage, x_preimage, y_preimage = \ models.from_linearized_index(preindex, config.Ls, config.n_orbitals, config.n_sublattices) if config.n_orbitals == 2: if not chiral: orbit_image = orbit_preimage coefficient = -1.0 if orbit_image == 0 else 1.0 else: orbit_image = 1 - orbit_preimage coefficient = -1.0 else: orbit_image = orbit_preimage coefficient = 1.0 r_preimage = np.array(models.lattice_to_physical([x_preimage, y_preimage, sublattice_preimage], geometry)) if geometry == 'hexagonal': r_preimage -= np.array([1. / np.sqrt(3) / 2, 0.0]) r_image = np.array([-r_preimage[0], r_preimage[1]]) + np.array([1. / np.sqrt(3) / 2, 0.0]) else: r_image = np.array([-r_preimage[0], r_preimage[1]]) x_image, y_image, sublattice_image = models.physical_to_lattice(r_image, geometry) x_image = int(np.rint(x_image)); y_image = int(np.rint(y_image)) x_image = (x_image % config.Ls); y_image = (y_image % config.Ls) index = models.to_linearized_index(x_image, y_image, sublattice_image, orbit_image, \ config.Ls, config.n_orbitals, config.n_sublattices) mapping[preindex, index] += coefficient assert np.sum(np.abs(mapping.dot(mapping) - np.eye(mapping.shape[0]))) < 1e-5 # C_2y^2 = I return mapping + 0.0j
def get_kinetic_orbitals(config, filling): Ls = config.Ls K0 = config.K_0 assert config.twist_mesh == 'PBC' Tx, Ty = pairings.Tx_symmetry_map, pairings.Ty_symmetry_map C3z = np.argmax(np.abs(pairings.C3z_symmetry_map_chiral), axis=0) C2y = np.argmax(np.abs(pairings.C2y_symmetry_map_chiral), axis=0) tx, ty = [], [] for i in range(Tx.shape[0]): assert len(np.where(Tx[i, :] == 1)[0]) == 1 assert len(np.where(Ty[i, :] == 1)[0]) == 1 tx.append(np.where(Tx[i, :] == 1)[0][0]) ty.append(np.where(Ty[i, :] == 1)[0][0]) tx, ty = np.array(tx), np.array(ty) np.save('tx.npy', tx) np.save('ty.npy', ty) assert np.allclose(tx[ty], ty[tx]) tx_valley = tx[::2] // 2 ty_valley = ty[::2] // 2 assert np.allclose(tx_valley[ty_valley], ty_valley[tx_valley]) valley = np.concatenate( [np.array([2 * i + 1, 2 * i]) for i in range(config.Ls**2 * 2)]) path = '/home/astronaut/Documents/all_Imada_formats/' ########### writing the spin locations (none) ########## f = open(os.path.join(path, 'locspn_{:d}.def'.format(Ls)), 'w') f.write('================================\n') f.write('NlocalSpin 0\n') f.write('================================\n') f.write('========i_0LocSpn_1IteElc ======\n') f.write('================================\n') for i in range(Ls**2 * 4): f.write(' {:d} 0\n'.format(i)) f.close() symmetries = [np.arange(Ls**2 * 4)] ########### writing the translational symmetries ########## f = open(os.path.join(path, 'qptransidx_{:d}.def'.format(Ls)), 'w') f.write('=============================================\n') f.write('NQPTrans {:d}\n'.format(len(symmetries))) f.write('=============================================\n') f.write('======== TrIdx_TrWeight_and_TrIdx_i_xi ======\n') f.write('=============================================\n') for i in range(len(symmetries)): f.write('{:d} 1.00000\n'.format(i)) for i, symm in enumerate(symmetries): for i_from in range(symm.shape[0]): f.write(' {:d} {:d} {:d}\n'.format( i, i_from, symm[i_from])) f.close() from copy import deepcopy ########### writing the jastrows ########## all_translations = [np.arange(Ls**2 * 4)] curr_trans = tx.copy() all_new_translations = [] for kx in range(config.Ls - 1): new_translations = [symm[curr_trans] for symm in all_translations] all_new_translations.append(deepcopy(new_translations)) curr_trans = curr_trans[tx] for d in all_new_translations: all_translations += d curr_trans = ty.copy() all_new_translations = [] for kx in range(config.Ls - 1): new_translations = [symm[curr_trans] for symm in all_translations] all_new_translations.append(deepcopy(new_translations)) curr_trans = curr_trans[ty] for d in all_new_translations: all_translations += d f = open(os.path.join(path, 'jastrowidx_TRSbroken_{:d}.def'.format(Ls)), 'w') jastrow_ij, jastrow_k, n_jastrows, matrix_jastrows = get_jastrow_fromshift( all_translations, config.Ls, np.around(np.array(config.all_distances), decimals=5), dist_threshold=5.) np.save('check.npy', matrix_jastrows) # G) assert np.allclose(matrix_jastrows, matrix_jastrows.T) matrix_jastrows_trans = matrix_jastrows.copy() matrix_jastrows_trans = matrix_jastrows_trans[:, tx] matrix_jastrows_trans = matrix_jastrows_trans[tx, :] assert np.allclose(matrix_jastrows_trans, matrix_jastrows) matrix_jastrows_trans = matrix_jastrows.copy() matrix_jastrows_trans = matrix_jastrows_trans[:, ty] matrix_jastrows_trans = matrix_jastrows_trans[ty, :] assert np.allclose(matrix_jastrows_trans, matrix_jastrows) f.write('=============================================\n') f.write('NJastrowIdx {:d}\n'.format(n_jastrows + 1)) f.write('ComplexType {:d}\n'.format(0)) f.write('=============================================\n') f.write('=============================================\n') uniques = [] for i in range(config.Ls**2 * 4): for j in range(config.Ls**2 * 4): if i == j: continue f.write(' {:d} {:d} {:d}\n'.format( i, j, matrix_jastrows[i, j])) for i in range(n_jastrows + 1): f.write(' {:d} 1\n'.format(i)) f.close() f = open(os.path.join(path, 'InJastrow_TRSbroken_{:d}.def'.format(Ls)), 'w') f.write('======================\n') f.write('NJastrowIdx {:d}\n'.format(n_jastrows + 1)) f.write('======================\n') f.write('== i_j_JastrowIdx ===\n') f.write('======================\n') for i in range(n_jastrows): f.write('{:d} {:.10f} {:.10f}\n'.format(i, \ np.random.uniform(0.0, 1.0) * 0, np.random.uniform(0.0, 1.0) * 0)) f.write('{:d} {:.10f} {:.10f}\n'.format(n_jastrows, 0, 0)) f.close() f = open(os.path.join(path, 'gutzwilleridx_{:d}.def'.format(Ls)), 'w') f.write('=============================================\n') f.write('NGutzwillerIdx {:d}\n'.format(1)) f.write('ComplexType {:d}\n'.format(0)) f.write('=============================================\n') f.write('=============================================\n') for i in range(4 * Ls**2): f.write(' {:d} {:d}\n'.format(i, 0)) #idx)) for i in range(1): f.write(' {:d} 1\n'.format(i)) f.close() f = open(os.path.join(path, 'InGutzwiller.def'), 'w') f.write('======================\n') f.write('NGutzwillerIdx {:d}\n'.format(1)) f.write('======================\n') f.write('== i_j_GutzwillerIdx ===\n') f.write('======================\n') for i in range(1): f.write('{:d} {:.10f} {:.10f}\n'.format( i, np.random.uniform(0.0, 1.0) * 0, np.random.uniform(0.0, 1.0) * 0)) f.close() ########### writing the modpara ########## f = open(os.path.join(path, 'modpara_{:d}_{:d}.def'.format(Ls, filling)), 'w') f.write('--------------------\n') f.write('Model_Parameters 0\n') f.write('--------------------\n') f.write('VMC_Cal_Parameters\n') f.write('--------------------\n') f.write('CDataFileHead zvo\n') f.write('CParaFileHead zqp\n') f.write('--------------------\n') f.write('NVMCCalMode 0\n') f.write('--------------------\n') f.write('NDataIdxStart 1\n') f.write('NDataQtySmp 1\n') f.write('--------------------\n') f.write('Nsite {:d}\n'.format(Ls**2 * 4)) f.write('Ncond {:d}\n'.format(filling)) f.write('2Sz 0\n') f.write('NSPGaussLeg 8\n') f.write('NSPStot 0\n') f.write('NMPTrans {:d}\n'.format(1)) f.write('NSROptItrStep 400\n') f.write('NSROptItrSmp 40\n') f.write('DSROptRedCut 0.0000001000\n') f.write('DSROptStaDel 0.0200000000\n') f.write('DSROptStepDt 0.0000020000\n') f.write('NVMCWarmUp 400\n') f.write('NVMCInterval 1\n') f.write('NVMCSample 4000\n') f.write('NExUpdatePath 0\n') f.write('RndSeed 1\n') f.write('NSplitSize 1\n') f.write('NStore 0\n') f.write('NSRCG 1\n') f.close() twist = (0, 0.5) twist_exp = [ np.exp(2 * np.pi * 1.0j * twist[0]), np.exp(2 * np.pi * 1.0j * twist[1]) ] fft = get_fft_APBCy(config.Ls) for gap_idx in [40, 9, 36, 14]: #[0, 32, 43, 17, 11, 19]: # 40, 43, 9, 36[!!] print('gap_idx = ', gap_idx) #if config.idx_map[gap_idx] != 13: # continue for gap_val in [0.0, 0.003, 0.02]: #g = gap_val * np.load('the_wave_extended_{:d}.npy'.format(config.Ls)) g = gap_val * np.load( '/home/astronaut/Documents/DQMC_TBG/gaps_8x8/gap_{:d}.npy'. format(gap_idx)) # = gap_val * np.load('/home/astronaut/Documents/XQMC/gaps_6x6_extended/twist_0/gap_{:d}.npy'.format(gap_idx)) #gap_val * np.load('/home/astronaut/Documents/DQMC_TBG/gaps_8x8/gap_{:d}.npy'.format(gap_idx)) if config.Ls == 6: g = models.xy_to_chiral(g, 'pairing', config, True) TRS = np.concatenate( [np.array([2 * i + 1, 2 * i]) for i in range(g.shape[0] // 2)]) g_TRS = g[:, TRS] g_TRS = g_TRS[TRS, :] g = g + g_TRS # * (0.1 if gap_val == 0.02 else 1.) #np.save('sheck.npy', g) if gap_idx in [11, 19]: g = g / 1.0j # g = (g + g.conj()) / np.sqrt(2) print(g[0], 'g[0]') print(g[1], 'g[1]') assert np.allclose(g, g.T) swave = 1e-5 * models.xy_to_chiral( pairings.combine_product_terms( config, pairings.twoorb_hex_all[1]), 'pairing', config, True) assert np.allclose(swave, swave.T) print(swave[0], swave[1], 'swave in chiral basis') g = g + swave gap = models.apply_TBC(config, twist_exp, deepcopy(g), inverse=False) #np.save('the_wave_extended_twisted_{:d}.npy'.format(config.Ls), models.apply_TBC(config, twist_exp, deepcopy(np.load('the_wave_extended_{:d}.npy'.format(config.Ls))), inverse = False)) #exit(-1) gapT = models.apply_TBC(config, twist_exp, deepcopy(g).T, inverse=True) gap_fft = fft.T.conj().dot(gap).dot(fft) gap_check = gap_fft.copy() for i in range(gap_check.shape[0] // 4): #print(i % 4, i // 4) #(np.abs(np.linalg.eig(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4])[0]), i) # print(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4]) #assert np.allclose(gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4], gap_check[i * 4:i * 4 + 4,i * 4:i * 4 + 4].conj().T) gap_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(gap_check)), 0.0) ############ determine required mu_BCS to start ################ K0_up = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False) K0_down = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=True) K0_downT = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=True).T K0_upT = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False).T #print('energies {:d}'.format(config.Ls), np.linalg.eigh(K0_up)[0]) #exit(-1) #### check twist is correct ### K0_fft_plus = fft.conj().T.dot(K0_up).dot(fft) K0_fft_minus = fft.T.dot(K0_up).dot(fft.conj()) K0_check = K0_fft_plus.copy() for i in range(K0_check.shape[0] // 4): K0_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(K0_check)), 0.0) K0_check = K0_fft_minus.copy() for i in range(K0_check.shape[0] // 4): K0_check[i * 4:i * 4 + 4, i * 4:i * 4 + 4] = 0.0 assert np.isclose(np.sum(np.abs(K0_check)), 0.0) assert np.allclose(K0_up, K0_up.conj().T) assert np.allclose(K0_down, K0_down.conj().T) L = K0.shape[0] totalM = np.zeros((4 * L, 4 * L), dtype=np.complex128) totalM[:L, :L] = K0_up totalM[L:2 * L, L:2 * L] = K0_down totalM[2 * L:3 * L, 2 * L:3 * L] = -K0_upT totalM[3 * L:, 3 * L:] = -K0_downT totalM[:L, 3 * L:] = gap totalM[L:2 * L, 2 * L:3 * L] = -gapT totalM[2 * L:3 * L, L:2 * L] = -gapT.conj().T totalM[3 * L:, :L] = gap.conj().T energies = np.linalg.eigh(totalM)[ 0] # energies with BC twist and gap #print(energies) mu_BCS = (energies[filling * 2] + energies[filling * 2 - 1]) / 2. print(energies[filling * 2], energies[filling * 2 - 1]) #assert not np.isclose(energies[filling * 2], energies[filling * 2 - 1]) print('mu_BCS = ', mu_BCS) K0_up = K0_up - np.eye(K0_up.shape[0]) * mu_BCS K0_upT = K0_upT - np.eye(K0_upT.shape[0]) * mu_BCS K0_down = K0_down - np.eye(K0_down.shape[0]) * mu_BCS K0_downT = K0_downT - np.eye(K0_downT.shape[0]) * mu_BCS L = K0.shape[0] totalM = np.zeros((4 * L, 4 * L), dtype=np.complex128) totalM[:L, :L] = K0_up totalM[L:2 * L, L:2 * L] = K0_down totalM[2 * L:3 * L, 2 * L:3 * L] = -K0_upT totalM[3 * L:, 3 * L:] = -K0_downT totalM[:L, 3 * L:] = gap totalM[L:2 * L, 2 * L:3 * L] = -gapT totalM[2 * L:3 * L, L:2 * L] = -gapT.conj().T totalM[3 * L:, :L] = gap.conj().T selected_idxs = np.concatenate( [np.arange(0, L), np.arange(3 * L, 4 * L)]) totalM_updown = totalM[:, selected_idxs] totalM_updown = totalM_updown[selected_idxs, ...] #totalM_updown = np.zeros((2 * L, 2 * L), dtype=np.complex128) #totalM_updown[:L, :L] = K0; totalM_updown[L:, L:] = -K0.T; #totalM_updown[:L, L:] = gap; totalM_updown[L:, :L] = gap.conj().T; selected_idxs = np.arange(L, 3 * L) totalM_downup = totalM[:, selected_idxs] totalM_downup = totalM_downup[selected_idxs, ...] TRS = np.concatenate([ np.array([2 * i + 1, 2 * i], dtype=np.int64) for i in range(L) ]) #totalM_downup = np.zeros((2 * L, 2 * L), dtype=np.complex128) #totalM_downup[:L, :L] = K0; totalM_downup[L:, L:] = -K0.T; #totalM_downup[:L, L:] = -gap.T; totalM_downup[L:, :L] = -gap.conj(); en_updown, W_updown = np.linalg.eigh(totalM_updown) totalM_updown_TRS = totalM_updown[TRS, ...] totalM_updown_TRS = totalM_updown_TRS[..., TRS] totalM_updown_TRS = totalM_updown_TRS.conj() print('after TRS, discrepancy', np.sum(np.abs(totalM_updown_TRS - totalM_updown))) en_downup, W_downup = np.linalg.eigh(totalM_downup) assert np.allclose(en_updown, np.sort(-en_updown)) assert np.allclose(en_downup, np.sort(-en_downup)) en_total, W = np.linalg.eigh(totalM) #print('energies with gap', gap_val, en_total) #print('updown energies', en_updown) #print('downup energies', en_downup) #for en, state in zip(en_downup, W_downup.T): # if np.abs(en + 0.03085819) < 1e-6: # print(en, state) #exit(-1) for i in range(W_updown.shape[1] // 2): v = W_updown[:, i] en = en_updown[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM_updown.dot(v_conj)) / np.dot( v_conj.conj(), v_conj) #print(en_conj, en, np.dot(v_conj.conj(), v_conj), np.dot(v.conj(), totalM_updown.dot(v))) #W_conj.append(v_conj) #assert np.isclose(en_conj, -en) #exit(-1) W_conj = [] for i in range(W.shape[1] // 2): v = W[:, i] en = en_total[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM.dot(v_conj)) #print(en_conj, en) W_conj.append(v_conj) assert np.isclose(en_conj, -en) W_conj = np.array(W_conj).T W[:, W.shape[1] // 2:] = W_conj # make the right form -- but this makes no difference: this is only rearrangement of 2nd part of the array, while we only use the 1st part # why W does not protect that block form? -- or do we even need this form? assert np.allclose( np.diag(W.conj().T.dot(totalM).dot(W)).real, np.diag(W.conj().T.dot(totalM).dot(W))) assert np.allclose( np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real), np.linalg.eigh(totalM)[0]) # with gap 6, W_pieces does not diagonalize totalM! why? W_pieces = np.zeros((4 * L, 4 * L), dtype=np.complex128) W_pieces[:L, :L] = W_updown[:L, :L] W_pieces[3 * L:, 3 * L:] = W_updown[L:, L:] W_pieces[3 * L:, :L] = W_updown[L:, :L] W_pieces[:L, 3 * L:] = W_updown[:L, L:] W_pieces[L:2 * L, L:2 * L] = W_downup[:L, :L] W_pieces[2 * L:3 * L, 2 * L:3 * L] = W_downup[L:, L:] W_pieces[2 * L:3 * L, L:2 * L] = W_downup[L:, :L] W_pieces[L:2 * L, 2 * L:3 * L] = W_downup[:L, L:] #assert np.allclose(np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real), np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)))) #assert np.isclose(np.sum(np.abs(W_pieces.conj().T.dot(totalM).dot(W_pieces) - np.diag(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces))))), 0.0) assert np.isclose( np.sum( np.abs(W.conj().T.dot(totalM).dot(W) - np.diag(np.diag(W.conj().T.dot(totalM).dot(W))))), 0.0) #print(np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real) - np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real)) #assert np.allclose(np.sort(np.diag(W.conj().T.dot(totalM).dot(W)).real), \ # np.sort(np.diag(W_pieces.conj().T.dot(totalM).dot(W_pieces)).real)) #print(np.linalg.det(W_updown), np.linalg.det(W_downup), np.linalg.det(W_updown) * np.linalg.det(W_downup)) #print(np.linalg.det(W_pieces)) #print(np.linalg.det(W)) for i in range(W_updown.shape[1]): v = W_updown[:, i] en = en_updown[i] v_conj = v * 0.0 v_conj[:len(v) // 2] = v[len(v) // 2:].conj() v_conj[len(v) // 2:] = v[:len(v) // 2].conj() en_conj = np.dot(v_conj.conj(), totalM_updown.dot(v_conj)) # print(en_conj, en) #assert en_conj == -en mask = np.zeros((4 * L, 4 * L), dtype=np.complex128) mask[:L, :L] = np.ones((L, L)) mask[L:2 * L, L:2 * L] = np.ones((L, L)) mask[2 * L:3 * L, 2 * L:3 * L] = np.ones((L, L)) mask[3 * L:, 3 * L:] = np.ones((L, L)) mask[3 * L:, :L] = np.ones((L, L)) mask[2 * L:3 * L, L:2 * L] = np.ones((L, L)) mask[L:2 * L, 2 * L:3 * L] = np.ones((L, L)) mask[:L, 3 * L:] = np.ones((L, L)) #totalM[:L, :L] = K0; totalM[L:2 * L, L:2 * L] = K0; totalM[2 * L:3 * L, 2 * L:3 * L] = -K0.T; totalM[3 * L:, 3 * L:] = -K0.T #totalM[:L, 2 * L:3 * L] = gap; totalM[L: 2 * L, 3 * L:] = -gap.T; totalM[3 * L:, L: 2 * L] = -gap.conj(); totalM[2 * L:3 * L, :L] = gap.conj().T; assert np.allclose(totalM, totalM.conj().T) # W = np.linalg.eigh(totalM / 2.)[1] #print(np.linalg.eigh(totalM / 2.)[0]) #assert np.sum(np.abs(W - W * mask)) == 0 #assert np.allclose(W[:W.shape[0] // 2, :W.shape[0] // 2], W[W.shape[0] // 2:, W.shape[0] // 2:].conj()) #assert np.allclose(W[W.shape[0] // 2:, :W.shape[0] // 2], W[:W.shape[0] // 2, W.shape[0] // 2:].conj()) Q, V = W[:W.shape[0] // 2, :W.shape[0] // 2], \ W[W.shape[0] // 2:, :W.shape[0] // 2] Z = (Q.dot(np.linalg.inv(V))) print('max U^{-1} = ', np.max(np.abs(np.linalg.inv(Q))), gap_val, gap_idx) np.save('Z_fast.npy', Z) result = Z[Z.shape[0] // 2:, :Z.shape[0] // 2] Z = Z / np.max(np.abs(Z)) print( np.sum( np.abs(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T))) print( np.sum( np.abs( np.real(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T)))) print( np.sum( np.abs( np.imag(Z[Z.shape[0] // 2:, :Z.shape[0] // 2] + Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T)))) assert np.allclose(Z[Z.shape[0] // 2:, :Z.shape[0] // 2], -Z[:Z.shape[0] // 2, Z.shape[0] // 2:].T) assert np.allclose(Z[Z.shape[0] // 2:, Z.shape[0] // 2:], Z[Z.shape[0] // 2:, Z.shape[0] // 2:] * 0.0) assert np.allclose(Z[:Z.shape[0] // 2, :Z.shape[0] // 2], Z[:Z.shape[0] // 2, :Z.shape[0] // 2] * 0.0) ##### preparing orbital idxs and teir initial values #### vol = 4 * Ls**2 orbital_idxs = -np.ones((vol, vol), dtype=np.int64) f_ij = result f_ij = f_ij / np.abs(np.max(f_ij)) np.save('f_ij_fast.npy', f_ij) current_orb_idx = 0 for xshift in range(Ls): for yshift in range(Ls): for iorb in range(4): for jorb in range(4): if yshift > 0: for ipos in range(Ls**2): i = ipos * 4 + iorb oi, si, xi, yi = models.from_linearized_index( i, config.Ls, config.n_orbitals, config.n_sublattices) j = models.to_linearized_index( (xi + xshift) % Ls, (yi + yshift) % Ls, jorb % 2, jorb // 2, Ls, 2, 2) if yi + yshift > Ls - 1: orbital_idxs[i, j] = current_orb_idx current_orb_idx += 1 for ipos in range(Ls**2): i = ipos * 4 + iorb oi, si, xi, yi = models.from_linearized_index( i, config.Ls, config.n_orbitals, config.n_sublattices) j = models.to_linearized_index( (xi + xshift) % Ls, (yi + yshift) % Ls, jorb % 2, jorb // 2, Ls, 2, 2) if yi + yshift <= Ls - 1: orbital_idxs[i, j] = current_orb_idx current_orb_idx += 1 print('FAST: orbitals after enforcing APBCy remaining:', current_orb_idx) for i in range(current_orb_idx): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) if np.allclose(f_ij, f_ij.T): print( 'FAST: symmetric f_ij = f_ji (singlet): restricting su(2) parameters' ) for i in range(vol): for j in range(vol): orb_ij = orbital_idxs[i, j] orb_ji = orbital_idxs[j, i] orbital_idxs[i, j] = np.min([orb_ij, orb_ji]) orbital_idxs[j, i] = np.min([orb_ij, orb_ji]) new_orbitals = np.unique(orbital_idxs.flatten()) mapping = list(np.sort(new_orbitals)) for i in range(vol): for j in range(vol): orbital_idxs[i, j] = mapping.index(orbital_idxs[i, j]) for i in range(len(mapping)): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) print('FAST: total orbitals su(2) with APBCy', len(mapping)) current_orb_idx = len(mapping) TRS = np.concatenate([[2 * i + 1, 2 * i] for i in range(vol // 2)]) f_trs = f_ij[:, TRS] f_trs = f_trs[TRS, :] if np.allclose(f_trs, f_ij): print('FAST: f_ij = TRS f_ij: resticting TRS parameters') for i in range(vol): for j in range(vol): orb_ij = orbital_idxs[i, j] i_trs = ((i // 2) * 2) + (((i % 2) + 1) % 2) j_trs = ((j // 2) * 2) + (((j % 2) + 1) % 2) orb_ij_trs = orbital_idxs[i_trs, j_trs] #print(f_ij[i, j], f_ij[i_trs, j_trs]) assert np.isclose(f_ij[i, j], f_ij[i_trs, j_trs]) orbital_idxs[i, j] = np.min([orb_ij, orb_ij_trs]) orbital_idxs[i_trs, j_trs] = np.min([orb_ij, orb_ij_trs]) #for i in range(current_orb_idx): # if np.sum(orbital_idxs.flatten() == i) == 0: # print('orbital', i, 'is missing') new_orbitals = np.unique(orbital_idxs.flatten()) mapping = list(np.sort(new_orbitals)) for i in range(vol): for j in range(vol): orbital_idxs[i, j] = mapping.index(orbital_idxs[i, j]) for i in range(len(mapping)): values = f_ij.flatten()[orbital_idxs.flatten() == i] assert np.isclose(np.std(values - values.mean()), 0.0) print('FAST: total orbitals su(2) with APBCy and TRS!', len(mapping) + 1) current_orb_idx = len(mapping) np.save('orbital_idxs_fast.npy', orbital_idxs) f = open( os.path.join( path, 'InOrbital_extended_{:d}_{:d}_{:d}_{:.4f}.def'.format( Ls, gap_idx, filling, gap_val)), 'w') f.write('======================\n') f.write('NOrbitalIdx {:d}\n'.format(current_orb_idx)) f.write('======================\n') f.write('== i_j_OrbitalIdx ===\n') f.write('======================\n') for k in range(current_orb_idx): mask = (orbital_idxs == k) val = np.sum(f_ij * mask) / np.sum(mask) f.write('{:d} {:.20f} {:.20f}\n'.format( k, val.real, val.imag)) f.close() ########### writing the orbitals indexes ########## f = open( os.path.join( path, 'orbitalidx_extended_{:d}_{:d}_{:d}.def'.format( Ls, gap_idx, filling)), 'w') f.write('=============================================\n') f.write('NOrbitalIdx {:d}\n'.format(current_orb_idx)) f.write('ComplexType {:d}\n'.format(1)) f.write('=============================================\n') f.write('=============================================\n') for i in range(config.Ls**2 * 4): for j in range(config.Ls**2 * 4): f.write(' {:d} {:d} {:d}\n'.format( i, j, orbital_idxs[i, j])) for i in range(current_orb_idx): f.write(' {:d} 1\n'.format(i)) f.close() twist_exp = [ np.exp(2.0j * np.pi * twist[0]), np.exp(2.0j * np.pi * twist[1]) ] K_0_twisted = models.apply_TBC(config, twist_exp, deepcopy(K0), inverse=False) ########### writing the K--matrix ########## K0_up_int = K0_up - np.diag(np.diag(K0_up)) K0_down_int = K0_down - np.diag(np.diag(K0_down)) f = open( os.path.join(path, 'trans_{:d}_{:.3f}_{:.3f}.def'.format(Ls, *twist)), 'w') f.write('========================\n') f.write('NTransfer {:d}\n'.format( 2 * np.sum(np.abs(K0_up_int) > 1e-7))) f.write('========================\n') f.write('========i_j_s_tijs======\n') f.write('========================\n') for i in range(K_0_twisted.shape[0]): for j in range(K_0_twisted.shape[1]): if np.abs(K0_up_int[i, j]) > 1e-7: f.write( ' {:d} 0 {:d} 0 {:.6f} {:.6f}\n'. format(i, j, np.real(-K0_up_int[i, j]), np.imag(-K0_up_int[i, j]))) f.write( ' {:d} 1 {:d} 1 {:.6f} {:.6f}\n'. format(i, j, np.real(-K0_down_int[i, j]), np.imag(-K0_down_int[i, j]))) f.close() return
def plot_Jastrow(config, Jastrow, index): geometry = 'hexagonal' if config.n_sublattices == 2 else 'square' pairing, name = Jastrow if geometry == 'hexagonal': R = models.R_hexagonal else: R = models.R_square set_style() textshift = np.array([0.1, 0.1]) x1, y1 = config.Ls // 2, config.Ls // 2 for sublattice1 in range(config.n_sublattices): for orbit1 in range(config.n_orbitals): first = models.to_linearized_index(x1, y1, sublattice1, orbit1, config.Ls, config.n_orbitals, config.n_sublattices) for second in range(config.total_dof // 2): orbit2, sublattice2, x2, y2 = models.from_linearized_index(deepcopy(second), config.Ls, \ config.n_orbitals, config.n_sublattices) if pairing[first, second] == 0: continue value = 1. labelstring = str(value) labelstring = '(' + str(orbit1) + '-' + str( orbit2) + '), ' + labelstring + ' ' + str(index) r1 = np.array([x1, y1]).dot(R) + sublattice1 * np.array( [1, 0]) / np.sqrt(3) # always 0 in the square case r2 = np.array([ x2, y2 ]).dot(R) + sublattice2 * np.array([1, 0]) / np.sqrt(3) r1_origin = np.array([x1, y1]).dot(R) r1 = r1 - r1_origin r2 = r2 - r1_origin if sublattice2 == 0: plt.scatter(*r2, s=20, color='red') else: plt.scatter(*r2, s=20, color='blue') if np.sum(np.abs(r1 - r2)) < 1e-5: plt.plot([r1[0]], [r1[1]], marker='*', ms=10) else: plt.annotate(s='', xy=r2, xytext=r1, arrowprops=dict(arrowstyle='->')) textshift = np.array([r2[1] - r1[1], r1[0] - r2[0]]) textshift = textshift / np.sqrt(np.sum(textshift**2) + 1e-5) shiftval = 0.1 - (orbit1 * config.n_orbitals + orbit2) * 0.1 / 2 plt.text(*(r2 + shiftval * textshift + np.random.uniform(-0.05, 0.05, 2)), labelstring, zorder=10, fontsize=8) plt.xlabel('$x$') plt.ylabel('$y$') plt.title(name) plt.savefig('../plots/' + name + '.pdf') plt.clf() return
def plot_wave(config, wave, name): geometry = 'hexagonal' if config.n_sublattices == 2 else 'square' if geometry == 'hexagonal': R = models.R_hexagonal else: R = models.R_square set_style() textshift = np.array([0.1, 0.1]) x1, y1 = config.Ls // 2, config.Ls // 2 for sublattice1 in range(config.n_sublattices): for orbit1 in range(config.n_orbitals): first = models.to_linearized_index(x1, y1, sublattice1, orbit1, config.Ls, config.n_orbitals, config.n_sublattices) for second in range(config.total_dof // 2): orbit2, sublattice2, x2, y2 = models.from_linearized_index(deepcopy(second), config.Ls, \ config.n_orbitals, config.n_sublattices) if wave[first, second] == 0: continue value_uu = wave[first, second] value_dd = wave[first + config.total_dof // 2, second + config.total_dof // 2] labelstring_up = str(value_uu) if np.abs(value_uu.imag) < 1e-10: labelstring_up = str(value_uu.real) elif geometry == 'hexagonal': if np.abs(value_uu - np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$\\omega$' if np.abs(value_uu + np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$-\\omega$' if np.abs(value_uu - np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$\\omega^*$' if np.abs(value_uu + np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$-\\omega^*$' if np.abs(value_uu - 1.0j * np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$i \\omega$' if np.abs(value_uu + 1.0j * np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$-i \\omega$' if np.abs(value_uu - 1.0j * np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$i \\omega^*$' if np.abs(value_uu + 1.0j * np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_up = '$-i \\omega^*$' if np.abs(value_uu - 1.0j) < 1e-7: labelstring_up = '$i$' if np.abs(value_uu + 1.0j) < 1e-7: labelstring_up = '$-i$' if np.abs(value_uu - 1.0) < 1e-7: labelstring_up = '$1$' if np.abs(value_uu + 1.0) < 1e-7: labelstring_up = '$-1$' if np.abs(value_uu - 1.0j * np.sqrt(3)) < 1e-7: labelstring_up = '$i\\sqrt{3}$' if np.abs(value_uu + 1.0j * np.sqrt(3)) < 1e-7: labelstring_up = '$-i\\sqrt{3}$' if np.abs(value_uu - np.sqrt(3)) < 1e-7: labelstring_up = '$\\sqrt{3}$' if np.abs(value_uu + np.sqrt(3)) < 1e-7: labelstring_up = '$-\\sqrt{3}$' labelstring_up = '(' + str(orbit1) + '-' + str( orbit2) + '), ' + labelstring_up + ', $\\uparrow$' labelstring_down = str(value_dd) if np.abs(value_dd.imag) < 1e-10: labelstring_down = str(value_dd.real) elif geometry == 'hexagonal': if np.abs(value_dd - np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$\\omega$' if np.abs(value_dd + np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$-\\omega$' if np.abs(value_dd - np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$\\omega^*$' if np.abs(value_dd + np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$-\\omega^*$' if np.abs(value_dd - 1.0j * np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$i \\omega$' if np.abs(value_dd + 1.0j * np.exp(2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$-i \\omega$' if np.abs(value_dd - 1.0j * np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$i \\omega^*$' if np.abs(value_dd + 1.0j * np.exp(-2.0 * np.pi / 3.0 * 1.0j)) < 1e-11: labelstring_down = '$-i \\omega^*$' if np.abs(value_dd - 1.0j) < 1e-7: labelstring_down = '$i$' if np.abs(value_dd + 1.0j) < 1e-7: labelstring_down = '$-i$' if np.abs(value_dd - 1.0) < 1e-7: labelstring_down = '$1$' if np.abs(value_dd + 1.0) < 1e-7: labelstring_down = '$-1$' if np.abs(value_dd - 1.0j * np.sqrt(3)) < 1e-7: labelstring_down = '$i\\sqrt{3}$' if np.abs(value_dd + 1.0j * np.sqrt(3)) < 1e-7: labelstring_down = '$-i\\sqrt{3}$' if np.abs(value_dd - np.sqrt(3)) < 1e-7: labelstring_down = '$\\sqrt{3}$' if np.abs(value_dd + np.sqrt(3)) < 1e-7: labelstring_down = '$-\\sqrt{3}$' labelstring_down = '(' + str(orbit1) + '-' + str( orbit2) + '), ' + labelstring_down + ', $\\downarrow$' r1 = np.array([x1, y1]).dot(R) + sublattice1 * np.array( [1, 0]) / np.sqrt(3) # always 0 in the square case r2 = np.array([ x2, y2 ]).dot(R) + sublattice2 * np.array([1, 0]) / np.sqrt(3) r1_origin = np.array([x1, y1]).dot(R) r1 = r1 - r1_origin r2 = r2 - r1_origin if sublattice2 == 0: plt.scatter(*r2, s=20, color='red') else: plt.scatter(*r2, s=20, color='blue') plt.annotate(s='', xy=r2, xytext=r1, arrowprops=dict(arrowstyle='->')) textshift = np.array([r2[1] - r1[1], r1[0] - r2[0]]) textshift = textshift / np.sqrt(np.sum(textshift**2) + 1e-5) shiftval = 0.4 - ( (orbit1 * config.n_orbitals + orbit2) + 4) * 0.1 plt.text(*(r2 + np.random.uniform(-0.003, 0.003, size=2) + shiftval * textshift), labelstring_up, zorder=10, fontsize=8, color='orange') shiftval = 0.4 - ((orbit1 * config.n_orbitals + orbit2)) * 0.1 plt.text(*(r2 + np.random.uniform(-0.003, 0.003, size=2) + shiftval * textshift), labelstring_down, zorder=10, fontsize=8, color='violet') plt.xlabel('$x$') plt.ylabel('$y$') #plt.xlim([-0.5, 1.25]) #plt.ylim([-0.75, 0.75]) # plt.title(name + ' pairing') plt.savefig('../plots/' + name + '.pdf') plt.clf() return