Beispiel #1
0
    def __init__(self, objective, sampler=None, **kwds):
        """response surface interpolator, where data is sampled from objective

        Input:
          objective: function of the form z=f(x)
          sampler: mystic.search.Searcher instance

        Additional Inputs:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          dim: number of parameters in the input for the objective function
          filter: a data filter produced with mystic.filters.generate_filter
          penalty: mystic.penalty instance of the form y' = k*p(x)
          constraints: mystic.constraints instance of the form x' = c(x)

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        self.filter = kwds.pop('filter', None)
        self.penalty = kwds.pop('penalty', None)
        self.constraints = kwds.pop('constraints', None)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective  # original F(x)
        self.surrogate = None  # interpolated F(*x)
        # interpolator configuration
        self.args = {}  #dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return
Beispiel #2
0
 def __init__(self, objective, sampler=None, **kwds):
     # sampler configuration
     from mystic.search import Searcher
     self.sampler = Searcher() if sampler is None else sampler
     self.maxpts = kwds.pop('maxpts', None)  # N = 1000
     self.noise = kwds.pop('noise', 1e-8)
     # monitor, archive, and trajectories
     self._minmon = self._maxmon = None  #XXX: better default?
     self._minarch = self._maxarch = None  #XXX: better default?
     self.x = None  # params (x)
     self.z = None  # cost   (objective(x))
     # point generator(s) and interpolated model(s) #XXX: better names?
     self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
     self.objective = objective  # original F(x)
     self.surrogate = None  # interpolated F(*x)
     # interpolator configuration
     self.args = {}  #dict(smooth=0, function='thin_plate')
     self.args.update(kwds)
     return
Beispiel #3
0
 def __init__(self, objective, sampler=None, **kwds):
     # sampler configuration
     from mystic.search import Searcher
     self.sampler = Searcher() if sampler is None else sampler
     self.maxpts = kwds.pop('maxpts', None)  # N = 1000
     self.noise = kwds.pop('noise', 1e-8)
     # monitor, archive, and trajectories
     self._minmon = self._maxmon = None  #XXX: better default?
     self._minarch = self._maxarch = None  #XXX: better default?
     self.x = None  # params (x)
     self.z = None  # cost   (objective(x))
     # point generator(s) and interpolated model(s) #XXX: better names?
     self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
     self.objective = objective # original F(x)
     self.surrogate = None # interpolated F(*x)
     # interpolator configuration
     self.args = {}#dict(smooth=0, function='thin_plate')
     self.args.update(kwds)
     return
Beispiel #4
0
    def __init__(self, objective, sampler=None, **kwds):
        """response surface interpolator, where data is sampled from objective

        Input:
          objective: function of the form z=f(x)
          sampler: mystic.search.Searcher instance

        Additional Inputs:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          dim: number of parameters in the input for the objective function

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective # original F(x)
        self.surrogate = None # interpolated F(*x)
        # interpolator configuration
        self.args = {}#dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return
