def test_e03(): """ Minimal test of low-energy spectrum search. """ # expected number of states with dE<1 for droplet instance 1 for L=128 expected_number_of_states = 31 ins0 = search_spectrum_droplet(D=16, excitations_encoding=1, rot=0, precondition=False, dE=1.) ins1 = search_spectrum_droplet(D=16, excitations_encoding=1, rot=1, precondition=False, dE=1.) ins2 = search_spectrum_droplet(D=16, excitations_encoding=2, rot=2, precondition=False, dE=1.) ins3 = search_spectrum_droplet(D=16, excitations_encoding=3, rot=3, precondition=False, dE=1.) ins0.decode_low_energy_states(max_dEng=1.) ins1.decode_low_energy_states(max_dEng=1.) ins2.decode_low_energy_states(max_dEng=1.) ins3.decode_low_energy_states(max_dEng=1.) assert(len(ins0.energy) == expected_number_of_states) assert(len(ins1.energy) == expected_number_of_states) assert(len(ins2.energy) == expected_number_of_states) assert(len(ins3.energy) == expected_number_of_states) err0 = max(abs(ins0.energy - ins1.energy)) err1 = max(abs(ins1.energy - ins2.energy)) err2 = max(abs(ins1.energy - ins3.energy)) assert(max(err0, err1, err2) < 1e-4) st0 = ins0.binary_states() st1 = ins1.binary_states() st2 = ins2.binary_states() st3 = ins3.binary_states() filename_in = os.path.join(os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera128_spinglass_power/001.txt') J = tnac4o.load_Jij(filename_in) J = tnac4o.Jij_f2p(J) J = tnac4o.round_Jij(J, 1 / 75) E0 = tnac4o.energy_Jij(J, st0) E1 = tnac4o.energy_Jij(J, st1) E2 = tnac4o.energy_Jij(J, st2) E3 = tnac4o.energy_Jij(J, st3) err0 = max(abs(E1 - E0)) err1 = max(abs(E2 - E0)) err2 = max(abs(E3 - E0)) assert(max(err0, err1, err2) < 1e-4)
def test_e02(): """ Minimal test of Gibbs sampling. """ M = 128 ins0 = gibbs_sampling(M=M, precondition=False, rot=0) assert(M == len(ins0.states)) ins1 = gibbs_sampling(M=M, precondition=False, rot=1) filename_in = os.path.join(os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera128_spinglass_power/001.txt') # test consistency of energies J = tnac4o.load_Jij(filename_in) J = tnac4o.Jij_f2p(J) J = tnac4o.round_Jij(J, 1 / 75) st0 = ins0.binary_states() st1 = ins1.binary_states() E0 = tnac4o.energy_Jij(J, st0) E1 = tnac4o.energy_Jij(J, st1) err0 = max(abs(ins0.energy - E0)) err1 = max(abs(ins1.energy - E1)) assert(max(err0, err1) < 1e-6)
def search_gs_droplet(L=128, instance=1, rot=0, beta=3, D=48, M=1024, relative_P_cutoff=1e-8, precondition=True): ''' Runs a script searching for a ground state of a droplet instance. Instances are located in the folder ./../instances/. Reasonable (but not neccesarily optimal) values of parameters for those instances are set as default. Some can be changed using options in this script. See documentation for more information. ''' # Initialize global logging level to INFO. logging.basicConfig(level='INFO') # filename of the instance of interest if L == 128: Nx, Ny, Nc = 4, 4, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera128_spinglass_power/%03d.txt' % instance) elif L == 512: Nx, Ny, Nc = 8, 8, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera512_spinglass_power/%03d.txt' % instance) elif L == 1152: Nx, Ny, Nc = 12, 12, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera1152_spinglass_power/%03d.txt' % instance) elif L == 2048: Nx, Ny, Nc = 16, 16, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera2048_spinglass_power/%03d.txt' % instance) # load Jij couplings J = tnac4o.load_Jij(filename_in) # those instances are defined with spin numering starting with 1 # change to 0-base indexing J = tnac4o.Jij_f2p(J) # round J to multiplies of 1/75 for those instances # as couplings were saved with 6 digit precision J = tnac4o.round_Jij(J, 1 / 75) # initializes solver ins = tnac4o.tnac4o(mode='Ising', Nx=Nx, Ny=Ny, Nc=Nc, J=J, beta=beta) ins.logger.info( 'Analysing droplet instance %1d on chimera graph of %1d sites.' % (instance, L)) # rotates graph to contract from different side/edge if rot > 0: ins.rotate_graph(rot=rot) # applies preconditioning using balancing heuristics if precondition: ins.precondition(mode='balancing') # search ground state (return lowest energy, full data stored in ins) Eng = ins.search_ground_state(M=M, relative_P_cutoff=relative_P_cutoff, Dmax=D) return ins
def main(): """ Runs a script loading solution for low energy spectrum, and decoding it. Instances are located in the folder ./../instances/. Reasonable (but not neccesarily optimal) values of parameters for those instances are set as default. Some can be changed using options in this script. See documentation for more information. """ # Initialize global logging level to INFO. parser = argparse.ArgumentParser() parser.add_argument("-L", type=int, choices=[128, 512, 1152, 2048], default=128, help="Size of chimera graph. Default is 128 (C4).") parser.add_argument("-ins", type=int, choices=range(1, 101), metavar="[1-100]", default=1, help="Instance number (1-100). Default is 1.") parser.add_argument("-r", type=int, default=0, help="Rotate graph by 90 deg r times. Default is 0. \ Used to try to search/contract from different sides." ) parser.add_argument("-b", type=float, default=3, help="Inverse temperature. Default is set at 3.") parser.add_argument( "-D", type=int, default=48, help="Maximal bond dimension of boundary MPS used to contract PEPS.") parser.add_argument( "-M", type=int, default=2**10, help= "Maximal number of partial states kept during branch and bound search." ) parser.add_argument( "-P", type=float, default=1e-8, help= "Cuttof on the range of relative probabilities kept during branch and bound search." ) parser.add_argument("-dE", type=float, default=1.0, help="Limit on excitation energy.") parser.add_argument( "-hd", type=int, default=0, help= "Lower limit of Hamming distance between states (while merging). Outputs less states." ) parser.add_argument( "-max_st", type=int, default=2**20, help= "Limit total number of low energy states which is being reconstructed." ) parser.add_argument("-ee", type=int, default=1, choices=[1, 2, 3], help="Strategy used to compress droplets. \ For excitations_encoding = 2 or 3 small noise is added to the couplings slighly modyfings energies." ) parser.add_argument('-no-pre', dest='pre', action='store_false', help="Do not use preconditioning.") parser.set_defaults(pre=True) args = parser.parse_args() if args.L == 128: Nx, Ny, Nc = 4, 4, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera128_spinglass_power/%03d.txt' % args.ins) elif args.L == 512: Nx, Ny, Nc = 8, 8, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera512_spinglass_power/%03d.txt' % args.ins) elif args.L == 1152: Nx, Ny, Nc = 12, 12, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera1152_spinglass_power/%03d.txt' % args.ins) elif args.L == 2048: Nx, Ny, Nc = 16, 16, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera2048_spinglass_power/%03d.txt' % args.ins) # load Jij couplings J = tnac4o.load_Jij(filename_in) # those instances are defined with spin numering starting with 1 # change to 0-base indexing J = tnac4o.Jij_f2p(J) # round J to multiplies of 1/75 for those instances # as couplings were saved with 6 digit precision J = tnac4o.round_Jij(J, 1 / 75) logging.basicConfig(level='INFO') # file to load file_name = os.path.join( os.path.dirname(__file__), './results/L=%1d_ins=%03d_r=%1d_beta=%0.2f_D=%1d_M=%1d_P=%0.2e_ee=%1d_dE=%0.3f_hd=%1d_pre=%1d.npy' % (args.L, args.ins, args.r, args.b, args.D, args.M, args.P, args.ee, args.dE, args.hd, args.pre)) # load instance try: ins = tnac4o.load(file_name) except FileNotFoundError: raise Exception( 'First run script e03_search_spectrum_droplet_instances.py with option `-s`' ) print('Decomposing excitation structure into low energy states.') keep_time_decode = time.time() Eng = ins.decode_low_energy_states(max_dEng=args.dE, max_states=args.max_st) bit_strings = ins.binary_states() ins.logger.info('Decoding spectrum elapse time : %.2f seconds', time.time() - keep_time_decode) ins.show_solution() Eng = tnac4o.energy_Jij(J, bit_strings) error = max(abs(ins.energy - Eng)) print('Consistency of different ways to calculate energies.') print('For ee = 2 or 3 expected difference is ~1e-6 due to applied noise.') print('Difference = ', error) return error
def search_spectrum_droplet(L=128, instance=1, rot=0, beta=3, D=48, M=1024, relative_P_cutoff=1e-8, excitations_encoding=1, dE=1., hd=0, precondition=True): """ Runs a script searching for ground state of `droplet instances`. Instances are located in the folder ./../instances/. Reasonable (but not neccesarily optimal) values of parameters for those instances are set as default. Some can be changed using options in this script. See documentation for more information. """ # Initialize global logging level to INFO. logging.basicConfig(level='INFO') # filename of the instance of interest if L == 128: Nx, Ny, Nc = 4, 4, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera128_spinglass_power/%03d.txt' % instance) elif L == 512: Nx, Ny, Nc = 8, 8, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera512_spinglass_power/%03d.txt' % instance) elif L == 1152: Nx, Ny, Nc = 12, 12, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera1152_spinglass_power/%03d.txt' % instance) elif L == 2048: Nx, Ny, Nc = 16, 16, 8 filename_in = os.path.join( os.path.dirname(__file__), './../instances/Chimera_droplet_instances/chimera2048_spinglass_power/%03d.txt' % instance) # load Jij couplings J = tnac4o.load_Jij(filename_in) # those instances are defined with spin numering starting with 1 # change to 0-base indexing J = tnac4o.Jij_f2p(J) # round J to multiplies of 1/75 for those instances # as couplings were saved with 6 digit precision J = tnac4o.round_Jij(J, 1 / 75) # initialize solver ins = tnac4o.tnac4o(mode='Ising', Nx=Nx, Ny=Ny, Nc=Nc, J=J, beta=beta) ins.logger.info( 'Analysing droplet instance %1d on chimera graph of %1d sites.' % (instance, L)) # rotates graph if rot > 0: ins.rotate_graph(rot=rot) # if using excitations_encoding = 2 or 3 # adds small noise to remove accidental degeneracies if excitations_encoding > 1: ins.add_noise(amplitude=1e-7) # applies preconditioning using balancing heuristics if precondition: ins.precondition(mode='balancing') # search for low energy spectrum (return lowest energy, full data stored in ins) Eng = ins.search_low_energy_spectrum( excitations_encoding=excitations_encoding, M=M, relative_P_cutoff=relative_P_cutoff, Dmax=D, max_dEng=dE, lim_hd=hd) return ins