def SetSampledInitialPoints(self, dist=None): """Generate Random Initial Points from Distribution (dist) input:: - dist: a mystic.math.Distribution instance """ from mystic.math import Distribution if dist is None: dist = Distribution() elif type(Distribution) not in dist.__class__.mro(): dist = Distribution(dist) #XXX: or throw error? for i in range(self.nPop): self.population[i] = dist(self.nDim) return
def SetDistribution(self, dist=None): """Set the distribution used for determining solver starting points Inputs: - dist: a mystic.math.Distribution instance """ from mystic.math import Distribution if dist and Distribution not in dist.__class__.mro(): dist = Distribution(dist) #XXX: or throw error? self._dist = dist return
def _noisy(x, dist=None, op=None): """make x noisy, by sampling from dist; returns op(x, dist.rvs(x.shape)) x: parameters (list or array) dist: mystic.math.Distribution object op: numpy operator (e.g. np.add or np.prod) For example: >>> from numpy.random import normal >>> import mystic >>> x = [1,2,3] >>> rng = mystic.random_state('numpy.random', new=True, seed=123) >>> dist = mystic.math.Distribution(normal, 0, .1, rng=rng) >>> noisy(x, dist) [0.8914369396699439, 2.0997345446583586, 3.0282978498051993] """ if op is None: op = np.add _type = type(x) if type(x) is not np.ndarray else None x = np.asarray(x) if dist is None: from mystic.math import Distribution dist = Distribution() dx = dist.rvs(x.shape) return op(x, dx) if _type is None else _type(op(x, dx))
from mystic.termination import VTR from mystic.termination import ChangeOverGeneration as COG solver = DifferentialEvolutionSolver(nd, npop) solver.SetRandomInitialPoints(lb, ub) solver.SetStrictRanges(lb, ub) term = VTR(tol) #term = COG() solver.Solve(peaks, term, disp=True) sol = solver.Solution() print('solution = %s' % sol) print('expected = [0.23, -1.63]') try: from scipy.stats import uniform except ImportError: exit() from mystic.math import Distribution print('-' * 60) print('using a uniform distribution...') solver = DifferentialEvolutionSolver(nd, npop) solver.SetSampledInitialPoints(Distribution(uniform, lb[0], ub[0])) solver.SetStrictRanges(lb, ub) term = VTR(tol) #term = COG() solver.Solve(peaks, term, disp=True) sol = solver.Solution() print('solution = %s' % sol) print('expected = [0.23, -1.63]')
def sample(model, bounds, pts=None, **kwds): """sample model within bounds, writing to an archive and returning data Inputs: model: a cached model function, of form y = model(x, axis=None) bounds: list of tuples of (lower,upper), bounds on each 'x' pts: int, number of points sampled by the sampler Additional Inputs: sampler: the mystic.sampler type [default: LatticeSampler] solver: the mystic.solver type [default: NelderMeadSimplexSolver] dist: a distribution type (or float amplitude) [default: None] map: a map instance [default: builtins.map] ny: int, number of model outputs, len(y) [default: None] axis: int, index of output on which to search [default: None] Returns: the mystic.math.legacydata.dataset of sampled data NOTE: additional keywords (evalmon, stepmon, maxiter, maxfun, saveiter, state, termination, constraints, penalty, reducer) are available for use. See mystic.ensemble for more details. NOTE: dist can be used to add randomness to the sampler, and can accept a numpy distribution type such as numpy.random.normal, or a mystic distribution type built with mystic.math.Distribution. if dist=N, where N is an int or float, use normalized Gaussian noise, mystic.math.Distribution(numpy.random.normal, 0, sigma), where sigma is N * sum(bound) for each bound in the bounds, and N scales the amplitude of the noise (typically, N ~ 0.05). NOTE: if pts is negative (i.e. pts=-4), use solver-directed sampling. initial points are chosen by the sampler, then solvers run until converged. a LatticeSampler also accepts a list of pts, indicating the number of bins on each axis; if the product of npts is negative, then use solver-directed sampling. NOTE: given the model is cached, a klepto.dir_archive is created by default """ from mystic.samplers import LatticeSampler searcher = kwds.pop('sampler', LatticeSampler) ax = getattr(model, '__axis__', None) axis = None if hasattr(ax, '__len__') else ax # get default for axis axis = kwds.pop('axis', axis) # allow override? ny = kwds.pop('ny', getattr(model, 'ny', None)) #XXX: best? mvl = ny is not None # True if multivalued axis = axis if mvl else None #XXX: allow multi-axis search? dist = kwds.pop('dist', None) if isinstance(dist, (int, float)): # noise N(0, sig); sig = dist*(ub+lb) import numpy as np from mystic.math import Distribution sig = [dist * (ub + lb) for (lb, ub) in bounds] #FIXME: allow None and inf dist = Distribution(np.random.normal, 0, sig) map_ = kwds.pop('map', map) if not hasattr(model, '__cache__') or not hasattr(model, '__inverse__'): import mystic.cache as mc name = getattr(model, '__name__', None) #XXX: do better? model = mc.cached(archive=name, multivalued=mvl)(model) cache = model.__cache__ imodel = model.__inverse__ if hasattr(pts, '__len__'): import numpy as np pts, _pts = np.prod(pts), [abs(i) for i in pts] else: _pts = None if pts is None: pts = -1 if pts == 0: # don't sample, just grab the archive pass elif pts > 0: # sample pts without optimizing pts = pts if _pts is None else _pts def doit(axis=None): _model = _modelaxis(model, axis) s = searcher(bounds, _model, npts=pts, dist=dist, **kwds) s.sample() return s if mvl and axis is None: # as we don't optimize, we really don't need axis...? doit(axis=0) else: doit(axis) else: # search for minima until terminated pts = -pts if _pts is None else _pts def lower(axis=None): _model = _modelaxis(model, axis) s = searcher(bounds, _model, npts=pts, dist=dist, **kwds) s.sample_until(terminated=all) return s def upper(axis=None): model_ = _modelaxis(imodel, axis) si = searcher(bounds, model_, npts=pts, dist=dist, **kwds) si.sample_until(terminated=all) return si def _apply(f, arg): return f(arg) fs = lower, upper def doit(axis=None): return list(map_(_apply, fs, [axis] * len(fs))) if mvl and axis is None: if ny: import multiprocess.dummy as mt pool = mt.Pool() tmap = pool.map list(tmap(doit, range(ny))) pool.close() pool.join() else: #XXX: default to 0, warn, or error? doit(axis=0) else: doit(axis) import dataset as ds return ds.from_archive(cache(), axis=None)