Beispiel #5
0
class Surface(object):  #FIXME: should be subclass of Interpolator (?)
    #surface has:
    #    args - interpolation configuration (smooth, function, ...)
    #    sampler - a search algorithm
    #    maxpts - a maximum number of sampling points
    #    noise - a noise coefficient
    #    dim - dimensionality of the model
    #    function - target function [F(*x)]
    #    objective - target function [F(x)]
    #    surrogate - interpolated function [F(*x)]
    #    model - interpolated function [F(x)]
    #    x,y,z - sampled points(*)
    #
    #surface (or sampler) has:
    #    _minmon,_maxmon - step monitor(*)
    #    _minarch,_maxarch - sampled point archives(*)
    #
    #surface can:
    #    Sample - populate sampled point archive with solver trajectories
    #    Interpolate - build interpolated function from sampled points
    #    Plot - plot sampled points and interpolated surface
    #
    #surface (or sampler) can:
    #    UseMonitor - track trajectories with a monitor(s)
    #    UseArchive - track sampled points in an archive(s)
    #    _max - fetch (x,y,z,model(x,y)) for maximal z of sampled points
    #    _min - fetch (x,y,z,model(x,y)) for minimal z of sampled points

    def __init__(self, objective, sampler=None, **kwds):
        """response surface interpolator, where data is sampled from objective

        Input:
          objective: function of the form z=f(x)
          sampler: mystic.search.Searcher instance

        Additional Inputs:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          dim: number of parameters in the input for the objective function
          filter: a data filter produced with mystic.filters.generate_filter
          penalty: mystic.penalty instance of the form y' = k*p(x)
          constraints: mystic.constraints instance of the form x' = c(x)

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        self.filter = kwds.pop('filter', None)
        self.penalty = kwds.pop('penalty', None)
        self.constraints = kwds.pop('constraints', None)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective  # original F(x)
        self.surrogate = None  # interpolated F(*x)
        # interpolator configuration
        self.args = {}  #dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return

# XXX: useful?
# def _invert_model:
#     takes model and returns inverted_model (maxmodel or invmodel?)
# def _invert_trajectories:
#     takes (xyz) trajectories and returns inverted trajectories (xy-z)

    def UseMonitor(self, min=None, max=None):
        """track parameter trajectories with a monitor(s)

        Input:
          min: monitor instance to track minima; if True, use a new Monitor
          max: monitor instance to track maxima; if True, use a new Monitor

        Output:
          None
        """
        from mystic.monitors import Monitor
        if type(min) is bool: self._minmon = Monitor() if min else None
        elif min is not None: self._minmon = min
        if type(max) is bool: self._maxmon = Monitor() if max else None
        elif max is not None: self._maxmon = max
        return

    def UseArchive(self, min=None, max=None):
        """track sampled points in an archive(s)

        Input:
          min: archive instance to store minima; if True, use a new archive
          max: archive instance to store maxima; if True, use a new archive

        Output:
          None
        """
        from klepto.archives import dict_archive as d
        if type(min) is bool: self._minarch = d(cached=False) if min else None
        elif min is not None: self._minarch = min
        if type(max) is bool: self._maxarch = d(cached=False) if max else None
        elif max is not None: self._maxarch = max
        return

    """
    def doit(self, bounds, stop, step=200, scale=False, shift=False,
             density=9, axes=(), vals=(), maxpts=maxpts, **kwds):
        if not self.sampler.traj: self.sampler.UseTrajectories()
        # get trajectories
        self.Sample(bounds, stop)
        # get interpolated function
        self.Interpolate(**kwds)
        # check extrema  #XXX: put _min,_max in Interpolate? (downsampled)
        f = lambda x,z: (z,surface.surrogate(*x))
        print("min: {}; min@f: {}".format(*f(*surface._min())))
        print("max: {}; max@f: {}".format(*f(*urfacef._max())))
        # plot surface
        self.Plot(step=step, scale=scale, shift=shift, density=density, axes=axes, vals=vals, maxpts=maxpts)
        return
    """

    def Sample(self,
               bounds,
               stop,
               clear=False,
               verbose=False,
               all=False,
               **kwds):
        """sample data (x,z) using objective function z=f(x)

        Input:
          bounds: tuple of floats (min,max), bounds on the search region
          stop: termination condition
          clear: if True, clear the archive of stored points
          verbose: if True, print a summary of search/sampling results
          all: if True, use solver EvalMonitor, else use StepMonitor
          filter: a data filter produced with mystic.filters.generate_filter
          penalty: mystic.penalty instance of the form y' = k*p(x)
          constraints: mystic.constraints instance of the form x' = c(x)

        Output:
          x: an array of shape (npts, dim) or (npts,)
          z: an array of shape (npts,)
        """
        #XXX: does the strategy of finding min/max always apply?
        import numpy as np
        penalty = kwds.get('penalty', self.penalty)
        constraints = kwds.get('constraints', self.constraints)
        kwargs = dict(stop=stop, penalty=penalty, constraints=constraints)

        # get model (for minima)
        model = self.objective
        self.dim = len(bounds)

        ### get mins ###
        monitor = self._minmon
        archive = None if clear else self._minarch
        inverse = False

        if all:  #FIXME: better define role/use of Reset/Archive/clear...
            self.sampler.Reset(None, inv=inverse)  # reset the sampler
            self.sampler.archive = archive
            self.sampler.Search(model, bounds, evalmon=monitor, **kwargs)

        else:
            self.sampler.Reset(archive, inv=inverse)  # reset the sampler
            self.sampler.Search(model, bounds, monitor=monitor, **kwargs)
        if verbose: self.sampler._summarize()
        # read trajectories from log (or monitor)
        xyz = self.sampler.Samples(all=all)
        if clear: self.sampler.Reset()  # reset the sampler
        ### end mins ###

        # invert model (for maxima)
        imodel = lambda *args, **kwds: -model(*args, **kwds)
        if penalty is not None:  # also invert penalty
            kwargs['penalty'] = lambda *args, **kwds: -penalty(*args, **kwds)

        ### get maxs ###
        monitor = self._maxmon
        archive = None if clear else self._maxarch
        inverse = True

        if all:  #FIXME: better define role/use of Reset/Archive/clear...
            self.sampler.Reset(None, inv=inverse)  # reset the sampler
            self.sampler.archive = archive
            self.sampler.Search(imodel, bounds, evalmon=monitor, **kwargs)
        else:
            self.sampler.Reset(archive, inv=inverse)  # reset the sampler
            self.sampler.Search(imodel, bounds, monitor=monitor, **kwargs)
        if verbose: self.sampler._summarize()
        xyz = np.hstack((xyz, self.sampler.Samples(all=all)))
        if clear: self.sampler.Reset()  # reset the sampler
        ### end maxs ###

        # split into params and cost
        self.x = xyz.T[:, :-1]
        self.z = xyz.T[:, -1]
        # apply any filter, and return
        filter = kwds.pop('filter', self.filter)
        if filter:  #XXX: better here, or in Interpolate???
            self.x, self.z = filter(self.x, self.z)
        return self.x, self.z

    def Interpolate(self, **kwds):  #XXX: refactor so use self.interpolator ?
        """interpolate data (x,z) to generate response function z=f(*x)

        Input:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          extrap: if True, extrapolate a bounding box (can reduce # of nans)
          arrays: if True, return a numpy array; otherwise don't return arrays

        Output:
          interpolated response function, where z=f(*x.T)

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        from interpolator import Interpolator
        args = self.args.copy()
        args.update(kwds)
        maxpts, noise = self.maxpts, self.noise
        ii = Interpolator(self.x, self.z, maxpts=maxpts, noise=noise, **args)
        self.surrogate = ii.Interpolate(**args)
        # build the surrogate
        self.surrogate.__doc__ = self.objective.__doc__
        return self.surrogate

    def _max(self):  #XXX: remove?
        """get the x[i],z[i] corresponding to the max(z)
        """
        import numpy as np
        mz = np.argmax(self.z)
        return self.x[mz], self.z[mz]

    def _min(self):  #XXX: remove?
        """get the x[i],z[i] corresponding to the min(z)
        """
        import numpy as np
        mz = np.argmin(self.z)
        return self.x[mz], self.z[mz]

    def Plot(self, **kwds):
        """produce a scatterplot of (x,z) and the surface z = function(*x.T)

        Input:
          step: int, plot every 'step' points on the grid [default: 200]
          scale: float, scaling factor for the z-axis [default: False]
          shift: float, additive shift for the z-axis [default: False]
          density: int, density of wireframe for the plot surface [default: 9]
          axes: tuple, indicies of the axes to plot [default: ()]
          vals: list of values (one per axis) for unplotted axes [default: ()]
          maxpts: int, maximum number of (x,z) points to use [default: None]
          kernel: function transforming x to x', where x' = kernel(x)
          vtol: float, maximum distance outside bounds hypercube to plot data
        """
        # get interpolted function
        fx = self.surrogate
        # plot interpolated surface
        from plotter import Plotter
        p = Plotter(self.x, self.z, fx, **kwds)
        p.Plot()
        # if plotter interpolated the function, get the function
        self.surrogate = fx or p.function

    def __set_function(self,
                       function):  #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        from mystic.math.interpolate import _to_objective
        _objective = _to_objective(function)

        def objective(x, *args, **kwds):
            result = _objective(x, *args, **kwds)
            return result.tolist() if hasattr(result, 'tolist') else result

        self.objective = objective
        self.objective.__doc__ = function.__doc__
        return

    def __function(self):  #XXX: deal w/ selector (2D)? ExtraArgs? _to_function
        # convert model to 'args' format (i.e. takes positional args)
        from mystic.math.interpolate import _to_function
        function = _to_function(self.objective, ndim=self.dim)
        function.__doc__ = self.objective.__doc__
        return function

    def __model(self):  #XXX: deal w/ selector (2D)? ExtraArgs? _to_objective
        # convert to 'model' format (i.e. takes a parameter vector)
        if self.surrogate is None: return None
        from mystic.math.interpolate import _to_objective
        _objective = _to_objective(self.surrogate)

        def objective(x, *args, **kwds):
            result = _objective(x, *args, **kwds)
            return result.tolist() if hasattr(result, 'tolist') else result

        objective.__doc__ = self.objective.__doc__
        return objective

    # interface
    function = property(__function, __set_function)
    model = property(__model)
Beispiel #6
0
class Surface(object):
    #surface has:
    #    args - interpolation configuration (smooth, function, ...)
    #    sampler - a search algorithm
    #    maxpts - a maximum number of sampling points
    #    noise - a noise coefficient
    #    dim - dimensionality of the model
    #    function - target function [F(*x)]
    #    objective - target function [F(x)]
    #    surrogate - interpolated function [F(*x)]
    #    model - interpolated function [F(x)]
    #    x,y,z - sampled points(*)
    #
    #surface (or sampler) has:
    #    _minmon,_maxmon - step monitor(*)
    #    _minarch,_maxarch - sampled point archives(*)
    #
    #surface can:
    #    Sample - populate sampled point archive with solver trajectories
    #    Interpolate - build interpolated function from sampled points
    #    Plot - plot sampled points and interpolated surface
    #
    #surface (or sampler) can:
    #    UseMonitor - track trajectories with a monitor(s)
    #    UseArchive - track sampled points in an archive(s)
    #    _noise - remove duplicate sampled points (x) by adding noise to x
    #    _downsample - skip sampled points at a regular interval (for speed)
    #    _max - fetch (x,y,z,model(x,y)) for maximal z of sampled points
    #    _min - fetch (x,y,z,model(x,y)) for minimal z of sampled points

    def __init__(self, objective, sampler=None, **kwds):
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective  # original F(x)
        self.surrogate = None  # interpolated F(*x)
        # interpolator configuration
        self.args = {}  #dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return

# XXX: useful?
# def _invert_model:
#     takes model and returns inverted_model (maxmodel or invmodel?)
# def _invert_trajectories:
#     takes (xyz) trajectories and returns inverted trajectories (xy-z)

    def UseMonitor(self, min=None, max=None):
        from mystic.monitors import Monitor
        if type(min) is bool: self._minmon = Monitor() if min else None
        elif min is not None: self._minmon = min
        if type(max) is bool: self._maxmon = Monitor() if max else None
        elif max is not None: self._maxmon = max
        return

    def UseArchive(self, min=None, max=None):
        from klepto.archives import dict_archive as d
        if type(min) is bool: self._minarch = d(cached=False) if min else None
        elif min is not None: self._minarch = min
        if type(max) is bool: self._maxarch = d(cached=False) if max else None
        elif max is not None: self._maxarch = max
        return

    """
    def doit(self, bounds, stop, step=200, scale=False, shift=False,
             density=9, axes=(), vals=(), maxpts=maxpts, **kwds):
        if not self.sampler.traj: self.sampler.UseTrajectories()
        # get trajectories
        self.Sample(bounds, stop)
        # get interpolated function
        self.Interpolate(**kwds)
        # check extrema  #XXX: put _min,_max in Interpolate? (downsampled)
        f = lambda x,z: (z,surface.surrogate(*x))
        print("min: {}; min@f: {}".format(*f(*surface._min())))
        print("max: {}; max@f: {}".format(*f(*urfacef._max())))
        # plot surface
        self.Plot(step, scale, shift, density, axes, vals, maxpts)
        return
    """

    def Sample(self, bounds, stop, clear=False, verbose=False):
        #XXX: does the strategy of finding min/max always apply?
        import numpy as np

        # get model (for minima)
        model = self.objective
        self.dim = len(bounds)

        ### get mins ###
        stepmon = self._minmon
        archive = None if clear else self._minarch
        inverse = False

        self.sampler.Reset(archive, inv=inverse)  # reset the sampler
        self.sampler.Search(model, bounds, stop=stop, monitor=stepmon)
        if verbose: self.sampler._summarize()
        # read trajectories from log (or monitor)
        xyz = self.sampler.Samples()
        if clear: self.sampler.Reset()  # reset the sampler
        ### end mins ###

        # invert model (for maxima)
        imodel = lambda *args, **kwds: -model(*args, **kwds)

        ### get maxs ###
        stepmon = self._maxmon
        archive = None if clear else self._maxarch
        inverse = True

        self.sampler.Reset(archive, inv=inverse)  # reset the sampler
        self.sampler.Search(imodel, bounds, stop=stop, monitor=stepmon)
        if verbose: self.sampler._summarize()
        xyz = np.hstack((xyz, self.sampler.Samples()))
        if clear: self.sampler.Reset()  # reset the sampler
        ### end maxs ###

        # split into params and cost
        self.x = xyz.T[:, :-1]
        self.z = xyz.T[:, -1]
        return self.x, self.z

    def _noise(self, scale=None, x=None):
        #HACK: remove any duplicate points by adding noise
        import numpy as np
        if x is None: x = self.x
        if scale is None: scale = self.noise
        if not scale: return x
        return x + np.random.normal(scale=scale, size=x.shape)

    def _downsample(self, maxpts=None, x=None, z=None):
        if maxpts is None: maxpts = self.maxpts
        if x is None: x = self.x
        if z is None: z = self.z
        if len(x) != len(z):
            raise ValueError("the input array lengths must match exactly")
        if maxpts is not None and len(z) > maxpts:
            N = max(int(round(len(z) / float(maxpts))), 1)
            #   print("for speed, sampling {} down to {}".format(len(z),len(z)/N))
            #   ax.plot(x[:,0], x[:,1], z, 'ko', linewidth=2, markersize=4)
            x = x[::N]
            z = z[::N]
        #   plt.show()
        #   exit()
        return x, z

    def _interpolate(self, x, z, **kwds):
        import numpy as np
        from scipy.interpolate import Rbf as interpolate
        return interpolate(*np.vstack((x.T, z)), **kwds)

    def Interpolate(self, **kwds):  #XXX: better take a strategy?
        maxpts = kwds.pop('maxpts', self.maxpts)
        noise = kwds.pop('noise', self.noise)
        args = self.args.copy()
        args.update(kwds)
        x, z = self._downsample(maxpts)
        #NOTE: really only need to add noise when have duplicate x,y coords
        x = self._noise(noise, x)
        # build the surrogate
        self.surrogate = self._interpolate(x, z, **args)
        self.surrogate.__doc__ = self.function.__doc__
        return self.surrogate

    def _max(self):
        import numpy as np
        x = self.x
        z = self.z
        mz = np.argmax(z)
        return x[mz], z[mz]

    def _min(self):
        import numpy as np
        x = self.x
        z = self.z
        mz = np.argmin(z)
        return x[mz], z[mz]


    def Plot(self, step=200, scale=False, shift=False, \
             density=9, axes=(), vals=(), maxpts=None):
        # plot interpolated surface
        from mpl_toolkits.mplot3d import axes3d
        import matplotlib.pyplot as plt
        from matplotlib import cm
        import numpy as np

        figure = plt.figure()
        kwds = {'projection': '3d'}
        ax = figure.gca(**kwds)
        ax.autoscale(tight=True)

        if maxpts is None: maxpts = self.maxpts
        x, z = self._downsample(maxpts)

        # get two axes to plot, and indices of the remaining axes
        axes = axes[:2]  #XXX: error if wrong size?
        ix = [i for i in range(len(x.T)) if i not in axes]
        n = 2 - len(axes)
        axes, ix = list(axes) + ix[:n], ix[n:]

        # build list of fixed values (default mins), override with user input
        #fix = np.zeros(len(ix))
        fix = enumerate(self._min()[0])
        fix = np.array(tuple(j for (i, j) in fix if i not in axes))
        fix[:len(vals)] = vals

        # build grid of points, one for each param, apply fixed values
        grid = np.ones((len(x.T), step, step))
        grid[ix] = fix[:, None, None]
        del ix, fix

        # build sub-surface of surrogate(x) to display, apply to the grid
        xy = x.T[axes]
        M = complex('{}j'.format(step))
        grid[axes] = np.mgrid[xy[0].min():xy[0].max():M,
                              xy[1].min():xy[1].max():M]
        del xy

        # evaluate the surrogate on the sub-surface
        z_ = self.surrogate(*grid)
        # scaling used by model plotter
        if scale:
            if shift:
                z_ = np.asarray(z_) + shift
            z_ = np.log(4 * np.asarray(z_) * scale + 1) + 2

        # plot surface
        d = max(11 - density, 1)
        x_ = grid[axes[0]]
        y_ = grid[axes[-1]]
        ax.plot_wireframe(x_, y_, z_, rstride=d, cstride=d)
        #ax.plot_surface(x_, y_, z_, rstride=d, cstride=d, cmap=cm.jet, linewidth=0, antialiased=False)

        # use the sampled values
        z_ = z
        # scaling used by model plotter
        if scale:
            if shift:
                z_ = np.asarray(z_) + shift
            z_ = np.log(4 * np.asarray(z_) * scale + 1) + 2

        # plot data points
        x_ = x.T[axes[0]]
        y_ = x.T[axes[-1]]
        ax.plot(x_, y_, z_, 'ko', linewidth=2, markersize=4)
        plt.show()  #XXX: show or don't show?... or return?


#       figure.savefig('griewangk.png')

    def __set_function(self,
                       function):  #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        def objective(x, *args, **kwds):
            return function(*(tuple(x) + args), **kwds).tolist()

        self.objective = objective
        self.objective.__doc__ = function.__doc__
        return

    def __function(self):  #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert model to 'args' format (i.e. takes positional args)
        def function(*args, **kwds):
            len = self.dim  # or kwds.pop('len', None)
            if len is None: return self.objective(args, **kwds)
            return self.objective(args[:len], *args[len:], **kwds)

        function.__doc__ = self.objective.__doc__
        return function

    def __model(self):  #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        if self.surrogate is None: return None

        def objective(x, *args, **kwds):
            return self.surrogate(*(tuple(x) + args), **kwds).tolist()

        objective.__doc__ = self.objective.__doc__
        return objective

    # interface
    function = property(__function, __set_function)
    model = property(__model)
Beispiel #7
0
class Surface(object):
   #surface has:
   #    args - interpolation configuration (smooth, function, ...)
   #    sampler - a search algorithm
   #    maxpts - a maximum number of sampling points
   #    noise - a noise coefficient
   #    dim - dimensionality of the model
   #    function - target function [F(*x)]
   #    objective - target function [F(x)]
   #    surrogate - interpolated function [F(*x)]
   #    model - interpolated function [F(x)]
   #    x,y,z - sampled points(*)
   #
   #surface (or sampler) has:
   #    _minmon,_maxmon - step monitor(*)
   #    _minarch,_maxarch - sampled point archives(*)
   #
   #surface can:
   #    Sample - populate sampled point archive with solver trajectories
   #    Interpolate - build interpolated function from sampled points
   #    Plot - plot sampled points and interpolated surface
   #
   #surface (or sampler) can:
   #    UseMonitor - track trajectories with a monitor(s)
   #    UseArchive - track sampled points in an archive(s)
   #    _noise - remove duplicate sampled points (x) by adding noise to x
   #    _downsample - skip sampled points at a regular interval (for speed)
   #    _max - fetch (x,y,z,model(x,y)) for maximal z of sampled points
   #    _min - fetch (x,y,z,model(x,y)) for minimal z of sampled points

    def __init__(self, objective, sampler=None, **kwds):
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective # original F(x)
        self.surrogate = None # interpolated F(*x)
        # interpolator configuration
        self.args = {}#dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return

  # XXX: useful?
  # def _invert_model:
  #     takes model and returns inverted_model (maxmodel or invmodel?)
  # def _invert_trajectories:
  #     takes (xyz) trajectories and returns inverted trajectories (xy-z)

    def UseMonitor(self, min=None, max=None):
        from mystic.monitors import Monitor
        if type(min) is bool: self._minmon = Monitor() if min else None
        elif min is not None: self._minmon = min
        if type(max) is bool: self._maxmon = Monitor() if max else None
        elif max is not None: self._maxmon = max
        return


    def UseArchive(self, min=None, max=None):
        from klepto.archives import dict_archive as d
        if type(min) is bool: self._minarch = d(cached=False) if min else None
        elif min is not None: self._minarch = min
        if type(max) is bool: self._maxarch = d(cached=False) if max else None
        elif max is not None: self._maxarch = max
        return

    """
    def doit(self, bounds, stop, step=200, scale=False, shift=False,
             density=9, axes=(), vals=(), maxpts=maxpts, **kwds):
        if not self.sampler.traj: self.sampler.UseTrajectories()
        # get trajectories
        self.Sample(bounds, stop)
        # get interpolated function
        self.Interpolate(**kwds)
        # check extrema  #XXX: put _min,_max in Interpolate? (downsampled)
        f = lambda x,z: (z,surface.surrogate(*x))
        print "min: {}; min@f: {}".format(*f(*surface._min()))
        print "max: {}; max@f: {}".format(*f(*urfacef._max()))
        # plot surface
        self.Plot(step, scale, shift, density, axes, vals, maxpts)
        return
    """

    def Sample(self, bounds, stop, clear=False, verbose=False):
        #XXX: does the strategy of finding min/max always apply?
        import numpy as np

        # get model (for minima)
        model = self.objective
        self.dim = len(bounds)

        ### get mins ###
        stepmon = self._minmon
        archive = None if clear else self._minarch
        inverse = False

        self.sampler.Reset(archive, inv=inverse) # reset the sampler
        self.sampler.Search(model, bounds, stop=stop, monitor=stepmon)
        if verbose: self.sampler._summarize()
        # read trajectories from log (or monitor)
        xyz = self.sampler.Samples()
        if clear: self.sampler.Reset()  # reset the sampler
        ### end mins ###

        # invert model (for maxima)
        imodel = lambda *args, **kwds: -model(*args, **kwds)

        ### get maxs ###
        stepmon = self._maxmon
        archive = None if clear else self._maxarch
        inverse = True

        self.sampler.Reset(archive, inv=inverse) # reset the sampler
        self.sampler.Search(imodel, bounds, stop=stop, monitor=stepmon)
        if verbose: self.sampler._summarize()
        xyz = np.hstack((xyz, self.sampler.Samples()))
        if clear: self.sampler.Reset()  # reset the sampler
        ### end maxs ###

        # split into params and cost
        self.x = xyz.T[:,:-1]
        self.z = xyz.T[:,-1]
        return self.x, self.z


    def _noise(self, scale=None, x=None):
        #HACK: remove any duplicate points by adding noise
        import numpy as np
        if x is None: x = self.x
        if scale is None: scale = self.noise
        if not scale: return x
        return x + np.random.normal(scale=scale, size=x.shape)


    def _downsample(self, maxpts=None, x=None, z=None):
        if maxpts is None: maxpts = self.maxpts
        if x is None: x = self.x
        if z is None: z = self.z
        if len(x) != len(z):
            raise ValueError("the input array lengths must match exactly")
        if maxpts is not None and len(z) > maxpts:
            N = max(int(round(len(z)/float(maxpts))),1)
        #   print "for speed, sampling {} down to {}".format(len(z),len(z)/N)
        #   ax.plot(x[:,0], x[:,1], z, 'ko', linewidth=2, markersize=4)
            x = x[::N]
            z = z[::N]
        #   plt.show()
        #   exit()
        return x, z

    def _interpolate(self, x, z, **kwds):
        import numpy as np
        from scipy.interpolate import Rbf as interpolate
        return interpolate(*np.vstack((x.T, z)), **kwds)


    def Interpolate(self, **kwds): #XXX: better take a strategy?
        maxpts = kwds.pop('maxpts', self.maxpts)
        noise = kwds.pop('noise', self.noise)
        args = self.args.copy()
        args.update(kwds)
        x, z = self._downsample(maxpts)
        #NOTE: really only need to add noise when have duplicate x,y coords
        x = self._noise(noise, x)
        # build the surrogate
        self.surrogate = self._interpolate(x, z, **args)
        self.surrogate.__doc__ = self.function.__doc__
        return self.surrogate


    def _max(self):
        import numpy as np
        x = self.x
        z = self.z
        mz = np.argmax(z)
        return x[mz],z[mz]

    def _min(self):
        import numpy as np
        x = self.x
        z = self.z
        mz = np.argmin(z)
        return x[mz],z[mz]


    def Plot(self, step=200, scale=False, shift=False, \
             density=9, axes=(), vals=(), maxpts=None):
        # plot interpolated surface
        from mpl_toolkits.mplot3d import axes3d
        import matplotlib.pyplot as plt
        from matplotlib import cm
        import numpy as np

        figure = plt.figure()
        kwds = {'projection':'3d'}
        ax = figure.gca(**kwds)
        ax.autoscale(tight=True)

        if maxpts is None: maxpts = self.maxpts
        x, z = self._downsample(maxpts)

        # get two axes to plot, and indices of the remaining axes
        axes = axes[:2]  #XXX: error if wrong size?
        ix = [i for i in range(len(x.T)) if i not in axes]
        n = 2-len(axes)
        axes, ix = list(axes)+ix[:n], ix[n:]

        # build list of fixed values (default mins), override with user input
       #fix = np.zeros(len(ix))
        fix = enumerate(self._min()[0])
        fix = np.array(tuple(j for (i,j) in fix if i not in axes))
        fix[:len(vals)] = vals

        # build grid of points, one for each param, apply fixed values
        grid = np.ones((len(x.T),step,step))
        grid[ix] = fix[:,None,None]
        del ix, fix

        # build sub-surface of surrogate(x) to display, apply to the grid
        xy = x.T[axes]
        M = complex('{}j'.format(step))
        grid[axes] = np.mgrid[xy[0].min():xy[0].max():M, 
                              xy[1].min():xy[1].max():M]
        del xy

        # evaluate the surrogate on the sub-surface
        z_ = self.surrogate(*grid)
	# scaling used by model plotter
        if scale:
            if shift:
                z_ = np.asarray(z_)+shift
            z_ = np.log(4*np.asarray(z_)*scale+1)+2

        # plot surface
        d = max(11 - density, 1)
        x_ = grid[axes[0]]
        y_ = grid[axes[-1]]
        ax.plot_wireframe(x_, y_, z_, rstride=d, cstride=d)
        #ax.plot_surface(x_, y_, z_, rstride=d, cstride=d, cmap=cm.jet, linewidth=0, antialiased=False)

        # use the sampled values
        z_ = z
	# scaling used by model plotter
        if scale:
            if shift:
                z_ = np.asarray(z_)+shift
            z_ = np.log(4*np.asarray(z_)*scale+1)+2

        # plot data points
        x_ = x.T[axes[0]]
        y_ = x.T[axes[-1]]
        ax.plot(x_, y_, z_, 'ko', linewidth=2, markersize=4)
        plt.show()  #XXX: show or don't show?... or return?
#       figure.savefig('griewangk.png')


    def __set_function(self, function): #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        def objective(x, *args, **kwds):
            return function(*(tuple(x)+args), **kwds).tolist()
        self.objective = objective
        self.objective.__doc__ = function.__doc__
        return

    def __function(self): #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert model to 'args' format (i.e. takes positional args)
        def function(*args, **kwds):
            len = self.dim # or kwds.pop('len', None)
            if len is None: return self.objective(args, **kwds)
            return self.objective(args[:len], *args[len:], **kwds)
        function.__doc__ = self.objective.__doc__
        return function

    def __model(self): #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        if self.surrogate is None: return None
        def objective(x, *args, **kwds):
            return self.surrogate(*(tuple(x)+args), **kwds).tolist()
        objective.__doc__ = self.objective.__doc__
        return objective


    # interface
    function = property(__function, __set_function )
    model = property(__model )
Beispiel #8
0
    #CUTE: 'configure' monitor and archive if they are desired
    if stepmon:
        stepmon = LoggingMonitor(1) # montor for all runs
        itermon = LoggingMonitor(1, filename='inv.txt') #XXX: log.txt?
    else:
        stepmon = itermon = None
    if archive: #python2.5
        ar_name = '__%s_%sD_cache__' % (model.__self__.__class__.__name__,ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
        ar_name = '__%s_%sD_invcache__' % (model.__self__.__class__.__name__,ndim)
        ivcache = dir_archive(ar_name, serialized=True, cached=False)
    else:
        archive = ivcache = None

    from mystic.search import Searcher #XXX: init w/ archive, then UseArchive?
    sampler = Searcher(npts, retry, tol, mem, _map, archive, sprayer, seeker)
    sampler.Verbose(disp)
    sampler.UseTrajectories(traj)

    ### doit ###
    maxpts = 1000. #10000.
    surface = Surface(model, sampler, maxpts=maxpts, dim=ndim)
    surface.UseMonitor(stepmon, itermon)
    surface.UseArchive(archive, ivcache)

    density = 9
    shift = 0
    scale = 0
    step = 200
    args = {
    'smooth': 0,
Beispiel #9
0
    seeker = PowellDirectionalSolver
    npts = 25 # number of solvers
    _map = Pool().map
    retry = 1 # max consectutive iteration retries without a cache 'miss'
    tol = 8   # rounding precision
    mem = 1   # cache rounding precision

    #CUTE: 'configure' monitor and archive if they are desired
    if stepmon: stepmon = LoggingMonitor(1) # montor for all runs
    else: stepmon = None
    if archive: #python2.5
        ar_name = '__%s_%sD_cache__' % (model.__self__.__class__.__name__,ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
    else: archive = None

    searcher = Searcher(npts, retry, tol, mem, _map, archive, sprayer, seeker)
    searcher.Verbose(disp)
    searcher.UseTrajectories(traj)

    searcher.Reset(archive, inv=False)
    searcher.Search(model, bounds, stop=stop, monitor=stepmon)
    searcher._summarize()

    ##### extract results #####
    xyz = searcher.Samples()

    ##### invert the model, and get the maxima #####
    imodel = lambda *args, **kwds: -model(*args, **kwds)

    #CUTE: 'configure' monitor and archive if they are desired
    if stepmon not in (None, False):
Beispiel #10
0
    repeat = 0   # number of times to repeat the search
    tol = 8      # rounding precision
    mem = 1      # cache rounding precision
    size = 0     # max in-memory cache size

    #CUTE: 'configure' monitor and archive if they are desired
    if evalmon: evalmon = LoggingMonitor(1) # montor for all runs
    else: evalmon = None
    if archive: #python2.5
        name = getattr(model,'__name__','model')
        ar_name = '__%s_%sD_cache__' % (name,ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
    else: archive = None

    # configure a Searcher to use a "evaluation archive"
    searcher = Searcher(npts, retry, tol, mem, size, _map, archive, None, sprayer, seeker, repeat=repeat)
    searcher.Verbose(disp)
    searcher.UseTrajectories(traj)

    searcher.Reset(None, inv=False) #XXX: careful, can replace searcher.cache
    searcher.Search(model, bounds, stop=stop, evalmon=evalmon)
    searcher._summarize()

    ##### extract results #####
    xyz = searcher.Samples(all=True)

    ##### invert the model, and get the maxima #####
    imodel = lambda *args, **kwds: -model(*args, **kwds)

    #CUTE: 'configure' monitor and archive if they are desired
    if evalmon not in (None, False):
Beispiel #11
0
    if stepmon: stepmon = LoggingMonitor(1)  # montor for all runs
    else: stepmon = None
    if archive:  #python2.5
        name = getattr(model, '__name__', 'model')
        ar_name = '__%s_%sD_cache__' % (name, ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
    else:
        archive = None

    # configure a Searcher to use a "trajectory cache"
    searcher = Searcher(npts,
                        retry,
                        tol,
                        mem,
                        size,
                        _map,
                        None,
                        archive,
                        sprayer,
                        seeker,
                        repeat=repeat)
    searcher.Verbose(disp)
    searcher.UseTrajectories(traj)

    searcher.Reset(archive, inv=False)
    searcher.Search(model, bounds, stop=stop, monitor=stepmon)
    searcher._summarize()

    ##### extract results #####
    xyz = searcher.Samples()
Beispiel #12
0
class Surface(object): #FIXME: should be subclass of Interpolator (?)
   #surface has:
   #    args - interpolation configuration (smooth, function, ...)
   #    sampler - a search algorithm
   #    maxpts - a maximum number of sampling points
   #    noise - a noise coefficient
   #    dim - dimensionality of the model
   #    function - target function [F(*x)]
   #    objective - target function [F(x)]
   #    surrogate - interpolated function [F(*x)]
   #    model - interpolated function [F(x)]
   #    x,y,z - sampled points(*)
   #
   #surface (or sampler) has:
   #    _minmon,_maxmon - step monitor(*)
   #    _minarch,_maxarch - sampled point archives(*)
   #
   #surface can:
   #    Sample - populate sampled point archive with solver trajectories
   #    Interpolate - build interpolated function from sampled points
   #    Plot - plot sampled points and interpolated surface
   #
   #surface (or sampler) can:
   #    UseMonitor - track trajectories with a monitor(s)
   #    UseArchive - track sampled points in an archive(s)
   #    _max - fetch (x,y,z,model(x,y)) for maximal z of sampled points
   #    _min - fetch (x,y,z,model(x,y)) for minimal z of sampled points

    def __init__(self, objective, sampler=None, **kwds):
        """response surface interpolator, where data is sampled from objective

        Input:
          objective: function of the form z=f(x)
          sampler: mystic.search.Searcher instance

        Additional Inputs:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          dim: number of parameters in the input for the objective function

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        # sampler configuration
        from mystic.search import Searcher
        self.sampler = Searcher() if sampler is None else sampler
        self.maxpts = kwds.pop('maxpts', None)  # N = 1000
        self.noise = kwds.pop('noise', 1e-8)
        # monitor, archive, and trajectories
        self._minmon = self._maxmon = None  #XXX: better default?
        self._minarch = self._maxarch = None  #XXX: better default?
        self.x = None  # params (x)
        self.z = None  # cost   (objective(x))
        # point generator(s) and interpolated model(s) #XXX: better names?
        self.dim = kwds.pop('dim', None)  #XXX: should be (or set) len(x)
        self.objective = objective # original F(x)
        self.surrogate = None # interpolated F(*x)
        # interpolator configuration
        self.args = {}#dict(smooth=0, function='thin_plate')
        self.args.update(kwds)
        return

  # XXX: useful?
  # def _invert_model:
  #     takes model and returns inverted_model (maxmodel or invmodel?)
  # def _invert_trajectories:
  #     takes (xyz) trajectories and returns inverted trajectories (xy-z)

    def UseMonitor(self, min=None, max=None):
        """track parameter trajectories with a monitor(s)

        Input:
          min: monitor instance to track minima; if True, use a new Monitor
          max: monitor instance to track maxima; if True, use a new Monitor

        Output:
          None
        """
        from mystic.monitors import Monitor
        if type(min) is bool: self._minmon = Monitor() if min else None
        elif min is not None: self._minmon = min
        if type(max) is bool: self._maxmon = Monitor() if max else None
        elif max is not None: self._maxmon = max
        return


    def UseArchive(self, min=None, max=None):
        """track sampled points in an archive(s)

        Input:
          min: archive instance to store minima; if True, use a new archive
          max: archive instance to store maxima; if True, use a new archive

        Output:
          None
        """
        from klepto.archives import dict_archive as d
        if type(min) is bool: self._minarch = d(cached=False) if min else None
        elif min is not None: self._minarch = min
        if type(max) is bool: self._maxarch = d(cached=False) if max else None
        elif max is not None: self._maxarch = max
        return

    """
    def doit(self, bounds, stop, step=200, scale=False, shift=False,
             density=9, axes=(), vals=(), maxpts=maxpts, **kwds):
        if not self.sampler.traj: self.sampler.UseTrajectories()
        # get trajectories
        self.Sample(bounds, stop)
        # get interpolated function
        self.Interpolate(**kwds)
        # check extrema  #XXX: put _min,_max in Interpolate? (downsampled)
        f = lambda x,z: (z,surface.surrogate(*x))
        print("min: {}; min@f: {}".format(*f(*surface._min())))
        print("max: {}; max@f: {}".format(*f(*urfacef._max())))
        # plot surface
        self.Plot(step=step, scale=scale, shift=shift, density=density, axes=axes, vals=vals, maxpts=maxpts)
        return
    """

    def Sample(self, bounds, stop, clear=False, verbose=False, all=False):
        """sample data (x,z) using objective function z=f(x)

        Input:
          bounds: tuple of floats (min,max), bounds on the search region
          stop: termination condition
          clear: if True, clear the archive of stored points
          verbose: if True, print a summary of search/sampling results
          all: if True, use solver EvalMonitor, else use StepMonitor

        Output:
          x: an array of shape (npts, dim) or (npts,)
          z: an array of shape (npts,)
        """
        #XXX: does the strategy of finding min/max always apply?
        import numpy as np

        # get model (for minima)
        model = self.objective
        self.dim = len(bounds)

        ### get mins ###
        monitor = self._minmon
        archive = None if clear else self._minarch
        inverse = False

        if all: #FIXME: better define role/use of Reset/Archive/clear...
            self.sampler.Reset(None, inv=inverse) # reset the sampler
            self.sampler.archive = archive
            self.sampler.Search(model, bounds, stop=stop, evalmon=monitor)
        else:
            self.sampler.Reset(archive, inv=inverse) # reset the sampler
            self.sampler.Search(model, bounds, stop=stop, monitor=monitor)
        if verbose: self.sampler._summarize()
        # read trajectories from log (or monitor)
        xyz = self.sampler.Samples(all=all)
        if clear: self.sampler.Reset()  # reset the sampler
        ### end mins ###

        # invert model (for maxima)
        imodel = lambda *args, **kwds: -model(*args, **kwds)

        ### get maxs ###
        monitor = self._maxmon
        archive = None if clear else self._maxarch
        inverse = True

        if all: #FIXME: better define role/use of Reset/Archive/clear...
            self.sampler.Reset(None, inv=inverse) # reset the sampler
            self.sampler.archive = archive
            self.sampler.Search(imodel, bounds, stop=stop, evalmon=monitor)
        else:
            self.sampler.Reset(archive, inv=inverse) # reset the sampler
            self.sampler.Search(imodel, bounds, stop=stop, monitor=monitor)
        if verbose: self.sampler._summarize()
        xyz = np.hstack((xyz, self.sampler.Samples(all=all)))
        if clear: self.sampler.Reset()  # reset the sampler
        ### end maxs ###

        # split into params and cost
        self.x = xyz.T[:,:-1]
        self.z = xyz.T[:,-1]
        return self.x, self.z


    def Interpolate(self, **kwds): #XXX: refactor so use self.interpolator ?
        """interpolate data (x,z) to generate response function z=f(*x)

        Input:
          maxpts: int, maximum number of points to use from (x,z)
          noise: float, amplitude of gaussian noise to remove duplicate x
          method: string for kind of interpolator
          extrap: if True, extrapolate a bounding box (can reduce # of nans)
          arrays: if True, return a numpy array; otherwise don't return arrays

        Output:
          interpolated response function, where z=f(*x.T)

        NOTE:
          if scipy is not installed, will use np.interp for 1D (non-rbf),
          or mystic's rbf otherwise. default method is 'nearest' for
          1D and 'linear' otherwise. method can be one of ('rbf','linear',
          'nearest','cubic','inverse','gaussian','quintic','thin_plate').
        """
        from interpolator import Interpolator
        args = self.args.copy()
        args.update(kwds)
        maxpts, noise = self.maxpts, self.noise
        ii = Interpolator(self.x, self.z, maxpts=maxpts, noise=noise, **args)
        self.surrogate = ii.Interpolate(**args)
        # build the surrogate
        self.surrogate.__doc__ = self.objective.__doc__
        return self.surrogate


    def _max(self): #XXX: remove?
        """get the x[i],z[i] corresponding to the max(z)
        """
        import numpy as np
        mz = np.argmax(self.z)
        return self.x[mz], self.z[mz]

    def _min(self): #XXX: remove?
        """get the x[i],z[i] corresponding to the min(z)
        """
        import numpy as np
        mz = np.argmin(self.z)
        return self.x[mz], self.z[mz]


    def Plot(self, **kwds):
        """produce a scatterplot of (x,z) and the surface z = function(*x.T)

        Input:
          step: int, plot every 'step' points on the grid [default: 200]
          scale: float, scaling factor for the z-axis [default: False]
          shift: float, additive shift for the z-axis [default: False]
          density: int, density of wireframe for the plot surface [default: 9]
          axes: tuple, indicies of the axes to plot [default: ()]
          vals: list of values (one per axis) for unplotted axes [default: ()]
          maxpts: int, maximum number of (x,z) points to use [default: None]
          kernel: function transforming x to x', where x' = kernel(x)
        """
        # get interpolted function
        fx = self.surrogate
        # plot interpolated surface
        from plotter import Plotter
        p = Plotter(self.x, self.z, fx, **kwds)
        p.Plot()
        # if plotter interpolated the function, get the function
        self.surrogate = fx or p.function


    def __set_function(self, function): #XXX: deal w/ selector (2D)? ExtraArgs?
        # convert to 'model' format (i.e. takes a parameter vector)
        from mystic.math.interpolate import _to_objective
        _objective = _to_objective(function)
        def objective(x, *args, **kwds):
            result = _objective(x, *args, **kwds)
            return result.tolist() if hasattr(result, 'tolist') else result
        self.objective = objective
        self.objective.__doc__ = function.__doc__
        return

    def __function(self): #XXX: deal w/ selector (2D)? ExtraArgs? _to_function
        # convert model to 'args' format (i.e. takes positional args)
        from mystic.math.interpolate import _to_function
        function = _to_function(self.objective, ndim=self.dim)
        function.__doc__ = self.objective.__doc__
        return function

    def __model(self): #XXX: deal w/ selector (2D)? ExtraArgs? _to_objective
        # convert to 'model' format (i.e. takes a parameter vector)
        if self.surrogate is None: return None
        from mystic.math.interpolate import _to_objective
        _objective = _to_objective(self.surrogate)
        def objective(x, *args, **kwds):
            result = _objective(x, *args, **kwds)
            return result.tolist() if hasattr(result, 'tolist') else result
        objective.__doc__ = self.objective.__doc__
        return objective


    # interface
    function = property(__function, __set_function )
    model = property(__model )
Beispiel #13
0
        costmon = LoggingMonitor(1, filename='inv.txt') #XXX: log.txt?
    else:
        monitor = costmon = None
    if archive: #python2.5
        name = getattr(model,'__name__','model')
        ar_name = '__%s_%sD_cache__' % (name,ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
        ar_name = '__%s_%sD_invcache__' % (name,ndim)
        ivcache = dir_archive(ar_name, serialized=True, cached=False)
    else:
        archive = ivcache = None

    from mystic.search import Searcher #XXX: init w/ archive, then UseArchive?
    expts,evals = (None,archive) if all else (archive, None)
    #expts,evals = (archive, None) #XXX: don't override the sample archive
    sampler = Searcher(npts, retry, tol, mem, size, _map, evals, expts, sprayer, seeker, repeat=repeat)
    sampler.Verbose(disp)
    sampler.UseTrajectories(traj)

    ### doit ###
    maxpts = 1000. #10000.
    surface = Surface(model, sampler, maxpts=maxpts, dim=ndim)
    surface.UseMonitor(monitor, costmon)
    surface.UseArchive(archive, ivcache)

    density = 9
    shift = 0
    scale = 0
    step = 200
    args = {
   #'smooth': 0,
Beispiel #14
0
    if evalmon: evalmon = LoggingMonitor(1)  # montor for all runs
    else: evalmon = None
    if archive:  #python2.5
        name = getattr(model, '__name__', 'model')
        ar_name = '__%s_%sD_cache__' % (name, ndim)
        archive = dir_archive(ar_name, serialized=True, cached=False)
    else:
        archive = None

    # configure a Searcher to use a "evaluation archive"
    searcher = Searcher(npts,
                        retry,
                        tol,
                        mem,
                        size,
                        _map,
                        archive,
                        None,
                        sprayer,
                        seeker,
                        repeat=repeat)
    searcher.Verbose(disp)
    searcher.UseTrajectories(traj)

    searcher.Reset(None, inv=False)  #XXX: careful, can replace searcher.cache
    searcher.Search(model, bounds, stop=stop, evalmon=evalmon)
    searcher._summarize()

    ##### extract results #####
    xyz = searcher.Samples(all=True)