Ejemplo n.º 1
0
    def valid(self, model, blamelist=False, pairs=True, \
                           all=False, raw=False, **kwds):
        """check for validity with respect to given model

Args:
    model (func): the model function, ``y' = F(x')``.
    blamelist (bool, default=False): if True, indicate the infeasible points.
    pairs (bool, default=True): if True, indicate indices of infeasible points.
    all (bool, default=False): if True, get results for each individual point.
    raw (bool, default=False): if False, get boolean results (i.e. non-float).
    ytol (float, default=0.0): maximum acceptable difference ``|y - F(x')|``.
    xtol (float, default=0.0): maximum acceptable difference ``|x - x'|``.
    cutoff (float, default=ytol): zero out distances less than cutoff.
    hausdorff (bool, default=False): hausdorff ``norm``, where if given,
        then ``ytol = |y - F(x')| + |x - x'|/norm``.

Notes:
    *xtol* defines the n-dimensional base of a pilar of height *ytol*,
    centered at each point. The region inside the pilar defines the space
    where a "valid" model must intersect. If *xtol* is not specified, then
    the base of the pilar will be a dirac at ``x' = x``. This function
    performs an optimization for each ``x`` to find an appropriate ``x'``.

    *ytol* is a single value, while *xtol* is a single value or an iterable.
    *cutoff* takes a float or a boolean, where ``cutoff=True`` will set the
    value of *cutoff* to the default. Typically, the value of *cutoff* is
    *ytol*, 0.0, or None. *hausdorff* can be False (e.g. ``norm = 1.0``),
    True (e.g. ``norm = spread(x)``), or a list of points of ``len(x)``.

    While *cutoff* and *ytol* are very tightly related, they play a distinct
    role; *ytol* is used to set the optimization termination for an acceptable
    ``|y - F(x')|``, while *cutoff* is applied post-optimization.

    If we are using the *hausdorff* norm, then *ytol* will set the optimization
    termination for an acceptable ``|y - F(x')| + |x - x'|/norm``, where the
    ``x`` values are normalized by ``norm = hausdorff``.
"""
        ytol = kwds['ytol'] if 'ytol' in kwds else 0.0  # get tolerance in y
        # default is to zero out distances less than tolerance
        cutoff = kwds['cutoff'] if 'cutoff' in kwds else ytol
        if cutoff is True: cutoff = ytol
        elif cutoff is False: cutoff = None

        from mystic.math.distance import graphical_distance, is_feasible
        # calculate the model validity
        Rv = graphical_distance(model, self, **kwds)
        ld = is_feasible(Rv, cutoff)
        if raw:
            x = Rv
        else:
            x = ld
        if not blamelist: return ld.all() if not all else x
        if pairs: return _fails(ld)
        # else lookup failures
        return _fails(ld, self)
Ejemplo n.º 2
0
  def valid(self, model, blamelist=False, pairs=True, \
                         all=False, raw=False, **kwds):
    """check for validity with respect to given model

Args:
    model (func): the model function, ``y' = F(x')``.
    blamelist (bool, default=False): if True, indicate the infeasible points.
    pairs (bool, default=True): if True, indicate indices of infeasible points.
    all (bool, default=False): if True, get results for each individual point.
    raw (bool, default=False): if False, get boolean results (i.e. non-float).
    ytol (float, default=0.0): maximum acceptable difference ``|y - F(x')|``.
    xtol (float, default=0.0): maximum acceptable difference ``|x - x'|``.
    cutoff (float, default=ytol): zero out distances less than cutoff.
    hausdorff (bool, default=False): hausdorff ``norm``, where if given,
        then ``ytol = |y - F(x')| + |x - x'|/norm``.

Notes:
    *xtol* defines the n-dimensional base of a pilar of height *ytol*,
    centered at each point. The region inside the pilar defines the space
    where a "valid" model must intersect. If *xtol* is not specified, then
    the base of the pilar will be a dirac at ``x' = x``. This function
    performs an optimization for each ``x`` to find an appropriate ``x'``.

    *ytol* is a single value, while *xtol* is a single value or an iterable.
    *cutoff* takes a float or a boolean, where ``cutoff=True`` will set the
    value of *cutoff* to the default. Typically, the value of *cutoff* is
    *ytol*, 0.0, or None. *hausdorff* can be False (e.g. ``norm = 1.0``),
    True (e.g. ``norm = spread(x)``), or a list of points of ``len(x)``.

    While *cutoff* and *ytol* are very tightly related, they play a distinct
    role; *ytol* is used to set the optimization termination for an acceptable
    ``|y - F(x')|``, while *cutoff* is applied post-optimization.

    If we are using the *hausdorff* norm, then *ytol* will set the optimization
    termination for an acceptable ``|y - F(x')| + |x - x'|/norm``, where the
    ``x`` values are normalized by ``norm = hausdorff``.
"""
    ytol = kwds['ytol'] if 'ytol' in kwds else 0.0 # get tolerance in y
    # default is to zero out distances less than tolerance
    cutoff = kwds['cutoff'] if 'cutoff' in kwds else ytol
    if cutoff is True: cutoff = ytol
    elif cutoff is False: cutoff = None

    from mystic.math.distance import graphical_distance, is_feasible
    # calculate the model validity
    Rv = graphical_distance(model, self, **kwds)
    ld = is_feasible(Rv, cutoff)
    if raw:
      x = Rv
    else:
      x = ld
    if not blamelist: return ld.all() if not all else x
    if pairs: return _fails(ld)
    # else lookup failures
    return _fails(ld, self)
