`_ project.
18 |
19 | Through its c++ interface, mcpele makes Monte Carlo simulations available to
20 | researchers with little programming experience, without having to compromise
21 | on efficiency. Furthermore mcpele abstracts each element of a Monte Carlo
22 | simulation eliminating the need for frequent code rewriting that experienced
23 | Monte Carlo developers typically go through, thus reducing the time required for
24 | the implementation of an idea and reducing the occurrence of bugs.
25 |
26 | .. figure:: diagram_fluid.png
27 |
28 | Figure 1: Diagramatic representation of the mcpele framework. On the right
29 | is a hard spheres fluid equilibrated by uniform sampling in a cubic box with
30 | periodic boundary conditions.
31 |
32 | mcpele has been authored by Stefano Martiniani, Ken J Schrenk and Jacob Stevenson at the University of Cambridge.
33 | The project is publicly available under the GNU general public licence.
34 |
35 | Tutorials
36 | -----------
37 | .. toctree::
38 | :maxdepth: 3
39 |
40 | getting_started
41 |
42 | Reference
43 | ---------
44 |
45 | .. toctree::
46 | :maxdepth: 2
47 |
48 | BaseMCRunner
49 |
50 | .. toctree::
51 | :maxdepth: 2
52 |
53 | TakeStep
54 |
55 | .. toctree::
56 | :maxdepth: 2
57 |
58 | ConfTest
59 |
60 | .. toctree::
61 | :maxdepth: 2
62 |
63 | AcceptTest
64 |
65 | .. toctree::
66 | :maxdepth: 2
67 |
68 | Action
69 |
70 | .. toctree::
71 | :maxdepth: 2
72 |
73 | Base_MPI_Parallel_Tempering
74 |
75 | .. toctree::
76 | :maxdepth: 2
77 |
78 | MPI_Parallel_Tempering
79 |
80 | Modules
81 | +++++++
82 | .. toctree::
83 | :maxdepth: 1
84 |
85 | monte_carlo
86 | parallel_tempering
87 |
88 | Indices and tables
89 | ------------------
90 |
91 | * :ref:`genindex`
92 | * :ref:`modindex`
93 | * :ref:`search`
94 |
95 |
--------------------------------------------------------------------------------
/doc/monte_carlo.rst:
--------------------------------------------------------------------------------
1 | Monte Carlo
2 | -----------
3 |
4 | .. currentmodule:: mcpele.monte_carlo
5 | .. automodule:: mcpele.monte_carlo
--------------------------------------------------------------------------------
/doc/parallel_tempering.rst:
--------------------------------------------------------------------------------
1 | Parallel Tempering
2 | ------------------
3 |
4 | .. currentmodule:: mcpele.parallel_tempering
5 |
6 | .. automodule:: mcpele.parallel_tempering
--------------------------------------------------------------------------------
/doc/sphinxext/viewcode-new.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | sphinx.ext.viewcode
4 | ~~~~~~~~~~~~~~~~~~~
5 |
6 | Add links to module code in Python object descriptions.
7 |
8 | :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
9 | :license: BSD, see LICENSE for details.
10 | """
11 |
12 | from docutils import nodes
13 |
14 | from sphinx import addnodes
15 | from sphinx.locale import _
16 | from sphinx.pycode import ModuleAnalyzer
17 | from sphinx.util.nodes import make_refnode
18 |
19 | import sys
20 | import traceback
21 |
22 |
23 | def doctree_read(app, doctree):
24 | env = app.builder.env
25 | if not hasattr(env, '_viewcode_modules'):
26 | env._viewcode_modules = {}
27 |
28 | def get_full_modname(modname, attribute):
29 | try:
30 | __import__(modname)
31 | except Exception, error:
32 | if not app.quiet:
33 | app.info(traceback.format_exc().rstrip())
34 | app.warn('viewcode can\'t import %s, failed with error "%s"' %
35 | (modname, error))
36 | return None
37 | module = sys.modules[modname]
38 | try:
39 | # Allow an attribute to have multiple parts and incidentially allow
40 | # repeated .s in the attribute.
41 | attr = attribute.split('.')
42 | value = module
43 | for attr in attribute.split('.'):
44 | if attr:
45 | value = getattr(value, attr)
46 | except AttributeError:
47 | app.warn('Didn\'t find %s in %s' % (attribute, module.__name__))
48 | return None
49 | else:
50 | return getattr(value, '__module__', None)
51 |
52 |
53 | def has_tag(modname, fullname, docname, refname):
54 | entry = env._viewcode_modules.get(modname, None)
55 | if entry is None:
56 | try:
57 | analyzer = ModuleAnalyzer.for_module(modname)
58 | except Exception:
59 | env._viewcode_modules[modname] = False
60 | return
61 | analyzer.find_tags()
62 | if not isinstance(analyzer.code, unicode):
63 | code = analyzer.code.decode(analyzer.encoding)
64 | else:
65 | code = analyzer.code
66 | entry = code, analyzer.tags, {}, refname
67 | env._viewcode_modules[modname] = entry
68 | elif entry is False:
69 | return
70 | _crap1 = entry
71 | tags = _crap1[1]
72 | used = _crap1[2]
73 | if fullname in tags:
74 | used[fullname] = docname
75 | return True
76 |
77 |
78 | for objnode in doctree.traverse(addnodes.desc):
79 | if objnode.get('domain') != 'py':
80 | continue
81 | names = set()
82 | for signode in objnode:
83 | if not isinstance(signode, addnodes.desc_signature):
84 | continue
85 | modname = signode.get('module')
86 | fullname = signode.get('fullname')
87 | refname = modname
88 | if env.config.viewcode_import:
89 | modname = get_full_modname(modname, fullname)
90 | if not modname:
91 | continue
92 | if not has_tag(modname, fullname, env.docname, refname):
93 | continue
94 | if fullname in names:
95 | # only one link per name, please
96 | continue
97 | names.add(fullname)
98 | pagename = '_modules/' + modname.replace('.', '/')
99 | onlynode = addnodes.only(expr='html')
100 | onlynode += addnodes.pending_xref(
101 | '', reftype='viewcode', refdomain='std', refexplicit=False,
102 | reftarget=pagename, refid=fullname,
103 | refdoc=env.docname)
104 | onlynode[0] += nodes.inline('', _('[source]'),
105 | classes=['viewcode-link'])
106 | signode += onlynode
107 |
108 |
109 | def missing_reference(app, env, node, contnode):
110 | # resolve our "viewcode" reference nodes -- they need special treatment
111 | if node['reftype'] == 'viewcode':
112 | return make_refnode(app.builder, node['refdoc'], node['reftarget'],
113 | node['refid'], contnode)
114 |
115 |
116 | def collect_pages(app):
117 | env = app.builder.env
118 | if not hasattr(env, '_viewcode_modules'):
119 | return
120 | highlighter = app.builder.highlighter
121 | urito = app.builder.get_relative_uri
122 |
123 | modnames = set(env._viewcode_modules)
124 |
125 | app.builder.info(' (%d module code pages)' %
126 | len(env._viewcode_modules), nonl=1)
127 |
128 | for modname, entry in env._viewcode_modules.iteritems():
129 | if not entry:
130 | continue
131 | if len(entry) < 4: continue
132 | #code, tags, used, refname = entry
133 | code = entry[0]
134 | tags = entry[1]
135 | used = entry[2]
136 | refname = entry[3]
137 | # construct a page name for the highlighted source
138 | pagename = '_modules/' + modname.replace('.', '/')
139 | # highlight the source using the builder's highlighter
140 | highlighted = highlighter.highlight_block(code, 'python', linenos=False)
141 | # split the code into lines
142 | lines = highlighted.splitlines()
143 | # split off wrap markup from the first line of the actual code
144 | before, after = lines[0].split('')
145 | lines[0:1] = [before + '', after]
146 | # nothing to do for the last line; it always starts with
anyway
147 | # now that we have code lines (starting at index 1), insert anchors for
148 | # the collected tags (HACK: this only works if the tag boundaries are
149 | # properly nested!)
150 | maxindex = len(lines) - 1
151 | for name, docname in used.iteritems():
152 | type, start, end = tags[name]
153 | backlink = urito(pagename, docname) + '#' + refname + '.' + name
154 | lines[start] = (
155 | '%s' % (name, backlink, _('[docs]'))
157 | + lines[start])
158 | lines[min(end - 1, maxindex)] += '
'
159 | # try to find parents (for submodules)
160 | parents = []
161 | parent = modname
162 | while '.' in parent:
163 | parent = parent.rsplit('.', 1)[0]
164 | if parent in modnames:
165 | parents.append({
166 | 'link': urito(pagename, '_modules/' +
167 | parent.replace('.', '/')),
168 | 'title': parent})
169 | parents.append({'link': urito(pagename, '_modules/index'),
170 | 'title': _('Module code')})
171 | parents.reverse()
172 | # putting it all together
173 | context = {
174 | 'parents': parents,
175 | 'title': modname,
176 | 'body': _('Source code for %s
') % modname + \
177 | '\n'.join(lines)
178 | }
179 | yield (pagename, context, 'page.html')
180 |
181 | if not modnames:
182 | return
183 |
184 | app.builder.info(' _modules/index')
185 | html = ['\n']
186 | # the stack logic is needed for using nested lists for submodules
187 | stack = ['']
188 | for modname in sorted(modnames):
189 | if modname.startswith(stack[-1]):
190 | stack.append(modname + '.')
191 | html.append('
')
192 | else:
193 | stack.pop()
194 | while not modname.startswith(stack[-1]):
195 | stack.pop()
196 | html.append('
')
197 | stack.append(modname + '.')
198 | html.append('%s\n' % (
199 | urito('_modules/index', '_modules/' + modname.replace('.', '/')),
200 | modname))
201 | html.append('' * (len(stack) - 1))
202 | context = {
203 | 'title': _('Overview: module code'),
204 | 'body': _('All modules for which code is available
') + \
205 | ''.join(html),
206 | }
207 |
208 | yield ('_modules/index', context, 'page.html')
209 |
210 |
211 | def setup(app):
212 | app.add_config_value('viewcode_import', True, False)
213 | app.connect('doctree-read', doctree_read)
214 | app.connect('html-collect-pages', collect_pages)
215 | app.connect('missing-reference', missing_reference)
216 | #app.add_config_value('viewcode_include_modules', [], 'env')
217 | #app.add_config_value('viewcode_exclude_modules', [], 'env')
218 |
--------------------------------------------------------------------------------
/examples/compute_pi/compute_pi.py:
--------------------------------------------------------------------------------
1 | """
2 | This example computes the numerical value of Pi by Monte Carlo.
3 | Points are sampled uniformly at random from an n-dimensional cube of
4 | side length 2R. By measuring the fraction of points contained within
5 | a ball of radius R contained in the cube, we determine Pi.
6 | """
7 | from __future__ import division
8 | import numpy as np
9 | import copy
10 | from scipy.special import gamma
11 | from mcpele.monte_carlo import _BaseMCRunner
12 | from mcpele.monte_carlo import NullPotential
13 | from mcpele.monte_carlo import UniformRectangularSampling
14 | from mcpele.monte_carlo import CheckSphericalContainerConfig
15 |
16 | def volume_nball(radius, n):
17 | return np.power(np.pi, n / 2) * np.power(radius, n) / gamma(n / 2 + 1)
18 |
19 | def get_pi(accepted_fraction, ndim):
20 | return np.power(2 ** ndim * accepted_fraction * gamma(ndim / 2 + 1), 2 / ndim)
21 |
22 | class MC(_BaseMCRunner):
23 | def set_control(self, temp):
24 | self.set_temperature(temp)
25 |
26 | class ComputePi(object):
27 | def __init__(self, ndim=2, nsamples=1e4):
28 | #
29 | self.ndim = ndim
30 | self.nsamples = nsamples
31 | #
32 | self.radius = 44
33 | self.potential = NullPotential()
34 | self.mc = MC(self.potential, np.ones(self.ndim), 1, self.nsamples)
35 | self.step = UniformRectangularSampling(42, self.radius)
36 | self.mc.set_takestep(self.step)
37 | self.mc.set_report_steps(0)
38 | self.conftest_check_spherical_container = CheckSphericalContainerConfig(self.radius)
39 | self.mc.add_conf_test(self.conftest_check_spherical_container)
40 | self.mc.set_print_progress()
41 | self.mc.run()
42 | self.p = self.mc.get_accepted_fraction()
43 | self.pi = get_pi(self.p, self.ndim)
44 |
45 | if __name__ == "__main__":
46 | nsamples = 1e5
47 | ndim_ = []
48 | res = []
49 | for ndim in xrange(2, 16):
50 | print("computing pi in {} dimensions".format(ndim))
51 | c = ComputePi(ndim=ndim, nsamples=nsamples)
52 | res.append(c.pi)
53 | ndim_.append(ndim)
54 | for (i, p) in zip(ndim_, res):
55 | print("dimension", i)
56 | print("pi", p)
57 | print("pi / np.pi", p / np.pi)
58 |
--------------------------------------------------------------------------------
/examples/sfHS_WCA_fluid/radial_distribution_function.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | import numpy as np
3 | from scipy.special import gamma
4 | import matplotlib.pyplot as plt
5 | from pele.potentials import HS_WCA
6 | from pele.optimize import LBFGS_CPP
7 | from mcpele.monte_carlo import _BaseMCRunner
8 | from mcpele.monte_carlo import RandomCoordsDisplacement
9 | from mcpele.monte_carlo import RecordPairDistHistogram
10 | from mcpele.monte_carlo import MetropolisTest
11 |
12 | class MC(_BaseMCRunner):
13 | def set_control(self, temp):
14 | self.set_temperature(temp)
15 |
16 | class ComputeGR():
17 | def __init__(self, boxdim=2, nr_particles=100, hard_phi=0.4,
18 | nr_steps=1e6, epsilon=1, alpha=0.1, verbose=False):
19 | # Settings.
20 | np.random.seed(42)
21 | # Input parameters.
22 | self.boxdim = boxdim
23 | self.nr_particles = nr_particles
24 | self.hard_phi = hard_phi
25 | self.nr_steps = nr_steps
26 | self.epsilon = epsilon
27 | self.alpha = alpha
28 | self.verbose = verbose
29 | # Derived quantities.
30 | self.hard_radii = np.ones(self.nr_particles)
31 | def volume_nball(radius, n):
32 | return np.power(np.pi, n / 2) * np.power(radius, n) / gamma(n / 2 + 1)
33 | self.box_length = np.power(np.sum(np.asarray([volume_nball(r, self.boxdim) for r in self.hard_radii])) / self.hard_phi, 1 / self.boxdim)
34 | self.box_vector = np.ones(self.boxdim) * self.box_length
35 | # HS-WCA potential.
36 | self.potential = HS_WCA(use_periodic=True, use_cell_lists=True,
37 | ndim=self.boxdim, eps=self.epsilon,
38 | sca=self.alpha, radii=self.hard_radii,
39 | boxvec=self.box_vector)
40 | # Initial configuration by minimization.
41 | self.nr_dof = self.boxdim * self.nr_particles
42 | self.x = np.random.uniform(-0.5 * self.box_length, 0.5 * self.box_length, self.nr_dof)
43 | optimizer = LBFGS_CPP(self.x, self.potential)
44 | optimizer.run()
45 | if not optimizer.get_result().success:
46 | print ("warning: minimization has not converged")
47 | self.x = optimizer.get_result().coords.copy()
48 | # Potential and MC rules.
49 | self.temperature = 1
50 | self.mc = MC(self.potential, self.x, self.temperature, self.nr_steps)
51 | self.step = RandomCoordsDisplacement(42, 1, single=True, nparticles=self.nr_particles, bdim=self.boxdim)
52 | if self.verbose:
53 | print ("initial MC stepsize")
54 | print self.step.get_stepsize()
55 | self.mc.set_takestep(self.step)
56 | self.eq_steps = self.nr_steps / 2
57 | self.mc.set_report_steps(self.eq_steps)
58 | self.gr_quench = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles, optimizer=optimizer)
59 | self.gr = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles)
60 | self.mc.add_action(self.gr_quench)
61 | self.mc.add_action(self.gr)
62 | self.test = MetropolisTest(44)
63 | self.mc.add_accept_test(self.test)
64 | def run(self):
65 | self.mc.set_print_progress()
66 | if not self.verbose:
67 | self.mc.disable_input_warnings()
68 | self.mc.run()
69 | if self.verbose:
70 | print ("adapted MC stepsize")
71 | print self.step.get_stepsize()
72 | def show_result(self):
73 | r = self.gr.get_hist_r()
74 | number_density = self.nr_particles / np.prod(self.box_vector)
75 | gr = self.gr.get_hist_gr(number_density, self.nr_particles)
76 | grq = self.gr_quench.get_hist_gr(number_density, self.nr_particles)
77 | plt.plot(r, gr, "o-", label="Equilibrium")
78 | plt.plot(r, grq, "x-", label="Quench")
79 | plt.xlabel(r"Distance $r$")
80 | plt.ylabel(r"Radial distr. function $g(r)$")
81 | plt.legend()
82 | plt.show()
83 |
84 | if __name__ == "__main__":
85 | box_dimension = 2
86 | nr_particles = 100
87 | hard_volume_fraction = 0.4
88 | nr_steps = 1e5
89 | alpha = 0.48
90 | verbose = False
91 | simulation = ComputeGR(boxdim=box_dimension,
92 | nr_particles=nr_particles,
93 | hard_phi=hard_volume_fraction,
94 | nr_steps=nr_steps,
95 | alpha=alpha,
96 | verbose=verbose)
97 | simulation.run()
98 | simulation.show_result()
99 |
--------------------------------------------------------------------------------
/mcpele/__init__.py:
--------------------------------------------------------------------------------
1 | import logging as _mcpele_logging
2 | import sys as _mcpele_sys
3 |
4 | logger = _mcpele_logging.getLogger("mcpele")
5 | global_handler = _mcpele_logging.StreamHandler(_mcpele_sys.stdout)
6 | logger.addHandler(global_handler)
7 | logger.setLevel(_mcpele_logging.DEBUG)
8 |
9 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/__init__.py:
--------------------------------------------------------------------------------
1 | from _accept_test_cpp import MetropolisTest
2 | from _conf_test_cpp import CheckSphericalContainer
3 | from _conf_test_cpp import CheckSphericalContainerConfig
4 | from _conf_test_cpp import ConfTestOR
5 | from _takestep_cpp import RandomCoordsDisplacement
6 | from _takestep_cpp import SampleGaussian
7 | from _takestep_cpp import GaussianCoordsDisplacement
8 | from _takestep_cpp import ParticlePairSwap
9 | from _takestep_cpp import TakeStepPattern
10 | from _takestep_cpp import TakeStepProbabilities
11 | from _takestep_cpp import UniformSphericalSampling
12 | from _takestep_cpp import UniformRectangularSampling
13 | from _monte_carlo_cpp import _BaseMCRunner
14 | from _action_cpp import RecordEnergyHistogram
15 | from _action_cpp import RecordEnergyTimeseries
16 | from _action_cpp import RecordPairDistHistogram
17 | from _action_cpp import RecordLowestEValueTimeseries
18 | from _action_cpp import RecordDisplacementPerParticleTimeseries
19 | from _action_cpp import RecordCoordsTimeseries
20 | from _nullpotential_cpp import NullPotential
21 | from mcrunner import Metropolis_MCrunner
22 |
23 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_accept_test_cpp.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cbool
2 | from _pele_mc cimport cppAcceptTest,_Cdef_AcceptTest, shared_ptr
3 |
4 | #===============================================================================
5 | # Metropolis acceptance criterion
6 | #===============================================================================
7 |
8 | cdef extern from "mcpele/metropolis_test.h" namespace "mcpele":
9 | cdef cppclass cppMetropolisTest "mcpele::MetropolisTest":
10 | cppMetropolisTest(size_t) except +
11 | size_t get_seed() except +
12 | void set_generator_seed(size_t) except +
13 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_accept_test_cpp.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # distutils: sources = accept_test.cpp
3 |
4 | import sys
5 |
6 | #===============================================================================
7 | # Metropolis acceptance criterion
8 | #===============================================================================
9 |
10 | cdef class _Cdef_Metropolis(_Cdef_AcceptTest):
11 | cdef cppMetropolisTest* newptr
12 | def __cinit__(self, rseed):
13 | self.thisptr = shared_ptr[cppAcceptTest]( new cppMetropolisTest(rseed))
14 | self.newptr = self.thisptr.get()
15 |
16 | def get_seed(self):
17 | """return random number generator seed
18 |
19 | Returns
20 | -------
21 | int
22 | random number generator seed
23 | """
24 | cdef res = self.newptr.get_seed()
25 | return res
26 |
27 | def set_generator_seed(self, input):
28 | """sets the random number generator seed
29 |
30 | Parameters
31 | ----------
32 | input : pos int
33 | random number generator seed
34 | """
35 | cdef inp = input
36 | self.newptr.set_generator_seed(inp)
37 |
38 | class MetropolisTest(_Cdef_Metropolis):
39 | """Metropolis acceptance criterion
40 |
41 | This class is the Python interface for the c++ mcpele::MetropolisTest
42 | acceptance test class implementation. The Metropolis acceptance criterion
43 | accepts each move with probability
44 |
45 | .. math:: P( x_{old} \Rightarrow x_{new}) = min \{ 1, \exp [- \\beta (E_{new} - E_{old})] \}
46 |
47 | where :math:`\\beta` is the reciprocal of the temperature.
48 | """
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_action_cpp.pxd:
--------------------------------------------------------------------------------
1 | cimport pele.potentials._pele as _pele
2 | cimport pele.optimize._pele_opt as _pele_opt
3 | #from pele.potentials._pele cimport array_wrap_np
4 | from _pele_mc cimport cppAction,_Cdef_Action, shared_ptr
5 | from libcpp cimport bool as cbool
6 | from libcpp.deque cimport deque
7 |
8 | # cython has no support for integer template argument. This is a hack to get around it
9 | # https://groups.google.com/forum/#!topic/cython-users/xAZxdCFw6Xs
10 | # Basically you fool cython into thinking INT2 is the type integer,
11 | # but in the generated c++ code you use 2 instead.
12 | # The cython code MyClass[INT2] will create c++ code MyClass<2>.
13 | cdef extern from *:
14 | ctypedef int INT2 "2" # a fake type
15 | ctypedef int INT3 "3" # a fake type
16 |
17 | cdef extern from "mcpele/record_energy_histogram.h" namespace "mcpele":
18 | cdef cppclass cppRecordEnergyHistogram "mcpele::RecordEnergyHistogram":
19 | cppRecordEnergyHistogram(double, double, double, size_t) except +
20 | _pele.Array[double] get_histogram() except +
21 | void print_terminal() except +
22 | double get_max() except +
23 | double get_min() except +
24 | double get_mean() except +
25 | double get_variance() except +
26 | int get_count() except +
27 |
28 | cdef extern from "mcpele/record_pair_dist_histogram.h" namespace "mcpele":
29 | cdef cppclass cppRecordPairDistHistogram "mcpele::RecordPairDistHistogram"[ndim]:
30 | cppRecordPairDistHistogram(_pele.Array[double], size_t, size_t, size_t) except +
31 | cppRecordPairDistHistogram(_pele.Array[double], size_t, size_t, size_t, shared_ptr[_pele_opt.cGradientOptimizer]) except +
32 | _pele.Array[double] get_hist_r() except +
33 | _pele.Array[double] get_hist_gr(double, size_t) except +
34 | size_t get_eqsteps() except +
35 |
36 | cdef extern from "mcpele/record_scalar_timeseries.h" namespace "mcpele":
37 | cdef cppclass cppRecordScalarTimeseries "mcpele::RecordScalarTimeseries":
38 | _pele.Array[double] get_time_series() except +
39 | void clear() except +
40 | cbool moving_average_is_stable(size_t, double) except +
41 |
42 | cdef extern from "mcpele/record_energy_timeseries.h" namespace "mcpele":
43 | cdef cppclass cppRecordEnergyTimeseries "mcpele::RecordEnergyTimeseries":
44 | cppRecordEnergyTimeseries(size_t, size_t) except +
45 |
46 | cdef extern from "mcpele/record_lowest_evalue_timeseries.h" namespace "mcpele":
47 | cdef cppclass cppRecordLowestEValueTimeseries "mcpele::RecordLowestEValueTimeseries":
48 | cppRecordLowestEValueTimeseries(size_t, size_t,
49 | shared_ptr[_pele.cBasePotential], size_t, _pele.Array[double]
50 | , size_t) except +
51 |
52 | cdef extern from "mcpele/record_displacement_per_particle_timeseries.h" namespace "mcpele":
53 | cdef cppclass cppRecordDisplacementPerParticleTimeseries "mcpele::RecordDisplacementPerParticleTimeseries":
54 | cppRecordDisplacementPerParticleTimeseries(size_t, size_t,
55 | _pele.Array[double], size_t) except +
56 |
57 | cdef extern from "mcpele/record_vector_timeseries.h" namespace "mcpele":
58 | cdef cppclass cppRecordVectorTimeseries "mcpele::RecordVectorTimeseries":
59 | deque[_pele.Array[double]] get_time_series() except +
60 | void clear() except +
61 | size_t get_record_every() except +
62 |
63 | cdef extern from "mcpele/record_coords_timeseries.h" namespace "mcpele":
64 | cdef cppclass cppRecordCoordsTimeseries "mcpele::RecordCoordsTimeseries":
65 | cppRecordCoordsTimeseries(size_t, size_t, size_t) except +
66 | _pele.Array[double] get_mean_coordinate_vector() except +
67 | _pele.Array[double] get_mean2_coordinate_vector() except +
68 | _pele.Array[double] get_variance_coordinate_vector() except +
69 | size_t get_count() except +
70 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_conf_test_cpp.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cbool
2 | from _pele_mc cimport cppConfTest, _Cdef_ConfTest, shared_ptr
3 |
4 | cdef extern from "mcpele/check_spherical_container.h" namespace "mcpele":
5 | cdef cppclass cppCheckSphericalContainer "mcpele::CheckSphericalContainer":
6 | cppCheckSphericalContainer(double, size_t) except +
7 |
8 | cdef extern from "mcpele/check_spherical_container_config.h" namespace "mcpele":
9 | cdef cppclass cppCheckSphericalContainerConfig "mcpele::CheckSphericalContainerConfig":
10 | cppCheckSphericalContainerConfig(double) except +
11 |
12 | cdef extern from "mcpele/conf_test_OR.h" namespace "mcpele":
13 | cdef cppclass cppConfTestOR "mcpele::ConfTestOR":
14 | cppConfTestOR() except +
15 | void add_test(shared_ptr[cppConfTest]) except +
16 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_conf_test_cpp.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # distutils: sources = conf_test.cpp
3 |
4 |
5 | import sys
6 |
7 | #===============================================================================
8 | # Check spherical container
9 | #===============================================================================
10 |
11 | cdef class _Cdef_CheckSphericalContainer(_Cdef_ConfTest):
12 | cdef cppCheckSphericalContainer* newptr
13 | def __cinit__(self, radius, ndim):
14 | self.thisptr = shared_ptr[cppConfTest]( new cppCheckSphericalContainer(radius, ndim))
15 | self.newptr = self.thisptr.get()
16 |
17 | class CheckSphericalContainer(_Cdef_CheckSphericalContainer):
18 | """Check that the system is within a spherical container
19 |
20 | This class is the Python interface for the c++ pele::CheckSphericalContainer
21 | configuration test class implementation
22 |
23 | Parameters
24 | ----------
25 | radius : double
26 | radius of the spherical container, centered at **0**
27 | ndim : int
28 | dimensionality of the space (box dimensionality)
29 | """
30 |
31 | #===============================================================================
32 | # Check spherical container config
33 | #===============================================================================
34 |
35 | cdef class _Cdef_CheckSphericalContainerConfig(_Cdef_ConfTest):
36 | cdef cppCheckSphericalContainerConfig* newptr
37 | def __cinit__(self, radius):
38 | self.thisptr = shared_ptr[cppConfTest]( new cppCheckSphericalContainerConfig(radius))
39 | self.newptr = self.thisptr.get()
40 |
41 | class CheckSphericalContainerConfig(_Cdef_CheckSphericalContainerConfig):
42 | """Check that the configuration point of the system is within a spherical container
43 |
44 | Parameters
45 | ----------
46 | radius : double
47 | radius of the spherical container, centered at **0**
48 | """
49 |
50 | #===============================================================================
51 | # Union of configurational tests
52 | #===============================================================================
53 |
54 | cdef class _Cdef_ConfTestOR(_Cdef_ConfTest):
55 | cdef cppConfTestOR* newptr
56 | def __cinit__(self):
57 | self.thisptr = shared_ptr[cppConfTest]( new cppConfTestOR())
58 | self.newptr = self.thisptr.get()
59 |
60 | def add_test(self, _Cdef_ConfTest test):
61 | """add a conf test to the union
62 |
63 | Parameters
64 | ----------
65 | step : :class:`ConfTest`
66 | object of class :class:`ConfTest` constructed beforehand
67 | """
68 | self.newptr.add_test(test.thisptr)
69 |
70 | class ConfTestOR(_Cdef_ConfTestOR):
71 | """Creates a union of multiple configurational tests
72 |
73 | Python interface for c++ ConfTestOR. This configurational
74 | test takes multiple conf tests and generates an union,
75 | therefore it is sufficient to satisfy one of these
76 | subtests to pass their union.
77 |
78 | """
79 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_monte_carlo_cpp.pxd:
--------------------------------------------------------------------------------
1 | cimport pele.potentials._pele as _pele
2 | from libcpp cimport bool as cbool
3 | from _pele_mc cimport *
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_nullpotential_cpp.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = C++
2 |
3 | cimport cython
4 | cimport pele.potentials._pele as _pele
5 | from _pele_mc cimport shared_ptr
6 | from pele.potentials._pele cimport BasePotential
7 |
8 | # use external c++ class
9 | cdef extern from "mcpele/nullpotential.h" namespace "mcpele":
10 | cdef cppclass cNullPotential "mcpele::NullPotential":
11 | cNullPotential() except +
12 |
13 | cdef class _Cdef_NullPotential(BasePotential):
14 | """
15 | this is the null potential
16 | """
17 | cdef cNullPotential* newptr
18 |
19 | def __cinit__(self):
20 | self.thisptr = shared_ptr[_pele.cBasePotential]( <_pele.cBasePotential*>new cNullPotential() )
21 | self.newptr = self.thisptr.get()
22 |
23 | class NullPotential(_Cdef_NullPotential):
24 | """
25 | """
26 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_pele_mc.pxd:
--------------------------------------------------------------------------------
1 | #cython: boundscheck=False
2 | #cython: wraparound=False
3 |
4 | cimport pele.potentials._pele as _pele
5 | from pele.potentials._pele cimport shared_ptr
6 | from libcpp cimport bool as cbool
7 |
8 | #===============================================================================
9 | # mcpele::TakeStep
10 | #===============================================================================
11 |
12 | cdef extern from "mcpele/mc.h" namespace "mcpele":
13 | cdef cppclass cppTakeStep "mcpele::TakeStep"
14 |
15 | cdef class _Cdef_TakeStep(object):
16 | """This class is the python interface for the c++ mcpele::TakeStep base class implementation
17 | """
18 | cdef shared_ptr[cppTakeStep] thisptr
19 |
20 | #===============================================================================
21 | # mcpele::AcceptTest
22 | #===============================================================================
23 |
24 | cdef extern from "mcpele/mc.h" namespace "mcpele":
25 | cdef cppclass cppAcceptTest "mcpele::AcceptTest"
26 |
27 | cdef class _Cdef_AcceptTest(object):
28 | """This class is the python interface for the c++ mcpele::AcceptTest base class implementation
29 | """
30 | cdef shared_ptr[cppAcceptTest] thisptr
31 |
32 | #===============================================================================
33 | # mcpele::ConfTest
34 | #===============================================================================
35 |
36 | cdef extern from "mcpele/mc.h" namespace "mcpele":
37 | cdef cppclass cppConfTest "mcpele::ConfTest"
38 |
39 | cdef class _Cdef_ConfTest(object):
40 | """This class is the python interface for the c++ mcpele::ConfTest base class implementation
41 | """
42 | cdef shared_ptr[cppConfTest] thisptr
43 |
44 | #===============================================================================
45 | # mcpele::Action
46 | #===============================================================================
47 |
48 | cdef extern from "mcpele/mc.h" namespace "mcpele":
49 | cdef cppclass cppAction "mcpele::Action"
50 |
51 | cdef class _Cdef_Action(object):
52 | """This class is the python interface for the c++ mcpele::Action base class implementation
53 | """
54 | cdef shared_ptr[cppAction] thisptr
55 |
56 | #===============================================================================
57 | # mcpele::MC
58 | #===============================================================================
59 |
60 | cdef extern from "mcpele/mc.h" namespace "mcpele":
61 | cdef cppclass cppMC "mcpele::MC":
62 | cppMC(shared_ptr[_pele.cBasePotential], _pele.Array[double]&, double) except +
63 | void one_iteration() except +
64 | void run(size_t) except +
65 | void set_temperature(double) except +
66 | double get_temperature() except +
67 | void set_stepsize(double) except +
68 | void add_action(shared_ptr[cppAction]) except +
69 | void add_accept_test(shared_ptr[cppAcceptTest]) except +
70 | void add_conf_test(shared_ptr[cppConfTest]) except +
71 | void add_late_conf_test(shared_ptr[cppConfTest]) except +
72 | void set_takestep(shared_ptr[cppTakeStep]) except +
73 | void set_coordinates(_pele.Array[double]&, double) except +
74 | void reset_energy() except +
75 | double get_energy() except +
76 | _pele.Array[double] get_coords() except +
77 | _pele.Array[double] get_trial_coords() except +
78 | double get_accepted_fraction() except +
79 | size_t get_iterations_count() except +
80 | double get_conf_rejection_fraction() except +
81 | double get_E_rejection_fraction() except +
82 | size_t get_neval() except +
83 | double get_norm_coords() except +
84 | void set_report_steps(size_t) except +
85 | void abort() except +
86 | void set_print_progress() except +
87 | void enable_input_warnings() except+
88 | void disable_input_warnings() except +
89 | cbool get_success() except+
90 |
91 | cdef class _Cdef_BaseMC(object):
92 | """This class is the python interface for the c++ mcpele::MC base class implementation
93 | """
94 | cdef shared_ptr[cppMC] thisptr
95 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_pele_mc.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
--------------------------------------------------------------------------------
/mcpele/monte_carlo/_takestep_cpp.pxd:
--------------------------------------------------------------------------------
1 | cimport pele.potentials._pele as _pele
2 | from _pele_mc cimport cppTakeStep,_Cdef_TakeStep, shared_ptr
3 |
4 | cdef extern from "mcpele/random_coords_displacement.h" namespace "mcpele":
5 | cdef cppclass cppRandomCoordsDisplacement "mcpele::RandomCoordsDisplacement":
6 | cppRandomCoordsDisplacement(size_t, double) except +
7 | size_t get_seed() except +
8 | void set_generator_seed(size_t) except +
9 | size_t get_count() except +
10 | double get_stepsize() except +
11 | cdef cppclass cppRandomCoordsDisplacementAll "mcpele::RandomCoordsDisplacementAll":
12 | cppRandomCoordsDisplacementAll(size_t, double) except +
13 | size_t get_seed() except +
14 | void set_generator_seed(size_t) except +
15 | double get_stepsize() except +
16 | cdef cppclass cppRandomCoordsDisplacementSingle "mcpele::RandomCoordsDisplacementSingle":
17 | cppRandomCoordsDisplacementSingle(size_t, size_t, size_t, double) except +
18 | size_t get_seed() except +
19 | void set_generator_seed(size_t) except +
20 | double get_stepsize() except +
21 |
22 | cdef extern from "mcpele/uniform_spherical_sampling.h" namespace "mcpele":
23 | cdef cppclass cppUniformSphericalSampling "mcpele::UniformSphericalSampling":
24 | cppUniformSphericalSampling(size_t, double) except +
25 | void set_generator_seed(size_t) except +
26 |
27 | cdef extern from "mcpele/uniform_rectangular_sampling.h" namespace "mcpele":
28 | cdef cppclass cppUniformRectangularSampling "mcpele::UniformRectangularSampling":
29 | cppUniformRectangularSampling(size_t, _pele.Array[double]) except +
30 | void set_generator_seed(size_t) except +
31 |
32 | cdef extern from "mcpele/gaussian_coords_displacement.h" namespace "mcpele":
33 | cdef cppclass cppGaussianTakeStep "mcpele::GaussianTakeStep":
34 | cppGaussianTakeStep(size_t, double, size_t) except +
35 | size_t get_seed() except +
36 | void set_generator_seed(size_t) except +
37 | size_t get_count() except +
38 | double get_stepsize() except +
39 | cdef cppclass cppGaussianCoordsDisplacement "mcpele::GaussianCoordsDisplacement":
40 | cppGaussianCoordsDisplacement(size_t, double, size_t) except +
41 | cdef cppclass cppSampleGaussian "mcpele::SampleGaussian":
42 | cppSampleGaussian(size_t, double, _pele.Array[double]) except +
43 |
44 | cdef extern from "mcpele/particle_pair_swap.h" namespace "mcpele":
45 | cdef cppclass cppParticlePairSwap "mcpele::ParticlePairSwap":
46 | cppParticlePairSwap(size_t, size_t) except +
47 | size_t get_seed() except +
48 | void set_generator_seed(size_t) except +
49 |
50 | cdef extern from "mcpele/adaptive_takestep.h" namespace "mcpele":
51 | cdef cppclass cppAdaptiveTakeStep "mcpele::AdaptiveTakeStep":
52 | cppAdaptiveTakeStep(shared_ptr[cppTakeStep], size_t, double,
53 | double, double) except +
54 |
55 | cdef extern from "mcpele/take_step_pattern.h" namespace "mcpele":
56 | cdef cppclass cppTakeStepPattern "mcpele::TakeStepPattern":
57 | cppTakeStepPattern() except +
58 | void add_step(shared_ptr[cppTakeStep], size_t)
59 |
60 | cdef extern from "mcpele/take_step_probabilities.h" namespace "mcpele":
61 | cdef cppclass cppTakeStepProbabilities "mcpele::TakeStepProbabilities":
62 | cppTakeStepProbabilities(size_t) except +
63 | void add_step(shared_ptr[cppTakeStep], size_t)
64 |
--------------------------------------------------------------------------------
/mcpele/monte_carlo/tests/__init__.py:
--------------------------------------------------------------------------------
1 | from test_metropolis_mcrunner import *
2 |
3 | if __name__ == "__main__":
4 | unittest.main()
--------------------------------------------------------------------------------
/mcpele/monte_carlo/tests/test_take_step_probability.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | import numpy as np
3 | from pele.potentials import Harmonic
4 | from mcpele.monte_carlo import _BaseMCRunner, GaussianCoordsDisplacement
5 | from mcpele.monte_carlo import TakeStepProbabilities, TakeStepPattern
6 | from mcpele.monte_carlo import RandomCoordsDisplacement, MetropolisTest
7 | from mcpele.monte_carlo import RecordEnergyHistogram
8 | import unittest
9 |
10 | class MC(_BaseMCRunner):
11 |
12 | def set_control(self, temp):
13 | self.set_temperature(temp)
14 |
15 | class TestTakeStepProbability(unittest.TestCase):
16 |
17 | def setUp(self):
18 | self.ndim = 42
19 | self.k = 100
20 | self.bdim = 2
21 | self.origin = np.zeros(self.ndim)
22 | self.potential = Harmonic(self.origin, self.k, bdim=self.bdim, com=False)
23 | self.potential_pattern = Harmonic(self.origin, self.k, bdim=self.bdim, com=False)
24 | self.temp = 1
25 | self.nr_steps = 1e4
26 | self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps)
27 | self.mc_pattern = MC(self.potential_pattern, self.origin, self.temp, self.nr_steps)
28 |
29 | def test_frequencies(self):
30 | self.tsA = GaussianCoordsDisplacement(42, 1, self.ndim)
31 | self.tsA_pattern = GaussianCoordsDisplacement(42, 1, self.ndim)
32 | self.tsB = GaussianCoordsDisplacement(44, 2, self.ndim)
33 | self.tsB_pattern = GaussianCoordsDisplacement(44, 2, self.ndim)
34 | self.step = TakeStepProbabilities(42)
35 | self.step.add_step(self.tsA, 1)
36 | self.step.add_step(self.tsB, 3)
37 | self.step_pattern = TakeStepPattern()
38 | self.step_pattern.add_step(self.tsA_pattern, 1)
39 | self.step_pattern.add_step(self.tsB_pattern, 3)
40 | freqA = 1 / (1 + 3)
41 | freqB = 1 - freqA
42 | self.mc.set_takestep(self.step)
43 | self.mc.run()
44 | self.mc_pattern.set_takestep(self.step_pattern)
45 | self.mc_pattern.run()
46 | self.assertAlmostEqual(freqA, self.tsA.get_count() / self.nr_steps, delta=1e-2)
47 | self.assertAlmostEqual(freqB, self.tsB.get_count() / self.nr_steps, delta=1e-2)
48 | self.assertAlmostEqual(freqA, self.tsA_pattern.get_count() / self.nr_steps, delta=1e-2)
49 | self.assertAlmostEqual(freqB, self.tsB_pattern.get_count() / self.nr_steps, delta=1e-2)
50 |
51 | class TestTakeStepProbabilityHarmoinc(unittest.TestCase):
52 |
53 | def setUp(self):
54 | self.box_dimension = 3
55 | self.nr_particles = 10
56 | self.k = 42
57 | self.nr_dof = self.box_dimension * self.nr_particles
58 | self.origin = np.zeros(self.nr_dof)
59 | self.potential = Harmonic(self.origin, self.k, bdim=self.box_dimension, com=True)
60 | self.temp = 1
61 | self.nr_steps = 6e4
62 | self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps)
63 | self.take_step_A = RandomCoordsDisplacement(42, 4, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
64 | self.take_step_B = RandomCoordsDisplacement(44, 0.1, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
65 | self.step = TakeStepProbabilities(46)
66 | self.weight_A = 22
67 | self.weight_B = 78
68 | self.step.add_step(self.take_step_A, self.weight_A)
69 | self.step.add_step(self.take_step_B, self.weight_B)
70 | self.mc.set_takestep(self.step)
71 | self.frequency_step_A = self.weight_A / (self.weight_A + self.weight_B)
72 | self.frequency_step_B = self.weight_B / (self.weight_A + self.weight_B)
73 | self.metropolis = MetropolisTest(50)
74 | self.mc.add_accept_test(self.metropolis)
75 | self.hist_min = 0
76 | self.hist_max = 1e4
77 | self.eq_steps = self.nr_steps / 2
78 | self.mc.set_report_steps(self.eq_steps)
79 | self.measure_energy = RecordEnergyHistogram(self.hist_min, self.hist_max, (self.hist_max - self.hist_min)/14, self.eq_steps)
80 | self.mc.add_action(self.measure_energy)
81 | self.true_energy = self.box_dimension * (self.nr_particles - 1) / 2
82 |
83 | def test_basic_harmonic(self):
84 | self.mc.run()
85 | self.assertAlmostEqual(self.frequency_step_A, self.take_step_A.get_count() / self.nr_steps, delta=1e-2)
86 | self.assertAlmostEqual(self.frequency_step_B, self.take_step_B.get_count() / self.nr_steps, delta=1e-2)
87 | self.assertAlmostEqual(self.take_step_A.get_stepsize(), self.take_step_B.get_stepsize(), delta=1e-2)
88 | mean_energy, var_energy = self.measure_energy.get_mean_variance()
89 | self.assertAlmostEqual(mean_energy, self.true_energy, delta=3e-1)
90 |
91 | if __name__ == "__main__":
92 | unittest.main()
93 |
--------------------------------------------------------------------------------
/mcpele/parallel_tempering/__init__.py:
--------------------------------------------------------------------------------
1 | from _base_mpi_ptmc import _MPI_Parallel_Tempering
2 | from mpi_ptmc import *
--------------------------------------------------------------------------------
/mcpele/parallel_tempering/tests/__init__.py:
--------------------------------------------------------------------------------
1 | from test_run_mpi_ptmc import *
2 |
3 | if __name__ == "__main__":
4 | unittest.main()
--------------------------------------------------------------------------------
/mcpele/parallel_tempering/tests/_test_run_mpi_ptmc.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | import numpy as np
3 | import argparse
4 | from pele.potentials import Harmonic
5 | from mcpele.monte_carlo import Metropolis_MCrunner
6 | from mcpele.parallel_tempering import MPI_PT_RLhandshake
7 |
8 | if __name__ == "__main__":
9 |
10 | parser = argparse.ArgumentParser(description="do nested sampling on a Lennard Jones cluster")
11 | parser.add_argument("base_directory", type=str, help="directory in which to save results")
12 | #parser.add_argument("-K", "--nreplicas", type=int, help="number of replicas", default=300)
13 | args = parser.parse_args()
14 |
15 | natoms = 4
16 | bdim = 3
17 | k=1
18 | origin = np.zeros(natoms * bdim)
19 | potential = Harmonic(origin, k, bdim=bdim, com=False)
20 | path = args.base_directory
21 |
22 | #Parallel Tempering
23 | temperature = 1.0
24 | stepsize = 1
25 | niter = 1e4
26 | mcrunner = Metropolis_MCrunner(potential, origin, temperature, stepsize, niter, hEmax=100, adjustf=0.9,
27 | adjustf_niter=3000, radius=100000, seeds=dict(metropolis=44,takestep=42))
28 | ptrunner = MPI_PT_RLhandshake(mcrunner, 0.2, 1.6, max_ptiter=501, pfreq=10, base_directory=path, verbose=False, suppress_histogram=False)
29 | ptrunner.run()
30 |
31 |
--------------------------------------------------------------------------------
/mcpele/parallel_tempering/tests/test_run_mpi_ptmc.py:
--------------------------------------------------------------------------------
1 | import os
2 | import tempfile
3 | import numpy as np
4 | import unittest
5 | import logging
6 |
7 | def read_Visits(fname):
8 | """HACKED"""
9 | data = np.genfromtxt(fname, delimiter='\t')
10 | return data[:,0], data[:,1]
11 |
12 | class TestPTRun(unittest.TestCase):
13 |
14 | def test_heat_capacity(self):
15 | self.bdim = 3
16 | self.natoms = 4
17 | self.nprocs = 4
18 | testdir = os.path.dirname(os.path.abspath(__file__))
19 | # create a temporary directory using the context manager
20 | tmpdir = tempfile.mkdtemp()
21 | self.cmd = 'mpiexec -n {0} python {1}/_test_run_mpi_ptmc.py {2}'.format(self.nprocs, testdir, tmpdir)
22 | #print('created temporary directory', tmpdir)
23 | os.system(self.cmd)
24 | temperatures = np.genfromtxt(os.path.join(tmpdir, 'temperatures'), delimiter='\t')
25 | for i in xrange(self.nprocs):
26 | d = tmpdir + '/{}'.format(i)
27 | pre = 'Visits.his.'
28 | files = os.listdir(d)
29 | ftlist = []
30 | for s in files:
31 | if pre in s:
32 | ftlist.append(s)
33 | timel = []
34 | for s in ftlist:
35 | t = float(s[len(pre):])
36 | timel.append(t)
37 | max_t = np.amax(timel)
38 |
39 | ener, hist = read_Visits(d + '/' + pre + '{}'.format(max_t))
40 |
41 | T = temperatures[i]
42 |
43 | average = np.average(ener, weights=hist)
44 |
45 | average2 = np.average(np.square(ener), weights=hist)
46 |
47 | cv = (average2 - average ** 2) / (T ** 2)
48 | cv_true = self.natoms * self.bdim / 2.0
49 |
50 | self.assertLess(cv - cv_true, 0.1, 'failed for replica of rank {} cv = {}'.format(i, cv))
51 |
52 | if __name__ == "__main__":
53 | logging.basicConfig(filename='ParallelTempering.log', level=logging.DEBUG)
54 | unittest.main()
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/mcpele/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from _utils import *
--------------------------------------------------------------------------------
/mcpele/utils/_utils.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | import numpy as np
3 | import pandas as pd
4 |
5 | def write_2d_array_to_hf5(array, key, path):
6 | """
7 | this function can be used to dump any 2d array to a hf5 database
8 | use this to dump a trajectory to a database from python
9 | """
10 | assert array.ndim == 2
11 | nind , ncol = array.shape
12 | ind = [i for i in xrange(nind)]
13 | col = [i for i in xrange(ncol)]
14 | df = pd.DataFrame(np.array(array), index=ind, columns=col)
15 | df.to_hdf(path, key)
16 |
17 | def read_hf5_to_2d_array(path, key):
18 | """
19 | read a 2d array from a hf5 database
20 | """
21 | df = pd.read_hdf(path, key)
22 | array = np.array(df.values)
23 | return array
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import glob
2 | import os
3 | import sys
4 | import subprocess
5 |
6 | from numpy.distutils.core import setup
7 | from numpy.distutils.core import Extension
8 | from numpy.distutils.misc_util import has_cxx_sources
9 | import numpy as np
10 | import pele
11 |
12 | ## Numpy header files
13 | numpy_lib = os.path.split(np.__file__)[0]
14 | numpy_include = os.path.join(numpy_lib, 'core/include')
15 |
16 | # find pele path
17 | # note: this is used both for the c++ source files and for the cython pxd files,
18 | # neither of which are "installed". This should really point to the source directory.
19 | # So this will only work if pele was built in-place
20 | try:
21 | pelepath = os.path.dirname(pele.__file__)[:-5]
22 | except:
23 | sys.stderr.write("WARNING: could't find path to pele\n")
24 | sys.exit()
25 |
26 | def generate_cython():
27 | cwd = os.path.abspath(os.path.dirname(__file__))
28 | print("Cythonizing sources")
29 | p = subprocess.call([sys.executable,
30 | os.path.join(cwd, 'cythonize.py'),
31 | 'mcpele', "-I %s/pele/potentials/" % pelepath],
32 | cwd=cwd)
33 | if p != 0:
34 | raise RuntimeError("Running cythonize failed!")
35 |
36 | generate_cython()
37 |
38 | #
39 | # compile fortran extension modules
40 | #
41 |
42 | class ModuleList:
43 | def __init__(self, **kwargs):
44 | self.module_list = []
45 | self.kwargs = kwargs
46 | def add_module(self, filename):
47 | modname = filename.replace("/", ".")
48 | modname, ext = os.path.splitext(modname)
49 | self.module_list.append(Extension(modname, [filename], **self.kwargs))
50 |
51 | setup(name='mcpele',
52 | version='0.1',
53 | description="mcpele is a library of monte carlo and parallel tempering routines buil on the pele foundation",
54 | url='https://github.com/pele-python/mcpele',
55 | packages=["mcpele",
56 | "mcpele.monte_carlo",
57 | "mcpele.parallel_tempering",
58 | # add the test directories
59 | "mcpele.monte_carlo.tests",
60 | "mcpele.parallel_tempering.tests",
61 | ],
62 | )
63 |
64 | #
65 | # build the c++ files
66 | #
67 |
68 | include_sources_mcpele = ["source/" + f for f in os.listdir("source/")
69 | if f.endswith(".cpp")]
70 | include_dirs = [numpy_include, "source"]
71 |
72 | include_sources_pele = [pelepath+"/source/" + f for f in os.listdir(pelepath+"/source")
73 | if f.endswith(".cpp")]
74 |
75 | depends_mcpele = [os.path.join("source/mcpele", f) for f in os.listdir("source/mcpele/")
76 | if f.endswith(".cpp") or f.endswith(".h") or f.endswith(".hpp")]
77 |
78 | depends_pele = [os.path.join(pelepath+"/source/pele", f) for f in os.listdir(pelepath+"/source/pele")
79 | if f.endswith(".cpp") or f.endswith(".h") or f.endswith(".hpp")]
80 |
81 | # note: on my computer (ubuntu 12.04 gcc version 4.6.3), when compiled with the
82 | # flag -march=native I run into problems. Everything seems to run ok, but when
83 | # I run it through valgrind, valgrind complains about an unrecognized
84 | # instruction. I don't have a clue what is causing this, but it's probably
85 | # better to be on the safe side and not use -march=native
86 | #extra_compile_args = ['-I/home/sm958/Work/pele/source','-std=c++0x',"-Wall", "-Wextra", "-O3", '-funroll-loops']
87 | # uncomment the next line to add extra optimization options
88 |
89 | include_pele_source = '-I'+ pelepath + '/source'
90 | extra_compile_args = [include_pele_source,'-std=c++0x',"-Wall", '-Wextra','-pedantic','-O3'] #,'-DDEBUG'
91 |
92 | # note: to compile with debug on and to override extra_compile_args use, e.g.
93 | # OPT="-g -O2 -march=native" python setup.py ...
94 |
95 | include_sources_all = include_sources_mcpele + include_sources_pele
96 |
97 | depends_all = depends_mcpele + depends_pele
98 |
99 | cxx_modules = [
100 | Extension("mcpele.monte_carlo._pele_mc",
101 | ["mcpele/monte_carlo/_pele_mc.cxx"] + include_sources_all,
102 | include_dirs=include_dirs,
103 | extra_compile_args=extra_compile_args,
104 | language="c++", depends=depends_all,
105 | ),
106 | Extension("mcpele.monte_carlo._monte_carlo_cpp",
107 | ["mcpele/monte_carlo/_monte_carlo_cpp.cxx"] + include_sources_all,
108 | include_dirs=include_dirs,
109 | extra_compile_args=extra_compile_args,
110 | language="c++", depends=depends_all,
111 | ),
112 | Extension("mcpele.monte_carlo._takestep_cpp",
113 | ["mcpele/monte_carlo/_takestep_cpp.cxx"] + include_sources_all,
114 | include_dirs=include_dirs,
115 | extra_compile_args=extra_compile_args,
116 | language="c++", depends=depends_all,
117 | ),
118 | Extension("mcpele.monte_carlo._accept_test_cpp",
119 | ["mcpele/monte_carlo/_accept_test_cpp.cxx"] + include_sources_all,
120 | include_dirs=include_dirs,
121 | extra_compile_args=extra_compile_args,
122 | language="c++", depends=depends_all,
123 | ),
124 | Extension("mcpele.monte_carlo._conf_test_cpp",
125 | ["mcpele/monte_carlo/_conf_test_cpp.cxx"] + include_sources_all,
126 | include_dirs=include_dirs,
127 | extra_compile_args=extra_compile_args,
128 | language="c++", depends=depends_all,
129 | ),
130 | Extension("mcpele.monte_carlo._action_cpp",
131 | ["mcpele/monte_carlo/_action_cpp.cxx"] + include_sources_all,
132 | include_dirs=include_dirs,
133 | extra_compile_args=extra_compile_args,
134 | language="c++", depends=depends_all,
135 | ),
136 | Extension("mcpele.monte_carlo._nullpotential_cpp",
137 | ["mcpele/monte_carlo/_nullpotential_cpp.cxx"] + include_sources_all,
138 | include_dirs=include_dirs,
139 | extra_compile_args=extra_compile_args,
140 | language="c++", depends=depends_all,
141 | ),
142 | ]
143 | setup(ext_modules=cxx_modules,
144 | )
145 |
--------------------------------------------------------------------------------
/source/CODING_STYLE.rst:
--------------------------------------------------------------------------------
1 | For this project, as well as pele, we use the K&R c++ coding standard (more or
2 | less) as a default
3 |
4 | http://en.wikipedia.org/wiki/Indent_style
5 |
6 | we use 4 spaces for indentation and *no tabs*
7 |
8 | In generall, this means it looks like this
9 |
10 | int main(int argc, char *argv[])
11 | {
12 | ...
13 | while (x == y) {
14 | something();
15 | somethingelse();
16 |
17 | if (some_error) {
18 | do_correct();
19 | } else {
20 | continue_as_usual();
21 | }
22 | }
23 |
24 | finalthing();
25 | ...
26 | }
27 |
28 | For a class it would be something like this
29 |
30 | class MyClass{
31 | protected:
32 | double v1;
33 | double v2;
34 | public:
35 | MyClass()
36 | : v1(0),
37 | v2(0)
38 | {
39 | do_something();
40 | }
41 | };
42 |
43 | Some big things I noticed that we need to fix are
44 |
45 | if and while statements have the brace on the same line
46 |
47 | if (blah) {
48 | do something
49 | }
50 |
51 | functions have braces on separate lines
52 |
53 | void func()
54 | {
55 | do something
56 | }
57 |
58 | always add white space after commas and around most operators (this is a pet peeve of mine ;)) )
59 |
60 | func(var1,var2,var3); // no!
61 | func(var1, var2, var3) // yes!
62 | a=b+4; //no!
63 | a = b + 4; //yes!
64 |
65 | with initializer lists, put the colon on a separate line from the name. And the braces also
66 |
67 | Minimizer::Minimizer()
68 | : val(0),
69 | ptr(1)
70 | {
71 | do something
72 | }
73 |
74 | Try to keep the lines not too much longer than 80 characters.
75 |
76 | Try to generally use braces with if statements.
77 | for loops should always have braces. it's just too dangerous otherwise.
78 |
79 | // very easy to introduce problems
80 | if (condition)
81 | do_something;
82 |
83 | add a space after for, if, while, etc
84 |
85 | for(i = 0; i < N; ++i){ // no
86 | for (i = 0; i < N; ++i) { // yes
87 |
88 | Put whitespace between operators
89 |
90 | // way too little whitespace
91 | std::vector energies()const{return property_listing(&Minimum::energy);}
92 | // better, but it's still quite long and hard to read
93 | std::vector energies() const { return property_listing(&Minimum::energy); }
94 | // best
95 | std::vector energies() const
96 | {
97 | return property_listing(&Minimum::energy);
98 | }
99 |
100 | If in doubt about white space and operators, check out this list:
101 | http://legacy.python.org/dev/peps/pep-0008/#other-recommendations
102 | In particular:
103 | "If operators with different priorities are used, consider adding whitespace
104 | around the operators with the lowest priority(ies). Use your own judgment;
105 | however, never use more than one space, and always have the same amount of
106 | whitespace on both sides of a binary operator."
107 |
108 | for naming, we follow the python convention and use CamelCase for class names
109 | and lower_case_under_score for function and variable names.
110 |
111 | Ideally functions should have a name that contains a verb. It should be the
112 | action that the function performs.
113 |
114 | value() //bad
115 | get_value() //good
116 |
117 | If you can't come up with a function name that describes what the function
118 | does, that might be an indication that your function does too many things.
119 | Try breaking up your function into many functions that each perform one action.
120 | Functions should be simple enough that you can know what it's going to do just
121 | by reading the name.
122 |
123 | When naming the c++ tests we follow the standard convention and use
124 |
125 | TEST(ClassNameOrTestGroup, ActionPerformed_ExpectedResult)
126 |
127 | the above is all CamelCase except for the single underscore separating the
128 | action and the expected result.
129 |
130 | For documentation,
131 | we try to follow the c++ Doxygen format. That way we can
132 | automatically generate nice looking documentation.
133 | http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html
134 | In particular, functions should be documented like so
135 |
136 | /**
137 | * return the energy
138 | */
139 | double get_energy();
140 |
--------------------------------------------------------------------------------
/source/adaptive_takestep.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/adaptive_takestep.h"
2 |
3 | namespace mcpele {
4 |
5 | AdaptiveTakeStep::AdaptiveTakeStep(std::shared_ptr ts,
6 | const size_t interval, const double factor,
7 | const double min_acceptance_ratio, const double max_acceptance_ratio)
8 | : m_ts(ts),
9 | m_interval(interval),
10 | m_total_steps(0),
11 | m_accepted_steps(0),
12 | m_factor(factor),
13 | m_min_acceptance_ratio(min_acceptance_ratio),
14 | m_max_acceptance_ratio(max_acceptance_ratio)
15 | {
16 | if (factor <= 0 || factor >= 1) {
17 | throw std::runtime_error("AdaptiveTakeStep::AdaptiveTakeStep: input factor has illegal value");
18 | }
19 | }
20 |
21 | void AdaptiveTakeStep::report(pele::Array&, const double,
22 | pele::Array&, const double, const bool success, MC* mc)
23 | {
24 | ++m_total_steps;
25 | if (success) {
26 | ++m_accepted_steps;
27 | }
28 | if (mc->get_iterations_count() % m_interval == 0) {
29 | const double acceptance_fraction = static_cast(m_accepted_steps) / static_cast(m_total_steps);
30 | m_accepted_steps = 0;
31 | m_total_steps = 0;
32 | if (acceptance_fraction < get_min_acceptance_ratio()) {
33 | m_ts->increase_acceptance(m_factor);
34 | }
35 | else if (acceptance_fraction > get_max_acceptance_ratio()) {
36 | m_ts->decrease_acceptance(m_factor);
37 | }
38 | }
39 | }
40 |
41 | } // namespace mcpele
42 |
--------------------------------------------------------------------------------
/source/check_spherical_container.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/check_spherical_container.h"
2 |
3 | using std::runtime_error;
4 | using pele::Array;
5 |
6 | namespace mcpele{
7 |
8 | CheckSphericalContainer::CheckSphericalContainer(const double radius, const size_t ndim)
9 | : m_radius2(radius * radius),
10 | m_ndim(ndim)
11 | {}
12 |
13 | bool CheckSphericalContainer::conf_test(Array &trial_coords, MC * mc)
14 | {
15 | const size_t N = trial_coords.size();
16 | for (size_t i = 0; i < N; i += m_ndim) {
17 | double r2 = 0;
18 | for (size_t j = i; j < i + m_ndim; ++j) {
19 | r2 += trial_coords[j] * trial_coords[j];
20 | }
21 | if (r2 > m_radius2) {
22 | //printf("fail spherical container %d %f %f %f %f\n", i, sqrt(r2), x[i], x[i+1], x[i+2]);
23 | //an atom is outside the spherical container
24 | return false;
25 | }
26 | }
27 | //printf("check spherical OK ");
28 | return true;
29 | }
30 |
31 | } // namespace mcpele
32 |
--------------------------------------------------------------------------------
/source/conf_test_OR.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/conf_test_OR.h"
2 |
3 | namespace mcpele {
4 |
5 | ConfTestOR::ConfTestOR(){}
6 |
7 | void ConfTestOR::add_test(std::shared_ptr test_input)
8 | {
9 | m_tests.push_back(test_input);
10 | m_tests.swap(m_tests);
11 | }
12 |
13 | bool ConfTestOR::conf_test(pele::Array &trial_coords, MC * mc)
14 | {
15 | if (m_tests.size() == 0) {
16 | throw std::runtime_error("ConfTestOR::conf_test: no conf test specified");
17 | }
18 | for(auto & test : m_tests){
19 | bool result = test->conf_test(trial_coords, mc);
20 | if (result){
21 | return true;
22 | }
23 | }
24 | return false;
25 | }
26 |
27 | } // namespace mcpele
28 |
--------------------------------------------------------------------------------
/source/energy_window_test.cpp:
--------------------------------------------------------------------------------
1 | #include "pele/array.h"
2 |
3 | #include "mcpele/energy_window_test.h"
4 |
5 | using pele::Array;
6 |
7 | namespace mcpele {
8 |
9 | EnergyWindowTest::EnergyWindowTest(const double min_energy, const double max_energy)
10 | : m_min_energy(min_energy),
11 | m_max_energy(max_energy)
12 | {}
13 |
14 | bool EnergyWindowTest::test(Array&, double trial_energy,
15 | Array&, double, double, MC*)
16 | {
17 | return ((trial_energy >= m_min_energy) and (trial_energy <= m_max_energy));
18 | }
19 |
20 | } // namespace mcpele
21 |
--------------------------------------------------------------------------------
/source/gaussian_coords_displacement.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/gaussian_coords_displacement.h"
2 |
3 | namespace mcpele {
4 |
5 | GaussianTakeStep::GaussianTakeStep(const size_t rseed, const double stepsize, const size_t ndim)
6 | : m_seed(rseed),
7 | m_mean(0.0),
8 | m_stdev(1.0),
9 | m_generator(rseed),
10 | m_distribution(m_mean, m_stdev),
11 | m_stepsize(stepsize),
12 | m_count(0),
13 | m_ndim(ndim),
14 | m_normal_vec(ndim)
15 | {
16 | #ifdef DEBUG
17 | std::cout<<"seed TakeStep:"<<_seed<< "\n";
18 | #endif
19 | }
20 |
21 | GaussianCoordsDisplacement::GaussianCoordsDisplacement(const size_t rseed, const double stepsize, const size_t ndim)
22 | : GaussianTakeStep(rseed, stepsize, ndim){}
23 |
24 | /*see https://en.wikipedia.org/wiki/Multivariate_normal_distribution*/
25 | void GaussianCoordsDisplacement::displace(pele::Array& coords, MC* mc)
26 | {
27 | this->m_sample_normal_vec();
28 | m_normal_vec /= norm(m_normal_vec); //sample from surface of unit hypersphere
29 | for(size_t i = 0; i < m_ndim; ++i){
30 | coords[i] += m_normal_vec[i] * m_stepsize; //here the stepsize plays the same role as the stdev. This is sampled from N(0,stepsize)
31 | }
32 | ++m_count;
33 | }
34 |
35 | SampleGaussian::SampleGaussian(const size_t rseed, const double stepsize, const pele::Array origin)
36 | : GaussianTakeStep(rseed, stepsize, origin.size()),
37 | m_origin(origin.copy())
38 | {}
39 |
40 | /*see https://en.wikipedia.org/wiki/Multivariate_normal_distribution
41 | * SampleGaussian::displace ignore the coords passed to it and it sample
42 | * with mean centered at the origin and stdev defined by the stepsize
43 | * */
44 | void SampleGaussian::displace(pele::Array& coords, MC* mc)
45 | {
46 | this->m_sample_normal_vec();
47 | for(size_t i = 0; i < m_ndim; ++i){
48 | coords[i] = m_origin[i] + m_normal_vec[i] * m_stepsize; //here the stepsize plays the same role as the stdev. This is sampled from N(0,stepsize)
49 | }
50 | ++m_count;
51 | }
52 |
53 | } // namespace mcpele
54 |
--------------------------------------------------------------------------------
/source/histogram.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/histogram.h"
2 |
3 | namespace mcpele{
4 |
5 | Histogram::Histogram(const double min, const double max, const double bin)
6 | : m_max(floor((max / bin) + 1) * bin),
7 | m_min(floor((min / bin)) * bin),
8 | m_bin(bin),
9 | m_eps(std::numeric_limits::epsilon()),
10 | m_N((m_max - m_min) / bin),
11 | m_hist(m_N, 0),
12 | m_niter(0)
13 | {
14 | #ifdef DEBUG
15 | std::cout << "histogram is of size " << m_N << "\n";
16 | #endif
17 | }
18 |
19 | void Histogram::add_entry(double E)
20 | {
21 | m_moments(E);
22 | int i;
23 | E = E + m_eps; //this is a dirty hack, not entirely sure of its generality and possible consequences, tests seem to be fine
24 | i = floor((E - m_min) / m_bin);
25 | if (i < m_N && i >= 0) {
26 | m_hist[i] += 1;
27 | ++m_niter;
28 | }
29 | else {
30 | this->resize(E, i);
31 | }
32 |
33 | /*THIS IS A TEST*/
34 | /*int renorm = 0;
35 | * for(vector::iterator it = _hist.begin();it != _hist.end();++it)
36 | {
37 | renorm += *it;
38 | }
39 |
40 | if (renorm != _niter)
41 | {
42 | std::cout<<" E "<= m_N) {
51 | newlen = (i + 1) - m_N;
52 | m_hist.insert(m_hist.end(), (newlen - 1), 0);
53 | m_hist.push_back(1);
54 | ++m_niter;
55 | m_max = floor((E / m_bin) + 1) * m_bin; //round to nearest increment
56 | m_N = round((m_max - m_min) / m_bin); //was round
57 | if (static_cast(m_hist.size()) != m_N) {
58 | std::cout<< " E " << E << "\n niter " << m_niter<< "\n size " << m_hist.size() << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n";
59 | assert(static_cast(m_hist.size()) == m_N);
60 | exit (EXIT_FAILURE);
61 | }
62 | std::cout<< "resized above at niter " << m_niter << "\n";
63 | }
64 | else if (i < 0) {
65 | newlen = -1 * i;
66 | m_hist.insert(m_hist.begin(), (newlen - 1), 0);
67 | m_hist.insert(m_hist.begin(),1);
68 | ++m_niter;
69 | m_min = floor((E / m_bin)) * m_bin; //round to nearest increment
70 | m_N = round((m_max - m_min) / m_bin); //was round
71 | if (static_cast(m_hist.size()) != m_N) {
72 | std::cout<<" E "<< E << "\n niter " << m_niter << "\n size " << m_hist.size() << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n";
73 | assert(static_cast(m_hist.size()) == m_N);
74 | exit (EXIT_FAILURE);
75 | }
76 | std::cout<< "resized below at niter " << m_niter << "\n";
77 | }
78 | else {
79 | std::cerr << "histogram encountered unexpected condition\n";
80 | std::cout << " E " << E << "\n niter " << m_niter << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n";
81 | }
82 | }
83 |
84 | /*
85 | * Note: This gives the error bar on a bin of width _bin, under the assumption that the sum of all bin areas is 1.
86 | * */
87 | std::vector Histogram::get_vecdata_error() const
88 | {
89 | std::vector result(m_hist.size(), 0);
90 | for (size_t i = 0; i < result.size(); ++i) {
91 | const double this_fraction = static_cast(m_hist.at(i)) / static_cast(get_count());
92 | result.at(i) = sqrt(this_fraction * (1 - this_fraction) / m_bin) / sqrt(get_count());
93 | }
94 | return result;
95 | }
96 |
97 | std::vector Histogram::get_vecdata_normalized() const
98 | {
99 | std::vector result(m_hist.size(), 0);
100 | for (size_t i = 0; i < m_hist.size(); ++i) {
101 | const double this_fraction = static_cast(m_hist.at(i)) / static_cast(m_niter);
102 | result.at(i) = this_fraction / m_bin;
103 | }
104 | return result;
105 | }
106 |
107 | std::vector Histogram::get_vectics() const
108 | {
109 | std::vector result(m_hist.size(), 0);
110 | for (size_t i = 0; i < m_hist.size(); ++i) {
111 | result.at(i) = get_position(i);
112 | }
113 | return result;
114 | }
115 |
116 | void Histogram::print_terminal() const
117 | {
118 | for(size_t i = 0; i < m_hist.size(); ++i) {
119 | std::cout << i << "-" << (i + 1) << ": ";
120 | std::cout << std::string(m_hist[i] * 10000 / m_niter, '*') << "\n";
121 | }
122 | }
123 |
124 | }//namespace mcpele
125 |
--------------------------------------------------------------------------------
/source/lowest_eigenvalue.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "mcpele/lowest_eigenvalue.h"
4 |
5 | namespace mcpele{
6 |
7 | FindLowestEigenvalue::FindLowestEigenvalue(std::shared_ptr landscape_potential, const size_t boxdimension,
8 | const pele::Array ranvec, const size_t lbfgsniter)
9 | : m_lowesteigpot(std::make_shared(landscape_potential, ranvec.copy(), boxdimension)),
10 | m_ranvec((ranvec.copy() /= norm(ranvec))),
11 | m_lbfgs(m_lowesteigpot, m_ranvec.copy())
12 | {
13 | if (std::isinf(double(1) / norm(ranvec))) {
14 | throw std::runtime_error("FindLowestEigenvalue: 1/norm(ranvec) is isinf");
15 | }
16 | m_lbfgs.set_max_iter(lbfgsniter);
17 | }
18 |
19 | double FindLowestEigenvalue::compute_lowest_eigenvalue(pele::Array coords)
20 | {
21 | m_lowesteigpot->reset_coords(coords);
22 | m_lbfgs.reset(m_ranvec);
23 | m_lbfgs.set_use_relative_f(1);
24 | m_lbfgs.run();
25 | const double lowesteig = m_lbfgs.get_f();
26 | return lowesteig;
27 | }
28 |
29 | }//namespace mcpele
30 |
--------------------------------------------------------------------------------
/source/mc.cpp:
--------------------------------------------------------------------------------
1 | #include "mcpele/mc.h"
2 | #include "mcpele/progress.h"
3 |
4 | using pele::Array;
5 |
6 | namespace mcpele {
7 |
8 | MC::MC(std::shared_ptr potential, Array& coords, const double temperature)
9 | : m_potential(potential),
10 | m_coords(coords.copy()),
11 | m_trial_coords(m_coords.copy()),
12 | m_take_step(NULL),
13 | m_nitercount(0),
14 | m_accept_count(0),
15 | m_E_reject_count(0),
16 | m_conf_reject_count(0),
17 | m_success(true),
18 | m_print_progress(false),
19 | m_niter(0),
20 | m_neval(0),
21 | m_temperature(temperature),
22 | m_report_steps(0),
23 | m_enable_input_warnings(true)
24 | {
25 | m_energy = compute_energy(m_coords);
26 | m_trial_energy = m_energy;
27 | /*std::cout<<"mcrunner Energy is "<<_energy<< "\n";
28 | std::cout<<"mcrunner potential ptr is "<<_potential<< "\n";*/
29 | }
30 |
31 | /**
32 | * perform the configuration tests. Stop as soon as one of them fails
33 | */
34 | bool MC::do_conf_tests(Array x)
35 | {
36 | bool result;
37 | for (auto & test : m_conf_tests) {
38 | result = test->conf_test(x, this);
39 | if (not result) {
40 | ++m_conf_reject_count;
41 | return false;
42 | }
43 | }
44 | return true;
45 | }
46 |
47 | /**
48 | * perform the acceptance tests. Stop as soon as one of them fails
49 | */
50 | bool MC::do_accept_tests(Array xtrial, double etrial, Array xold, double eold)
51 | {
52 | bool result;
53 | for (auto & test : m_accept_tests) {
54 | result = test->test(xtrial, etrial, xold, eold, m_temperature, this);
55 | if (not result) {
56 | ++m_E_reject_count;
57 | return false;
58 | }
59 | }
60 | return true;
61 | }
62 |
63 | /**
64 | * perform the configuration tests. Stop as soon as one of them fails
65 | */
66 | bool MC::do_late_conf_tests(Array x)
67 | {
68 | bool result;
69 | for (auto & test : m_late_conf_tests) {
70 | result = test->conf_test(x, this);
71 | if (not result) {
72 | ++m_conf_reject_count;
73 | return false;
74 | }
75 | }
76 | return true;
77 | }
78 |
79 | void MC::do_actions(Array x, double energy, bool success)
80 | {
81 | for (auto & action : m_actions) {
82 | action->action(x, energy, success, this);
83 | }
84 | }
85 |
86 | void MC::take_steps()
87 | {
88 | m_take_step->displace(m_trial_coords, this);
89 | }
90 |
91 |
92 | void MC::one_iteration()
93 | {
94 | m_success = true;
95 | ++m_niter;
96 | ++m_nitercount;
97 |
98 | m_trial_coords.assign(m_coords);
99 |
100 | // take a step with the trial coords
101 | //_takestep->takestep(_trial_coords, _stepsize, this);
102 | take_steps();
103 |
104 | // perform the initial configuration tests
105 | m_success = do_conf_tests(m_trial_coords);
106 |
107 | // if the trial configuration is OK, compute the energy, and run the acceptance tests
108 | if (m_success) {
109 | // compute the energy
110 | m_trial_energy = compute_energy(m_trial_coords);
111 |
112 | // perform the acceptance tests. Stop as soon as one of them fails
113 | m_success = do_accept_tests(m_trial_coords, m_trial_energy, m_coords, m_energy);
114 | }
115 |
116 | // Do some final checks to ensure the configuration is OK.
117 | // These come last because they might be computationally demanding.
118 | if (m_success) {
119 | m_success = do_late_conf_tests(m_trial_coords);
120 | }
121 |
122 | // adapt stepsize etc.
123 | if (get_iterations_count() <= m_report_steps) {
124 | m_take_step->report(m_coords, m_energy, m_trial_coords, m_trial_energy, m_success, this);
125 | }
126 |
127 | // if the step is accepted, copy the coordinates and energy
128 | if (m_success) {
129 | m_coords.assign(m_trial_coords);
130 | m_energy = m_trial_energy;
131 | ++m_accept_count;
132 | }
133 |
134 | // perform the actions on the new configuration
135 | do_actions(m_coords, m_energy, m_success);
136 | }
137 |
138 | void MC::check_input()
139 | {
140 | if (!take_step_specified()) {
141 | throw std::runtime_error("MC::check_input: takestep not set");
142 | }
143 | if (m_enable_input_warnings) {
144 | if (m_conf_tests.size()==0 && m_late_conf_tests.size()==0) {
145 | std::cout << "warning: no conf tests set" <<"\n";
146 | }
147 | if (m_actions.size()==0) {
148 | std::cout << "warning: no actions set" << "\n";
149 | }
150 | if (m_accept_tests.size()==0) {
151 | std::cout << "warning: no accept tests set" << "\n";
152 | }
153 | }
154 | }
155 |
156 | void MC::set_coordinates(pele::Array& coords, double energy)
157 | {
158 | m_coords = coords.copy();
159 | m_energy = energy;
160 | }
161 |
162 | //this function is necessary if for example some potential parameter has been varied
163 | void MC::reset_energy()
164 | {
165 | if(m_niter > 0) {
166 | throw std::runtime_error("MC::reset_energy after first iteration is forbidden");
167 | }
168 | m_energy = compute_energy(m_coords);
169 | }
170 |
171 | void MC::run(size_t max_iter)
172 | {
173 | check_input();
174 | progress stat(max_iter);
175 | while(m_niter < max_iter) {
176 | this->one_iteration();
177 | if (m_print_progress) {
178 | stat.next(m_niter);
179 | }
180 | }
181 | m_niter = 0;
182 | }
183 |
184 | } // namespace mcpele
185 |
--------------------------------------------------------------------------------
/source/mcpele/adaptive_takestep.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_ADAPTIVE_TAKESTEP_H__
2 | #define _MCPELE_ADAPTIVE_TAKESTEP_H__
3 |
4 | #include "mcpele/mc.h"
5 |
6 | namespace mcpele {
7 |
8 | class AdaptiveTakeStep : public TakeStep {
9 | protected:
10 | std::shared_ptr m_ts;
11 | size_t m_interval;
12 | size_t m_total_steps;
13 | size_t m_accepted_steps;
14 | const double m_factor;
15 | const double m_min_acceptance_ratio;
16 | const double m_max_acceptance_ratio;
17 | public:
18 | virtual ~AdaptiveTakeStep() {}
19 | AdaptiveTakeStep(std::shared_ptr ts, const size_t interval=100,
20 | const double factor=0.9, const double min_acceptance_ratio=0.2,
21 | const double max_acceptance_ratio=0.5);
22 | void displace(pele::Array &coords, MC * mc) { m_ts->displace(coords, mc); }
23 | void report(pele::Array& old_coords, const double old_energy,
24 | pele::Array& new_coords, const double new_energy,
25 | const bool success, MC* mc);
26 | double get_min_acceptance_ratio() const { return m_min_acceptance_ratio; }
27 | double get_max_acceptance_ratio() const { return m_max_acceptance_ratio; }
28 | };
29 |
30 | } // namespace mcpele
31 |
32 | #endif // #ifndef _MCPELE_ADAPTIVE_TAKESTEP_H__
33 |
--------------------------------------------------------------------------------
/source/mcpele/check_spherical_container.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_CHECK_SPHERICAL_CONTAINER_H__
2 | #define _MCPELE_CHECK_SPHERICAL_CONTAINER_H__
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "pele/array.h"
11 | #include "pele/optimizer.h"
12 | #include "pele/distance.h"
13 |
14 | #include "mc.h"
15 |
16 | namespace mcpele {
17 |
18 | class CheckSphericalContainer : public ConfTest {
19 | protected:
20 | double m_radius2;
21 | size_t m_ndim;
22 | public:
23 | CheckSphericalContainer(const double radius, const size_t ndim);
24 | virtual bool conf_test(pele::Array &trial_coords, MC * mc);
25 | virtual ~CheckSphericalContainer() {}
26 | };
27 |
28 | } // namespace mcpele
29 |
30 | #endif // #ifndef _MCPELE_CHECK_SPHERICAL_CONTAINER_H__
31 |
--------------------------------------------------------------------------------
/source/mcpele/check_spherical_container_config.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_CHECK_SPHERICAL_CONTAINER_CONFIG_H__
2 | #define _MCPELE_CHECK_SPHERICAL_CONTAINER_CONFIG_H__
3 |
4 | #include "mc.h"
5 |
6 | namespace mcpele {
7 |
8 | class CheckSphericalContainerConfig : public ConfTest {
9 | protected:
10 | double m_radius2;
11 | public:
12 | CheckSphericalContainerConfig(const double radius) : m_radius2(radius * radius) {}
13 | bool conf_test(pele::Array &trial_coords, MC * mc) { return pele::dot(trial_coords, trial_coords) <= m_radius2; }
14 | virtual ~CheckSphericalContainerConfig() {}
15 | };
16 |
17 | } // namespace mcpele
18 |
19 | #endif // #ifndef _MCPELE_CHECK_SPHERICAL_CONTAINER_CONFIG_H__
20 |
--------------------------------------------------------------------------------
/source/mcpele/conf_test_OR.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_CONF_TEST_OR_H__
2 | #define _MCPELE_CONF_TEST_OR_H__
3 |
4 | #include
5 | #include
6 |
7 | #include "mc.h"
8 |
9 | namespace mcpele {
10 |
11 | /**
12 | * Create union of two configurational tests,
13 | * it is sufficient for one of them to be true in order to pass the overall test.
14 | *
15 | */
16 | class ConfTestOR : public ConfTest {
17 | private:
18 | std::vector > m_tests;
19 | public:
20 | virtual ~ConfTestOR(){}
21 | ConfTestOR();
22 | void add_test(std::shared_ptr test_input);
23 | bool conf_test(pele::Array &trial_coords, MC * mc);
24 | };
25 |
26 | } // namespace mcpele
27 |
28 | #endif // #ifndef _MCPELE_CONF_TEST_OR_H__
29 |
--------------------------------------------------------------------------------
/source/mcpele/energy_window_test.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_ENERGY_WINDOW_TEST_H__
2 | #define _MCPELE_ENERGY_WINDOW_TEST_H__
3 |
4 | #include "pele/array.h"
5 | #include "mc.h"
6 |
7 | namespace mcpele {
8 |
9 | /**
10 | * Energy window test
11 | * This test checks that the energy of the system stays within a certain energy
12 | * window
13 | */
14 | class EnergyWindowTest : public AcceptTest {
15 | protected:
16 | double m_min_energy;
17 | double m_max_energy;
18 | public:
19 | EnergyWindowTest(const double min_energy, const double max_energy);
20 | virtual ~EnergyWindowTest() {}
21 | virtual bool test(pele::Array &trial_coords, double trial_energy,
22 | pele::Array & old_coords, double old_energy, double temperature,
23 | MC * mc);
24 | };
25 |
26 | } // namesapce mcpele
27 |
28 | #endif // #ifndef _MCPELE_ENERGY_WINDOW_TEST_H__
29 |
--------------------------------------------------------------------------------
/source/mcpele/gaussian_coords_displacement.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_GAUSSIAN_COORDS_DISPLACEMENT_H__
2 | #define _MCPELE_GAUSSIAN_COORDS_DISPLACEMENT_H__
3 |
4 | #include
5 |
6 | #include "mc.h"
7 |
8 | namespace mcpele {
9 |
10 | /*GaussianTakeStep is a base class from which all the gaussian based take step routines should derive
11 | * as it implements all its basic components
12 | * */
13 | class GaussianTakeStep : public TakeStep {
14 | protected:
15 | size_t m_seed;
16 | double m_mean;
17 | double m_stdev;
18 | std::mt19937_64 m_generator;
19 | std::normal_distribution m_distribution;
20 | double m_stepsize;
21 | size_t m_count, m_ndim;
22 | pele::Array m_normal_vec;
23 | /*draw ndim random variates from N(0,1) and fill up the m_normal_vec array with them*/
24 | inline void m_sample_normal_vec(){
25 | for(size_t i = 0; i < m_ndim; ++i){
26 | double randz = m_distribution(m_generator); //this is sample from N(0,1)
27 | m_normal_vec[i] = randz;
28 | }
29 | }
30 | public:
31 | GaussianTakeStep(const size_t rseed, const double stepsize, const size_t ndim);
32 | virtual ~GaussianTakeStep() {}
33 | virtual void displace(pele::Array& coords, MC* mc)=0;
34 | size_t get_seed() const { return m_seed; }
35 | void set_generator_seed(const size_t inp) { m_generator.seed(inp); }
36 | double get_stepsize() const { return m_stepsize; }
37 | void set_stepsize(const double input) { m_stepsize = input; }
38 | size_t get_count() const { return m_count; }
39 | /*Reference: http://mathworld.wolfram.com/NormalDistribution.html*/
40 | double expected_mean() const { return 0; }
41 | double expected_variance(const double ss) const { return ss * ss; }
42 | };
43 |
44 | class GaussianCoordsDisplacement : public GaussianTakeStep {
45 | public:
46 | GaussianCoordsDisplacement(const size_t rseed, const double stepsize, const size_t ndim);
47 | virtual ~GaussianCoordsDisplacement() {}
48 | virtual void displace(pele::Array& coords, MC* mc);
49 | };
50 |
51 | /**
52 | * Sample a simple Gaussian distribution N(coords, stepsize)
53 | * this step samples first from the standard normal N(0, 1) and outputs a
54 | * random variate sampled from N(0, stepsize)
55 | */
56 |
57 | class SampleGaussian : public GaussianTakeStep {
58 | protected:
59 | pele::Array m_origin;
60 | public:
61 | SampleGaussian(const size_t rseed, const double stepsize, const pele::Array origin);
62 | virtual ~SampleGaussian() {}
63 | virtual void displace(pele::Array& coords, MC* mc);
64 | };
65 |
66 | } // namespace mcpele
67 |
68 | #endif // #ifndef _MCPELE_GAUSSIAN_COORDS_DISPLACEMENT_H__
69 |
--------------------------------------------------------------------------------
/source/mcpele/histogram.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_HISTOGRAM_H
2 | #define _MCPELE_HISTOGRAM_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "pele/array.h"
11 |
12 | namespace mcpele {
13 |
14 | /*Dynamic histogram class that expand if energies outside of the initial bounds are found.
15 | * Being generous on the initial bounds saves a lot of time in reallocation of memory, at
16 | * the cost of memory preallocation.
17 | * Notes:
18 | * ->floor always casts towards minus infinity
19 | * ->a list is used instead of a vector because more efficient at pushing forward
20 | * ->begin and end return list iterators point to the beginning and the end of the
21 | * histogram respectively.
22 | * -> the most basic test that histogram must satisfy is that there must be as many
23 | * beads as the number of iterations (commented out at the end of the script)
24 | * */
25 |
26 | class Moments {
27 | public:
28 | typedef double data_t;
29 | typedef size_t index_t;
30 | private:
31 | data_t m_mean;
32 | data_t m_mean2;
33 | index_t m_count;
34 | public:
35 | Moments()
36 | : m_mean(0),
37 | m_mean2(0),
38 | m_count(0)
39 | {}
40 | void update(const data_t input)
41 | {
42 | m_mean = (m_mean * m_count + input) / (m_count + 1);
43 | m_mean2 = (m_mean2 * m_count + (input * input)) / (m_count + 1);
44 | if (m_count == std::numeric_limits::max()) {
45 | throw std::runtime_error("Moments: update: integer overflow");
46 | }
47 | ++m_count;
48 | }
49 | /**
50 | * replace a data point with another one
51 | */
52 | void replace(const data_t old_data, const data_t new_data)
53 | {
54 | m_mean += (new_data - old_data) / m_count;
55 | m_mean2 += (new_data * new_data - old_data * old_data) / m_count;
56 | }
57 | void operator() (const data_t input) { update(input); }
58 | index_t count() const { return m_count; }
59 | data_t mean() const { return m_mean; }
60 | data_t variance() const { return (m_mean2 - m_mean * m_mean); }
61 | data_t std() const { return sqrt(variance()); }
62 | };
63 |
64 | class Histogram{
65 | private:
66 | double m_max;
67 | double m_min;
68 | double m_bin;
69 | double m_eps;
70 | int m_N;
71 | std::vector m_hist;
72 | int m_niter;
73 | Moments m_moments;
74 | public:
75 | Histogram(const double min, const double max, const double bin);
76 | ~Histogram() {}
77 | void add_entry(double entry);
78 | double max() const { return m_max; }
79 | double min() const { return m_min; }
80 | double bin() const { return m_bin; }
81 | size_t size() const { return m_N; }
82 | int get_count() const { return m_niter; }
83 | double get_mean() const { return m_moments.mean(); }
84 | double get_variance() const { return m_moments.variance(); }
85 | std::vector::iterator begin(){ return m_hist.begin(); }
86 | std::vector::iterator end(){ return m_hist.end(); }
87 | double get_position(const size_t bin_index) const { return m_min + (0.5 + bin_index) * m_bin; }
88 | std::vector get_vectics() const;
89 | std::vector get_vecdata() const { return m_hist; }
90 | double get_entry(const size_t bin_index) const { return m_hist.at(bin_index); }
91 | std::vector get_vecdata_error() const;
92 | std::vector get_vecdata_normalized() const;
93 | void print_terminal() const;
94 | void resize(const double E, const int i);
95 | };
96 |
97 | } // namespace mcpele
98 |
99 | #endif // #ifndef _MCPELE_HISTOGRAM_H
100 |
101 |
--------------------------------------------------------------------------------
/source/mcpele/lowest_eigenvalue.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_LOWEST_EIGENVALUE_H
2 | #define _MCPELE_LOWEST_EIGENVALUE_H
3 |
4 | #include "pele/base_potential.h"
5 | #include "pele/lbfgs.h"
6 | #include "pele/lowest_eig_potential.h"
7 |
8 | namespace mcpele{
9 |
10 |
11 | class FindLowestEigenvalue{
12 | private:
13 | std::shared_ptr m_lowesteigpot;
14 | pele::Array m_ranvec;
15 | pele::LBFGS m_lbfgs;
16 | public:
17 | FindLowestEigenvalue(std::shared_ptr landscape_potential, const size_t boxdimension,
18 | const pele::Array ranvec, const size_t lbfgsniter);
19 | double compute_lowest_eigenvalue(pele::Array coords);
20 | };
21 |
22 |
23 | }//namespace mcpele
24 |
25 | #endif//#ifndef _MCPELE_LOWEST_EIGENVALUE_H
26 |
--------------------------------------------------------------------------------
/source/mcpele/mc.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_MC_H
2 | #define _MCPELE_MC_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "pele/array.h"
10 | #include "pele/base_potential.h"
11 |
12 | namespace mcpele{
13 |
14 | class MC;
15 |
16 | /*
17 | * Action
18 | */
19 |
20 | class Action {
21 | public:
22 | //Action(){std::cout<< "Action()" << "\n";}
23 | //virtual ~Action(){std::cout << "~Action()" << "\n";}
24 | virtual ~Action(){}
25 | virtual void action(pele::Array &coords, double energy, bool accepted,
26 | MC* mc) =0;
27 | };
28 |
29 | /*
30 | * Accept Test
31 | */
32 |
33 | class AcceptTest{
34 | public:
35 | //AcceptTest(){std::cout << "AcceptTest()" << "\n";}
36 | //virtual ~AcceptTest(){std::cout << "~AcceptTest()" << "\n";}
37 | virtual ~AcceptTest(){}
38 | virtual bool test(pele::Array &trial_coords, double trial_energy,
39 | pele::Array & old_coords, double old_energy, double temperature,
40 | MC * mc) =0;
41 | };
42 |
43 | /*
44 | * Accept Test
45 | */
46 |
47 | class ConfTest{
48 | public:
49 | //ConfTest(){std::cout << "ConfTest()" << "\n";}
50 | //virtual ~ConfTest(){std::cout << "~ConfTest()" << "\n";}
51 | virtual ~ConfTest(){}
52 | virtual bool conf_test(pele::Array &trial_coords, MC * mc) =0;
53 | };
54 |
55 | /*
56 | * Take Step
57 | */
58 |
59 | class TakeStep {
60 | public:
61 | virtual ~TakeStep() {}
62 | virtual void displace(pele::Array& coords, MC* mc) = 0;
63 | virtual void report(pele::Array&, const double,
64 | pele::Array&, const double, const bool, MC*) {}
65 | virtual void increase_acceptance(const double) {}
66 | virtual void decrease_acceptance(const double) {}
67 | };
68 |
69 | /**
70 | * Monte Carlo
71 | * _coords and _trialcoords are arrays that store coordinates and trial coordinates respectively
72 | * _potential is on object of Pele::BasePotential type that defines the interaction potential
73 | * _E_reject_count is the count of rejections due to an energy test (e.g. Metropolis)
74 | * _conf_reject_count is the count of rejections due to a configuration test (e.g. spherical container)
75 | * _niter is the count of steps whithin a MCMC run, it is reset to zero at the end of the run
76 | * _nitercount is the cumulative number of MCMC steps taken by the class
77 | * _neval is the number of energy evaluations
78 | * _temperature is the temperature at which the simulation is performed
79 | * _energy is the current energy of the system
80 | * _success records whether the step has been accepted or rejected
81 | */
82 |
83 | class MC {
84 | public:
85 | typedef std::vector > actions_t;
86 | typedef std::vector > accept_t;
87 | typedef std::vector > conf_t;
88 | protected:
89 | std::shared_ptr m_potential;
90 | pele::Array m_coords;
91 | pele::Array m_trial_coords;
92 | actions_t m_actions;
93 | accept_t m_accept_tests;
94 | conf_t m_conf_tests;
95 | conf_t m_late_conf_tests;
96 | std::shared_ptr m_take_step;
97 | size_t m_nitercount;
98 | size_t m_accept_count;
99 | size_t m_E_reject_count;
100 | size_t m_conf_reject_count;
101 | bool m_success;
102 | /*nitercount is the cumulative count, it does not get reset at the end of run*/
103 | bool m_print_progress;
104 | public:
105 | /*need to keep these public to make them accessible to tests and actions, be careful though!*/
106 | size_t m_niter;
107 | size_t m_neval;
108 | double m_temperature;
109 | double m_energy;
110 | double m_trial_energy;
111 | private:
112 | size_t m_report_steps;
113 | bool m_enable_input_warnings;
114 | public:
115 | MC(std::shared_ptr potential, pele::Array& coords, const double temperature);
116 | virtual ~MC() {}
117 | void one_iteration();
118 | void run(const size_t max_iter);
119 | void set_temperature(const double T) { m_temperature = T; }
120 | double get_temperature() const { return m_temperature; }
121 | void set_report_steps(const size_t report_steps) { m_report_steps = report_steps; }
122 | size_t get_report_steps() const { return m_report_steps; }
123 | void add_action(std::shared_ptr action) { m_actions.push_back(action); }
124 | void add_accept_test(std::shared_ptr accept_test) { m_accept_tests.push_back(accept_test); }
125 | void add_conf_test(std::shared_ptr conf_test) { m_conf_tests.push_back(conf_test); }
126 | void add_late_conf_test(std::shared_ptr conf_test) { m_late_conf_tests.push_back(conf_test); }
127 | void set_takestep(std::shared_ptr takestep) { m_take_step = takestep; }
128 | std::shared_ptr get_takestep() const { return m_take_step; }
129 | void set_coordinates(pele::Array& coords, double energy);
130 | double get_energy() const { return m_energy; }
131 | void reset_energy();
132 | double get_trial_energy() const { return m_trial_energy; }
133 | pele::Array get_coords() const { return m_coords.copy(); }
134 | pele::Array get_trial_coords() const { return m_trial_coords.copy(); }
135 | double get_norm_coords() const { return norm(m_coords); }
136 | size_t get_naccept() const { return m_accept_count; }
137 | size_t get_nreject() const { return m_nitercount - m_accept_count; }
138 | double get_accepted_fraction() const { return static_cast(m_accept_count) /
139 | static_cast(m_nitercount); }
140 | double get_conf_rejection_fraction() const { return static_cast(m_conf_reject_count) /
141 | static_cast(m_nitercount); }
142 | double get_E_rejection_fraction() const { return static_cast(m_E_reject_count) /
143 | static_cast(m_nitercount); }
144 | size_t get_iterations_count() const { return m_nitercount; }
145 | size_t get_neval() const { return m_neval; }
146 | std::shared_ptr get_potential_ptr() { return m_potential; }
147 | bool take_step_specified() const { return m_take_step != NULL; }
148 | bool report_steps_specified() const { return get_report_steps() > 0; }
149 | void check_input();
150 | void set_print_progress(const bool input) { m_print_progress = input; }
151 | void set_print_progress() { set_print_progress(true); }
152 | bool get_success() const { return m_success; }
153 | /**
154 | * this will trigger premature exit from the MC run loop
155 | */
156 | void abort() { m_niter = std::numeric_limits::max(); }
157 | void enable_input_warnings() { m_enable_input_warnings = true; }
158 | void disable_input_warnings() { m_enable_input_warnings = false; }
159 | protected:
160 | inline double compute_energy(pele::Array x)
161 | {
162 | ++m_neval;
163 | return m_potential->get_energy(x);
164 | }
165 | bool do_conf_tests(pele::Array x);
166 | bool do_accept_tests(pele::Array xtrial, double etrial, pele::Array xold, double eold);
167 | bool do_late_conf_tests(pele::Array x);
168 | void do_actions(pele::Array x, double energy, bool success);
169 | void take_steps();
170 | };
171 |
172 | }//namespace mcpele
173 |
174 | #endif//#ifndef _MCPELE_MC_H
175 |
--------------------------------------------------------------------------------
/source/mcpele/metropolis_test.h:
--------------------------------------------------------------------------------
1 | #ifndef _MCPELE_METROPOLIS_TEST_H__
2 | #define _MCPELE_METROPOLIS_TEST_H__
3 |
4 | #include
5 |
6 | #include "pele/array.h"
7 | #include "mc.h"
8 |
9 | namespace mcpele {
10 |
11 | /**
12 | * Metropolis acceptance criterion
13 | */
14 | class MetropolisTest : public AcceptTest {
15 | protected:
16 | size_t m_seed;
17 | std::mt19937_64 m_generator;
18 | std::uniform_real_distribution m_distribution;
19 | public:
20 | MetropolisTest(const size_t rseed);
21 | virtual ~MetropolisTest() {}
22 | virtual bool test(pele::Array