def _test_logdetM(self, kappa): "Test log(det(M))." nx = kappa.rows() self.assertRaises(RuntimeError, lambda msg: isle.logdetM(isle.HubbardFermiMatrixDia(kappa, 1, 1), isle.CDVector(nx), isle.Species.PARTICLE), msg="logdetM must throw a RuntimeError when called with mu != 0. If this bug has been fixed, update the unit test!") for nt, mu, sigmaKappa, species, rep in itertools.product((4, 8, 32), [0], (-1, 1), (isle.Species.PARTICLE, isle.Species.HOLE), range(N_REP)): hfm = isle.HubbardFermiMatrixDia(kappa/nt, mu/nt, sigmaKappa) phi = _randomPhi(nx*nt) plain = isle.logdet(isle.Matrix(hfm.M(phi, species))) viaLU = isle.logdetM(hfm, phi, species) self.assertAlmostEqual(plain, viaLU, places=10, msg="Failed check log(det(M)) in repetition {}".format(rep)\ + "for nt={}, mu={}, sigmaKappa={}, species={}:".format(nt, mu, sigmaKappa, species)\ + "\nplain = {}".format(plain) \ + "\nviaLU = {}".format(viaLU))
def _testConstructionNt3(self, kappa, mu, sigmaKappa): "Check if nt=3 HFM is constructed properly." nt = 3 nx = kappa.rows() hfm = isle.HubbardFermiMatrixDia(kappa, mu, sigmaKappa) phi = _randomPhi(nx*nt) auto = np.array(isle.Matrix(hfm.Q(phi)), copy=False) # full matrix manual = np.empty(auto.shape, auto.dtype) P = np.array(isle.Matrix(hfm.P())) # diagonal blocks manual[:nx, :nx] = P manual[:nx, nx:2*nx] = isle.Matrix(hfm.Tminus(0, phi)) manual[:nx, 2*nx:] = isle.Matrix(hfm.Tplus(0, phi)) manual[nx:2*nx, :nx] = isle.Matrix(hfm.Tplus(1, phi)) manual[nx:2*nx, nx:2*nx] = P manual[nx:2*nx, 2*nx:] = isle.Matrix(hfm.Tminus(1, phi)) manual[2*nx:, :nx] = isle.Matrix(hfm.Tminus(2, phi)) manual[2*nx:, nx:2*nx] = isle.Matrix(hfm.Tplus(2, phi)) manual[2*nx:, 2*nx:] = P self.assertTrue(core.isEqual(auto, manual), msg="Failed equality check for construction of HubbardFermiMatrixDia "\ + "for nt={}, mu={}, sigmaKappa={}".format(nt, mu, sigmaKappa)\ + "\nauto = {}".format(auto) \ + "\nmanual {}".format(manual))
def main(): # Initialize Isle. # This sets up the command line interface, defines an argument parser for a measurement # command, and parses and returns arguments. args = isle.initialize("meas", prog="measure") # Set up a measurement driver to run the measurements. measState = isle.drivers.meas.init(args.infile, args.outfile, args.overwrite) # The driver has retrieved all previously stored parameters from the input file, params = measState.params # as well as the lattice including the number of time slices nt. lat = measState.lattice # For simplicity do not allow the spin basis. assert params.basis == isle.action.HFABasis.PARTICLE_HOLE # Get "tilde" parameters (xTilde = x*beta/Nt) needed to construct measurements. muTilde = params.tilde("mu", lat) kappaTilde = params.tilde(measState.lattice.hopping(), lat.nt()) # This object is a lower level interface for the Hubbard fermion action # needed by some measurements. The discretization (hopping) needs # to be selected manually. if params.hopping == isle.action.HFAHopping.DIA: hfm = isle.HubbardFermiMatrixDia(kappaTilde, muTilde, params.sigmaKappa) else: hfm = isle.HubbardFermiMatrixExp(kappaTilde, muTilde, params.sigmaKappa) # Define measurements to run. # # The measurements are run on each configuration in the slice passed to 'configSlice'. # It defaults to 'all configurations' in e.g. the Logdet measurement. # The two correlator measurements are called for every 10th configuration only # but across the entire range of configurations. # # The string parameter in each constructor call is the path in the output file # where the measurement shall be stored. # The driver ensures that the location can be written to and that nothing gets # overwritten by accident. measurements = [ # log(det(M)) where M is the fermion matrix isle.meas.Logdet(hfm, "logdet"), # \sum_i phi_i isle.meas.TotalPhi("field"), # copy the action into the output file isle.meas.Action("action"), # single particle correlator for particles / spin up isle.meas.SingleParticleCorrelator(hfm, isle.Species.PARTICLE, "correlation_functions/single_particle", configSlice=s_[::10]), # single particle correlator for holes / spin down isle.meas.SingleParticleCorrelator(hfm, isle.Species.HOLE, "correlation_functions/single_hole", configSlice=s_[::10]), ] # Run the measurements on all configurations in the input file. # This automatically saves all results to the output file when done. measState(measurements)
def makeHFM(lattice, params): muTilde = params.tilde("mu", lattice) kappaTilde = params.tilde(lattice.hopping(), LATTICE) if params.hopping == isle.action.HFAHopping.DIA: return isle.HubbardFermiMatrixDia(kappaTilde, muTilde, params.sigmaKappa) else: return isle.HubbardFermiMatrixExp(kappaTilde, muTilde, params.sigmaKappa)
def nt_scaling(): "Benchmark scaling with Nt." with open(str(BENCH_PATH / "../resources/lattices/c60_ipr.yml"), "r") as yamlf: lat = yaml.safe_load(yamlf) nx = lat.nx() functions = { "dense": (isle.logdet, "fn(Q)", "Q = isle.Matrix(hfm.Q(phi))"), "logdetQ": (isle.logdetQ, "fn(hfm, phi)", ""), "logdetM": (isle.logdetM, "fn(hfm, phi, isle.Species.PARTICLE)+fn(hfm, phi, isle.Species.HOLE)", ""), } times = {key: [] for key in functions} for nt in NTS: print("nt = {}".format(nt)) # make random auxilliary field and HFM phi = isle.Vector( np.random.randn(nx * nt) + 1j * np.random.randn(nx * nt)) hfm = isle.HubbardFermiMatrixDia(lat.hopping() / nt, 0, -1) # do the benchmarks for name, (function, execStr, setupStr) in functions.items(): if nt > 12 and name == "dense": # this is just too slow continue times[name].append( timeit.timeit(execStr, setup=setupStr, globals={ "fn": function, "hfm": hfm, "phi": phi, "isle": isle }, number=NREP) / NREP) # save benchmark to file pickle.dump( { "xlabel": "Nt", "ylabel": "time / s", "xvalues": NTS, "results": times }, open("logdet.ben", "wb"))
def _testConstructionNt1(self, kappa, mu, sigmaKappa): "Check if nt=1 HFM is constructed properly." nt = 1 nx = kappa.rows() hfm = isle.HubbardFermiMatrixDia(kappa, mu, sigmaKappa) phi = _randomPhi(nx*nt) auto = np.array(isle.Matrix(hfm.Q(phi)), copy=False) manual = np.array(isle.Matrix(hfm.P()+hfm.Tplus(0, phi)+hfm.Tminus(0, phi)), copy=False) self.assertTrue(core.isEqual(auto, manual), msg="Failed equality check for construction of HubbardFermiMatrixDia "\ + "for nt={}, mu={}, sigmaKappa={}".format(nt, mu, sigmaKappa)\ + "\nhfm.Q() = {}".format(auto) \ + "\nhfm.P() + hfm.Tplus(0) + hfm.Tminus(0) = {}".format(manual))
def _test_logdetQ(self, kappa): "Test log(det(Q))." nx = kappa.rows() for nt, mu, sigmaKappa, rep in itertools.product((4, 8, 32), [0], (-1, 1), range(N_REP)): hfm = isle.HubbardFermiMatrixDia(kappa/nt, mu/nt, sigmaKappa) phi = _randomPhi(nx*nt) plain = isle.logdet(isle.Matrix(hfm.Q(phi))) viaLU = isle.logdetQ(hfm, phi) self.assertAlmostEqual(plain, viaLU, places=10, msg="Failed check log(det(Q)) in repetition {}".format(rep)\ + "for nt={}, mu={}, sigmaKappa={}:".format(nt, mu, sigmaKappa)\ + "\nplain = {}".format(plain) \ + "\nviaLU = {}".format(viaLU))
def measure(lat, params, file, log): LATTICE = lat.name nt = lat.nt() discretization = DISC(params.hopping) measState = isle.drivers.meas.init(file, file, True) params = measState.params muTilde = params.tilde("mu", lat) kappaTilde = params.tilde(measState.lattice.hopping(), lat.nt()) if params.hopping == isle.action.HFAHopping.DIA: hfm = isle.HubbardFermiMatrixDia(kappaTilde, muTilde, params.sigmaKappa) else: hfm = isle.HubbardFermiMatrixExp(kappaTilde, muTilde, params.sigmaKappa) species = (isle.Species.PARTICLE, isle.Species.HOLE) allToAll = {s: isle.meas.propagator.AllToAll(hfm, s) for s in species} _, transformation = np.linalg.eigh(isle.Matrix(hfm.kappaTilde())) measurements = [ isle.meas.Logdet(hfm, "logdet"), isle.meas.TotalPhi("field"), isle.meas.CollectWeights("weights"), isle.meas.onePointFunctions(allToAll[isle.Species.PARTICLE], allToAll[isle.Species.HOLE], "correlation_functions/one_point", configSlice=s_[::], transform=None), isle.meas.SingleParticleCorrelator( allToAll[isle.Species.PARTICLE], "correlation_functions/single_particle", configSlice=s_[::], projector=transformation), isle.meas.SingleParticleCorrelator(allToAll[isle.Species.HOLE], "correlation_functions/single_hole", configSlice=s_[::], projector=transformation), ] measState(measurements)
def nx_scaling(): "Benchmark scaling with Nx." lattices = [ isle.yamlio.loadLattice(fname) for fname in (BENCH_PATH / "../resources/lattices").iterdir() ] lattices = sorted(lattices, key=lambda lat: lat.nx()) NT = 16 times = {"logdetM": []} nxs = [] for lat in lattices: print(f"lat = {lat.name}") nx = lat.nx() if nx in nxs: continue nxs.append(nx) lat.nt(NT) # make random auxilliary field and HFM phi = isle.Vector( np.random.randn(nx * NT) + 1j * np.random.randn(nx * NT)) hfm = isle.HubbardFermiMatrixDia(lat.hopping() / NT, 0, -1) times["logdetM"].append( timeit.timeit("isle.logdetM(hfm, phi, isle.Species.PARTICLE)", globals={ "hfm": hfm, "phi": phi, "isle": isle }, number=NREP) / NREP) # save benchmark to file pickle.dump( { "xlabel": "Nx", "ylabel": "time / s", "xvalues": nxs, "results": times }, open("logdet.ben", "wb"))
def _test_solveM(self, kappa): "Test solveM()." nx = kappa.rows() for nt, mu, sigmaKappa, species, rep in itertools.product((4, 8, 32), [0], (-1, 1), (isle.Species.PARTICLE, isle.Species.HOLE), range(N_REP)): hfm = isle.HubbardFermiMatrixDia(kappa/nt, mu/nt, sigmaKappa) phi = _randomPhi(nx*nt) M = hfm.M(phi, species) rhss = [_randomPhi(nx*nt) for _ in range(2)] res = isle.solveM(hfm, phi, species, rhss) chks = [np.max(np.abs(M*r-rhs)) for r, rhs in zip(res, rhss)] for chk in chks: self.assertAlmostEqual(chk, 0, places=10, msg="Failed check solveM in repetition {}".format(rep)\ + "for nt={}, mu={}, sigmaKappa={}, species={}:".format(nt, mu, sigmaKappa, species)\ + "\nMx - rhs = {}".format(chk))
def main(): # Initialize Isle. # This sets up the command line interface, defines an argument parser for a measurement # command, and parses and returns arguments. args = isle.initialize("meas", prog="measure") # Set up a measurement driver to run the measurements. measState = isle.drivers.meas.init(args.infile, args.outfile, args.overwrite) # The driver has retrieved all previously stored parameters from the input file, params = measState.params # as well as the lattice including the number of time slices nt. lat = measState.lattice # For simplicity do not allow the spin basis. assert params.basis == isle.action.HFABasis.PARTICLE_HOLE # Get "tilde" parameters (xTilde = x*beta/Nt) needed to construct measurements. muTilde = params.tilde("mu", lat) kappaTilde = params.tilde(measState.lattice.hopping(), lat.nt()) # This object is a lower level interface for the Hubbard fermion action # needed by some measurements. The discretization (hopping) needs # to be selected manually. if params.hopping == isle.action.HFAHopping.DIA: hfm = isle.HubbardFermiMatrixDia(kappaTilde, muTilde, params.sigmaKappa) else: hfm = isle.HubbardFermiMatrixExp(kappaTilde, muTilde, params.sigmaKappa) # Define measurements to run. species = (isle.Species.PARTICLE, isle.Species.HOLE) allToAll = {s: isle.meas.propagator.AllToAll(hfm, s) for s in species} _, diagonalize = np.linalg.eigh(isle.Matrix(hfm.kappaTilde())) # # The measurements are run on each configuration in the slice passed to 'configSlice'. # It defaults to 'all configurations' in e.g. the Logdet measurement. # The two correlator measurements are called for every 10th configuration only # but across the entire range of configurations. # # The string parameter in each constructor call is the path in the output file # where the measurement shall be stored. # The driver ensures that the location can be written to and that nothing gets # overwritten by accident. measurements = [ # log(det(M)) where M is the fermion matrix isle.meas.Logdet(hfm, "logdet"), # \sum_i phi_i isle.meas.TotalPhi("field"), # collect all weights and store them in consolidated datasets instead of # spread out over many HDF5 groups isle.meas.CollectWeights("weights"), # polyakov loop isle.meas.Polyakov(params.basis, lat.nt(), "polyakov", configSlice=s_[::10]), # one-point functions isle.meas.OnePointFunctions(allToAll[isle.Species.PARTICLE], allToAll[isle.Species.HOLE], "correlation_functions/one_point", configSlice=s_[::10], transform=diagonalize), # single particle correlator for particles / spin up isle.meas.SingleParticleCorrelator( allToAll[isle.Species.PARTICLE], "correlation_functions/single_particle", configSlice=s_[::10], transform=diagonalize), # single particle correlator for holes / spin down isle.meas.SingleParticleCorrelator(allToAll[isle.Species.HOLE], "correlation_functions/single_hole", configSlice=s_[::10], transform=diagonalize), isle.meas.SpinSpinCorrelator(allToAll[isle.Species.PARTICLE], allToAll[isle.Species.HOLE], "correlation_functions/spin_spin", configSlice=s_[::10], transform=diagonalize, sigmaKappa=params.sigmaKappa), isle.meas.DeterminantCorrelators( allToAll[isle.Species.PARTICLE], allToAll[isle.Species.HOLE], "correlation_functions/det", configSlice=s_[::10], ) ] # Run the measurements on all configurations in the input file. # This automatically saves all results to the output file when done. measState(measurements)