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)
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)
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 ?
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 ?
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)
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)
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