def wrapper(instance): if fn.func_name in instance._done: return log.begin(self.description) fn(instance) log.end() instance._done.add(fn.func_name)
def estimate_errors(atom_tables, fns_fchk): from hipart.context import Context, Options from hipart.schemes import HirshfeldScheme from hipart.log import log import numpy, time configs = [] ref_config = None # The loops below one jobs for each grid configuration, i.e. combination # of radial and angular grid. for size, atom_table in sorted(atom_tables.iteritems()): for lebedev in 26, 50, 110, 230, 434, 770, 1454, 2702: all_charges = [] start = time.clock() for fn_fchk in fns_fchk: log.begin("Config size=%i lebedev=%i fchk=%s" % (size, lebedev, fn_fchk)) # Make a new working environment for every sample options = Options(lebedev=lebedev, do_work=False, do_output=False, do_random=True) context = Context(fn_fchk, options) scheme = HirshfeldScheme(context, atom_table) scheme.do_charges() all_charges.append(scheme.charges) del scheme log.end() cost = time.clock() - start log("cost=%.2e" % cost) config = Config(size, lebedev, numpy.concatenate(all_charges), cost) configs.append(config) if ref_config is None or (ref_config.size <= config.size and ref_config.lebedev <= config.lebedev): ref_config = config # Compute the errors ref_charges = configs[-1].charges for config in configs: config.error = (ref_charges - config.charges).std() # Log all log.begin("All configs") for config in configs: log(str(config)) log.end() return configs
def __init__(self, filename, options): log.set_verbose(options.verbose) log.begin("Loading Electronic structure") self.wavefn = load_wavefunction(filename) self.wavefn.log() log.end() self.options = options outdir = "%s.hipart" % self.wavefn.prefix if options.do_output: self.output = Output(outdir, self.wavefn.molecule.numbers) else: self.output = Output() if options.do_work: workdir = os.path.join(outdir, "work") else: workdir = None self.work = Work(workdir, do_clean=options.do_clean)
def init_naturals(self, work): log.begin("Natural orbitals") def do_natural(dmat, label): orbitals_name = "%s_orbitals" % label occupations_name = "%s_occupations" % label orbitals = work.load(orbitals_name, (self.num_orbitals, self.num_orbitals)) occupations = work.load(occupations_name) if orbitals is None or occupations is None: log("Computing the %s orbitals and occupation numbers ..." % label) occupations, orbitals = compute_naturals( dmat, self.num_orbitals) work.dump(orbitals_name, orbitals) work.dump(occupations_name, occupations) num = get_num_filled(occupations) return num, occupations, orbitals if self.natural_orbitals is None or self.natural_occupations is None: self.num_natural, self.natural_occupations, self.natural_orbitals = \ do_natural(self.density_matrix, "natural") if self.alpha_orbitals is None or self.alpha_occupations is None: if self.spin_density_matrix is None: self.num_alpha = self.num_natural self.alpha_orbitals = self.natural_orbitals self.alpha_occupations = 0.5 * self.natural_occupations else: self.num_alpha, self.alpha_occupations, self.alpha_orbitals = \ do_natural((self.density_matrix + self.spin_density_matrix)/2, "alpha") if self.beta_orbitals is None or self.beta_occupations is None: if self.spin_density_matrix is None: self.num_beta = self.num_natural self.beta_orbitals = self.natural_orbitals self.beta_occupations = 0.5 * self.natural_occupations else: self.num_beta, self.beta_occupations, self.beta_orbitals = \ do_natural((self.density_matrix - self.spin_density_matrix)/2, "beta") log.end()
def pareto_front(configs): from hipart.log import log # take a copy of the list, so that we can modify locally. configs = list(configs) # eliminate all configs that are not pareto-optimal configs.sort(key=(lambda c: c.error)) i = 0 while i < len(configs): ref_cost = configs[i].cost j = len(configs) - 1 while j > i: if configs[j].cost >= configs[i].cost: del configs[j] j -= 1 i += 1 # print the pareto front. log.begin("Pareto front") for config in configs: log(str(config)) config.optimal = True log.end()
def pareto_front(configs): from hipart.log import log # take a copy of the list, so that we can modify locally. configs = list(configs) # eliminate all configs that are not pareto-optimal configs.sort(key=(lambda c: c.error)) i = 0 while i < len(configs): ref_cost = configs[i].cost j = len(configs) -1 while j > i: if configs[j].cost >= configs[i].cost: del configs[j] j -= 1 i += 1 # print the pareto front. log.begin("Pareto front") for config in configs: log(str(config)) config.optimal = True log.end()
def init_naturals(self, work): log.begin("Natural orbitals") def do_natural(dmat, label): orbitals_name = "%s_orbitals" % label occupations_name = "%s_occupations" % label orbitals = work.load(orbitals_name, (self.num_orbitals, self.num_orbitals)) occupations = work.load(occupations_name) if orbitals is None or occupations is None: log("Computing the %s orbitals and occupation numbers ..." % label) occupations, orbitals = compute_naturals(dmat, self.num_orbitals) work.dump(orbitals_name, orbitals) work.dump(occupations_name, occupations) num = get_num_filled(occupations) return num, occupations, orbitals if self.natural_orbitals is None or self.natural_occupations is None: self.num_natural, self.natural_occupations, self.natural_orbitals = \ do_natural(self.density_matrix, "natural") if self.alpha_orbitals is None or self.alpha_occupations is None: if self.spin_density_matrix is None: self.num_alpha = self.num_natural self.alpha_orbitals = self.natural_orbitals self.alpha_occupations = 0.5*self.natural_occupations else: self.num_alpha, self.alpha_occupations, self.alpha_orbitals = \ do_natural((self.density_matrix + self.spin_density_matrix)/2, "alpha") if self.beta_orbitals is None or self.beta_occupations is None: if self.spin_density_matrix is None: self.num_beta = self.num_natural self.beta_orbitals = self.natural_orbitals self.beta_occupations = 0.5*self.natural_occupations else: self.num_beta, self.beta_occupations, self.beta_orbitals = \ do_natural((self.density_matrix - self.spin_density_matrix)/2, "beta") log.end()
def estimate_errors(atom_tables, fn_fchk): from hipart.context import Context, Options from hipart.schemes import HirshfeldScheme from hipart.log import log import numpy, time configs = [] # The loops below run 40 jobs for each grid configuration, i.e. combination # of radial and angular grid. Due to the random rotations of the angular # integration grids, the resulting charges will differ in each run. The # standard devation on each charge over the 40 runs is computed, and then # the error over all atoms is averaged. This error is used as 'the' error on # the charges. The cost is the cpu time consumed for computing this error. for size, atom_table in sorted(atom_tables.iteritems()): for lebedev in 26, 50, 110, 170, 266, 434: log.begin("Config size=%i lebedev=%i" % (size, lebedev)) start = time.clock() all_charges = [] for counter in xrange(40): log.begin("Sample counter=%i" % counter) # Make a new working environment for every sample options = Options(lebedev=lebedev, do_work=False, do_output=False) context = Context(fn_fchk, options) scheme = HirshfeldScheme(context, atom_table) scheme.do_charges() all_charges.append(scheme.charges) del scheme log.end() all_charges = numpy.array(all_charges) error = all_charges.std(axis=0).mean() cost = time.clock() - start log("error=%.2e cost=%.2e" % (error, cost)) configs.append(Config(size, lebedev, error, cost)) log.end() log.begin("All configs") for config in configs: log(str(config)) log.end() return configs