Ejemplo n.º 3
0
 def cost(rv):
   """compute cost from a 1-d array of model parameters,
   where: cost = | sum( infeasibility ) | """
   # converting rv to scenario
   points = scenario()
   points.load(rv, pts)
   # calculate infeasibility
   Rv = graphical_distance(model, points, ytol=cutoff, ipop=ipop, \
                                                       imax=imax, **kwds)
   v = infeasibility(Rv, cutoff)
   # converting v to E
   return _sum(v) #XXX: abs ?
Ejemplo n.º 4
0
 def cost(rv):
   """compute cost from a 1-d array of model parameters,
   where: cost = | sum( infeasibility ) | """
   # converting rv to scenario
   points = scenario()
   points.load(rv, pts)
   # calculate infeasibility
   Rv = graphical_distance(model, points, ytol=cutoff, ipop=ipop, \
                                                       imax=imax, **kwds)
   v = infeasibility(Rv, cutoff)
   # converting v to E
   return _sum(v) #XXX: abs ?
Ejemplo n.º 5
0
    def valid(self, model, blamelist=False, pairs=True, all=False, raw=False, **kwds):
        """check for validity with respect to given model

Inputs:
    model -- the model function, y' = F(x')
    blamelist -- if True, report which points are infeasible
    pairs -- if True, report indices of infeasible points
    all -- if True, report results for each point (opposed to all points)
    raw -- if True, report numerical results (opposed to boolean results)

Additional Inputs:
    ytol -- maximum acceptable difference |y - F(x')|; a single value
    xtol -- maximum acceptable difference |x - x'|; an iterable or single value
    cutoff -- zero out distances less than cutoff; typically: ytol, 0.0, or None
    hausdorff -- norm; where if given, ytol = |y - F(x')| + |x - x'|/norm

Notes:
    xtol defines the n-dimensional base of a pilar of height ytol, centered at
    each point. The region inside the pilar defines the space where a "valid"
    model must intersect. If xtol is not specified, then the base of the pilar
    will be a dirac at x' = x. This function performs an optimization for each
    x to find an appropriate x'. While cutoff and ytol are very tightly related,
    they play a distinct role; ytol is used to set the optimization termination
    for an acceptable |y - F(x')|, while cutoff is applied post-optimization.
    If we are using the hausdorff norm, then ytol will set the optimization
    termination for an acceptable |y - F(x')| + |x - x'|/norm, where the x
    values are normalized by norm = hausdorff.
"""
        ytol = kwds["ytol"] if "ytol" in kwds else 0.0  # get tolerance in y
        # default is to zero out distances less than tolerance
        cutoff = kwds["cutoff"] if "cutoff" in kwds else ytol
        if cutoff is True:
            cutoff = ytol
        elif cutoff is False:
            cutoff = None

        from mystic.math.distance import graphical_distance, is_feasible

        # calculate the model validity
        Rv = graphical_distance(model, self, **kwds)
        ld = is_feasible(Rv, cutoff)
        if raw:
            x = Rv
        else:
            x = ld
        if not blamelist:
            return ld.all() if not all else x
        if pairs:
            return _fails(ld)
        # else lookup failures
        return _fails(ld, self)
Ejemplo n.º 6
0
  def valid(self, model, blamelist=False, pairs=True, \
                         all=False, raw=False, **kwds):
    """check for validity with respect to given model

Inputs:
    model -- the model function, y' = F(x')
    blamelist -- if True, report which points are infeasible
    pairs -- if True, report indicies of infeasible points
    all -- if True, report results for each point (opposed to all points)
    raw -- if True, report numerical results (opposed to boolean results)

Additional Inputs:
    ytol -- maximum acceptable difference |y - F(x')|; a single value
    xtol -- maximum acceptable difference |x - x'|; an iterable or single value
    cutoff -- zero out distances less than cutoff; typically: ytol, 0.0, or None
    hausdorff -- norm; where if given, ytol = |y - F(x')| + |x - x'|/norm

Notes:
    xtol defines the n-dimensional base of a pilar of height ytol, centered at
    each point. The region inside the pilar defines the space where a "valid"
    model must intersect. If xtol is not specified, then the base of the pilar
    will be a dirac at x' = x. This function performs an optimization for each
    x to find an appropriate x'. While cutoff and ytol are very tightly related,
    they play a distinct role; ytol is used to set the optimization termination
    for an acceptable |y - F(x')|, while cutoff is applied post-optimization.
    If we are using the hausdorff norm, then ytol will set the optimization
    termination for an acceptable |y - F(x')| + |x - x'|/norm, where the x
    values are normalized by norm = hausdorff.
"""
    ytol = kwds['ytol'] if 'ytol' in kwds else 0.0 # get tolerance in y
    # default is to zero out distances less than tolerance
    cutoff = kwds['cutoff'] if 'cutoff' in kwds else ytol
    if cutoff is True: cutoff = ytol
    elif cutoff is False: cutoff = None

    from mystic.math.distance import graphical_distance, is_feasible
    # calculate the model validity
    Rv = graphical_distance(model, self, **kwds)
    ld = is_feasible(Rv, cutoff)
    if raw:
      x = Rv
    else:
      x = ld
    if not blamelist: return ld.all() if not all else x
    if pairs: return _fails(ld)
    # else lookup failures
    return _fails(ld, self)
