Example #1
0
    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
Example #3
0
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))
Example #4
0
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]')
Example #5
0
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)