Ejemplo n.º 7
0
def distance(data, function=None, hausdorff=True, **kwds):
    """get graphical distance between function y=f(x) and a dataset

    Inputs:
      data: a mystic.math.legacydata.dataset of i points, M inputs, N outputs
      function: a function y=f(*x) of data (x,y)
      hausdorff: if True, use Hausdorff norm

    Additional Inputs:
      method: string for kind of interpolator
      maxpts: int, maximum number of points (x,z) to use from the monitor
      noise: float, amplitude of gaussian noise to remove duplicate x
      extrap: if True, extrapolate a bounding box (can reduce # of nans)
      arrays: if True, return a numpy array; otherwise don't return arrays
      axis: int in [0,N], index of z on which to interpolate (all, by default)

    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').

    NOTE:
      data and function may provide tuple-valued or single-valued output.
      Distance will be measured component-wise, resulting in a tuple of
      distances, unless an 'axis' is selected. If an axis is selected,
      then return distance for the selected component (i.e. axis) only.
    """
    """ #FIXME: the following is generally true (doesn't account for 'fax')
    # function is multi-value & has its components
      # data is multi-value
        # axis is None => apply function component-wise to data
        # axis is int => apply function component-wise to single axis
      # data is single-value
        # axis is None => ERROR: unknown which function component to apply
        # axis is int => apply selected function component to data
    # function is single-value (int or None)
      # data is multi-value
        # axis is None => ERROR: unknown which axis to apply function
        # axis is int => apply function to selected axis of data
      # data is single-value
        # axis is None => apply function to data
        # axis is int => ERROR: can't take axis of single-valued data
    # function is None
      # data is multi-value
        # axis is None => [fmv] => apply function component-wise to data
        # axis is int => [fsv] => apply function to selected axis of data
      # data is single-value
        # axis is None => [fsv] => apply function to data
        # axis is int => ERROR: can't take axis of single-valued data
    """
    axis = kwds.get('axis', None) # axis for tuple-valued data and/or function
    if function is None:
        function = interpolate(data, **kwds)
    import mystic.math.distance as md #FIXME: simplify axis vs fax
    from mystic.math.interpolate import _to_objective
    fax = getattr(function, '__axis__', None) # axis for tuple-valued function
    if axis is None:
        if len(data.values) and type(data.values[0]) in (tuple,list):
            if type(fax) is list: # multi-value func, multi-value data
                import numpy as np
                return np.array([md.graphical_distance(_to_objective(j), _getitem(data, i), hausdorff=hausdorff) for i,j in enumerate(fax)])
            elif type(fax) is int: # single-value func, multi-value data
                return md.graphical_distance(_to_objective(function), _getitem(data, fax), hausdorff=hausdorff)
            else: # single-value func, multi-value data
                msg = "axis required for multi-valued dataset.values"
                raise ValueError(msg)
        else:
            if type(fax) is list: # multi-value func, singe-value data
                msg = "axis required for multi-valued function"
                raise ValueError(msg)
            else: # single-value func, singe-value data
                return md.graphical_distance(_to_objective(function), data, hausdorff=hausdorff)
    else:
        if len(data.values) and type(data.values[0]) in (tuple,list):
            if type(fax) is list: # multi-value func, multi-value data
                return md.graphical_distance(_to_objective(fax[axis]), _getitem(data, axis), hausdorff=hausdorff)
            elif type(fax) is int and fax != axis: # single-value func, multi-value data
                msg = "inconsistent axis for multi-valued dataset.values"
                raise ValueError(msg)
            else: # single-value func, multi-value data
                return md.graphical_distance(_to_objective(function), _getitem(data, axis), hausdorff=hausdorff)
        else:
            if type(fax) is list: # multi-value func, singe-value data
                return md.graphical_distance(_to_objective(fax[axis]), data, hausdorff=hausdorff)
            elif type(fax) is int:
                if fax == axis: # single-value func, singe-value data
                    return md.graphical_distance(_to_objective(function), data, hausdorff=hausdorff)
                msg = "inconsistent axis for multi-valued function"
                raise ValueError(msg)
            else: # single-value func, singe-value data
                _getitem(data, axis) # raise ValueError
    return NotImplemented # should never get here