docstr: find the expected value of the statistical quantity
  
  Input:
      axis: int, the index of y on which to find value (all, by default)
      axmap: map instance, to execute each axis in parallel (None, by default)
      instance: bool, if True, return the solver instance (False, by default)
  
  Additional Input:
      solver: mystic.solver instance [default: DifferentialEvolutionSolver2]
      npop: population size [default: None]
      id: a unique identifier for the solver [default: None]
      nested: mystic.solver instance [default: None], for ensemble solvers
      x0: initial parameter guess [default: use RandomInitialPoints]
      maxiter: max number of iterations [default: defined in solver]
      maxfun: max number of objective evaluations [default: defined in solver]
      evalmon: mystic.monitor instance [default: Monitor], for evaluations
      stepmon: mystic.monitor instance [default: Monitor], for iterations
      map: pathos map instance for solver.SetMapper [default: None]
      save: iteration frequency to save solver [default: None]
      opts: dict of configuration options for solver.Solve [default: {}]
  
  Further Input:
      archive: the archive (str name for a new archive, or archive instance)
      dist: a mystic.tools.Distribution instance (or list of Distributions)
      tight: if True, apply bounds concurrent with other constraints
      clip: if True, clip at bounds, else resample [default = False]
      smap: map instance, to sample the quantity in parallel [default = None]
      npts: maximum number of sample points [default = 10000]
      ipts: number of sample points per iteration [default = npts]
      iter: number of iterations to stop after if change < itol [default = 1]
      itol: stop if change in value < itol over iter [default = 1e-15]
  
  Returns:
      expected value of the statistical quantity, for the specified axis
  
  NOTE: by default, npts samplings of the expected value will be drawn,
      where npts is large. When the randomness of the model is expected to
      be small, the expected value can often be found quickly by setting
      ipts=1 and iter to a small number. Note however, that iterations are
      serial, while samplings within an iteration can utilize a parallel map.
  
  NOTE: an optimization is used to solve for inputs that yield the expected
      value, where the objective includes a penalty targeted to stop at the
      sampled mean. The additional penalty is 'linear_equality' with a
      strength, k, set equal to the sampled mean. The additional termination
      condition is 'VTR(ftol, target)', where ftol=1e-16 for models with
      no randomness, and ftol is the sampled variance for models with
      randomness. Target is the sampled mean. If only the expected value is
      of interest, setting `instance=None` will skip the optimization.
      
docstr_tok: ["find","the","expected","value","of","the","statistical","quantity","Input",":","axis",":","int",",","the","index","of","y","on","which","to","find","value","(","all",",","by","default",")","axmap",":","map","instance",",","to","execute","each","axis","in","parallel","(","None",",","by","default",")","instance",":","bool",",","if","True",",","return","the","solver","instance","(","False",",","by","default",")","Additional","Input",":","solver",":","mystic.solver","instance","[","default",":","DifferentialEvolutionSolver2","]","npop",":","population","size","[","default",":","None","]","id",":","a","unique","identifier","for","the","solver","[","default",":","None","]","nested",":","mystic.solver","instance","[","default",":","None","]",",","for","ensemble","solvers","x0",":","initial","parameter","guess","[","default",":","use","RandomInitialPoints","]","maxiter",":","max","number","of","iterations","[","default",":","defined","in","solver","]","maxfun",":","max","number","of","objective","evaluations","[","default",":","defined","in","solver","]","evalmon",":","mystic.monitor","instance","[","default",":","Monitor","]",",","for","evaluations","stepmon",":","mystic.monitor","instance","[","default",":","Monitor","]",",","for","iterations","map",":","pathos","map","instance","for","solver.SetMapper","[","default",":","None","]","save",":","iteration","frequency","to","save","solver","[","default",":","None","]","opts",":","dict","of","configuration","options","for","solver.Solve","[","default",":","{","}","]","Further","Input",":","archive",":","the","archive","(","str","name","for","a","new","archive",",","or","archive","instance",")","dist",":","a","mystic.tools.Distribution","instance","(","or","list","of","Distributions",")","tight",":","if","True",",","apply","bounds","concurrent","with","other","constraints","clip",":","if","True",",","clip","at","bounds",",","else","resample","[","default","=","False","]","smap",":","map","instance",",","to","sample","the","quantity","in","parallel","[","default","=","None","]","npts",":","maximum","number","of","sample","points","[","default","=","10000","]","ipts",":","number","of","sample","points","per","iteration","[","default","=","npts","]","iter",":","number","of","iterations","to","stop","after","if","change","<","itol","[","default","=","1","]","itol",":","stop","if","change","in","value","<","itol","over","iter","[","default","=","1e-15","]","Returns",":","expected","value","of","the","statistical","quantity",",","for","the","specified","axis","NOTE",":","by","default",",","npts","samplings","of","the","expected","value","will","be","drawn",",","where","npts","is","large",".","When","the","randomness","of","the","model","is","expected","to","be","small",",","the","expected","value","can","often","be","found","quickly","by","setting","ipts=1","and","iter","to","a","small","number",".","Note","however",",","that","iterations","are","serial",",","while","samplings","within","an","iteration","can","utilize","a","parallel","map",".","NOTE",":","an","optimization","is","used","to","solve","for","inputs","that","yield","the","expected","value",",","where","the","objective","includes","a","penalty","targeted","to","stop","at","the","sampled","mean",".","The","additional","penalty","is","'linear_equality","'","with","a","strength",",","k",",","set","equal","to","the","sampled","mean",".","The","additional","termination","condition","is","'VTR","(","ftol",",","target",")","'",",","where","ftol=1e-16","for","models","with","no","randomness",",","and","ftol","is","the","sampled","variance","for","models","with","randomness",".","Target","is","the","sampled","mean",".","If","only","the","expected","value","is","of","interest",",","setting","`","instance=None","`","will","skip","the","optimization","."]
code: def expected(self, axis=None, **kwds):
      """find the expected value of the statistical quantity
  
      Input:
          axis: int, the index of y on which to find value (all, by default)
          axmap: map instance, to execute each axis in parallel (None, by default)
          instance: bool, if True, return the solver instance (False, by default)
  
      Additional Input:
          solver: mystic.solver instance [default: DifferentialEvolutionSolver2]
          npop: population size [default: None]
          id: a unique identifier for the solver [default: None]
          nested: mystic.solver instance [default: None], for ensemble solvers
          x0: initial parameter guess [default: use RandomInitialPoints]
          maxiter: max number of iterations [default: defined in solver]
          maxfun: max number of objective evaluations [default: defined in solver]
          evalmon: mystic.monitor instance [default: Monitor], for evaluations
          stepmon: mystic.monitor instance [default: Monitor], for iterations
          map: pathos map instance for solver.SetMapper [default: None]
          save: iteration frequency to save solver [default: None]
          opts: dict of configuration options for solver.Solve [default: {}]
  
      Further Input:
          archive: the archive (str name for a new archive, or archive instance)
          dist: a mystic.tools.Distribution instance (or list of Distributions)
          tight: if True, apply bounds concurrent with other constraints
          clip: if True, clip at bounds, else resample [default = False]
          smap: map instance, to sample the quantity in parallel [default = None]
          npts: maximum number of sample points [default = 10000]
          ipts: number of sample points per iteration [default = npts]
          iter: number of iterations to stop after if change < itol [default = 1]
          itol: stop if change in value < itol over iter [default = 1e-15]
  
      Returns:
          expected value of the statistical quantity, for the specified axis
  
      NOTE: by default, npts samplings of the expected value will be drawn,
          where npts is large. When the randomness of the model is expected to
          be small, the expected value can often be found quickly by setting
          ipts=1 and iter to a small number. Note however, that iterations are
          serial, while samplings within an iteration can utilize a parallel map.
  
      NOTE: an optimization is used to solve for inputs that yield the expected
          value, where the objective includes a penalty targeted to stop at the
          sampled mean. The additional penalty is 'linear_equality' with a
          strength, k, set equal to the sampled mean. The additional termination
          condition is 'VTR(ftol, target)', where ftol=1e-16 for models with
          no randomness, and ftol is the sampled variance for models with
          randomness. Target is the sampled mean. If only the expected value is
          of interest, setting `instance=None` will skip the optimization.
      """
      # NOTE: kwds(verbose, reducer) undocumented
      full = kwds.pop("instance", False)
      # self._expect.clear() #XXX: good idea?
      # use __call__ to get expected value [float or tuple(float)]
      from mystic.monitors import VerboseMonitor, Null
  
      verbose = kwds.pop("verbose", False)  # NOTE: used for debug
      label = self.__class__.__name__
      mon = VerboseMonitor(1, None, label=label) if verbose else Null()
      db = kwds.pop("archive", None)
      if db is None:
          db = file_archive()
      elif type(db) in (str, ("".__class__)):
          db = read(db, type=file_archive)
      # populate monitor with existing archive data
      m = Monitor()
      xs = list(db.values())
      N = size = ys = len(xs)
      if size:
          xtype = type(xs[-1])  # is tuple or float
          multi = hasattr(xtype, "__len__")
          import numpy as np
  
          xs = np.array(xs)
          var = xtype(xs.var(axis=0)) if multi else xs.var()
          if xs.ndim == 1:
              xs = np.atleast_2d(xs).T
          ys = np.arange(1, size + 1)
          m._x = xs = (xs.cumsum(axis=0).T / ys).T.tolist()
          m._y = ys = ys.tolist()
          ave = xtype(xs[-1]) if multi else xs[-1][0]
          if verbose:
              print("%s: %s @ %s" % (label, ave, N))
      else:
          var = ave = float("nan")  # XXX: good idea?
          multi = self.axes is not None
          if multi:
              var = ave = (ave,) * self.axes
      # sample expected value iteratively until termination met
      # reducer = kwds.pop('reducer', None) #XXX: throw error if provided?
      npts = kwds.pop("npts", 10000)
      ipts = kwds.pop("ipts", None)
      niter = kwds.pop("iter", None)
      itol = kwds.pop("itol", None)
      if npts is None:
          npts = float("inf")
      if ipts is None:
          ipts = npts
      if niter is None:
          niter = 1
      if itol is None:
          itol = 1e-15
      if ipts == float("inf") or ipts < 1:
          msg = "ipts must be a positive integer"
          raise ValueError(msg)
      if npts < ipts:
          msg = "ipts must be less than npts"
          raise ValueError(msg)
      smap = kwds.pop("smap", None)
      kwds_ = {}  # kwds for _expected
      keys = ("reducer", "dist", "tight", "clip")  # keys for __call__
      kwds = {
          k: v
          for k, v in kwds.items()
          if k in keys or kwds_.update({k: v})
      }
  
      import numpy as np
      from mystic.abstract_solver import AbstractSolver
      from mystic.termination import CollapseAt
  
      solver = AbstractSolver(self.axes or 1)  # XXX: axis?
      solver.SetTermination(
          CollapseAt(tolerance=itol, generations=niter)
      )
      solver.SetEvaluationLimits(maxiter=npts - 1)  # max num of samples
      solver.SetGenerationMonitor(m)
      while not solver.Terminated() and N != npts:
          N += ipts  # XXX: or self.axes?
          N = min(npts, N)
          ave = self.__call__(
              archive=db, axis=axis, npts=N, map=smap, **kwds
          )
          # update stepmon with the sampled values
          xs = list(db.values())
          xtype = type(xs[-1])  # is tuple or float
          multi = hasattr(xtype, "__len__")
          xs = np.array(xs)
          var = xtype(np.nanvar(xs, axis=0)) if multi else np.nanvar(xs)
          if xs.ndim == 1:
              xs = np.atleast_2d(xs).T
          ys = np.arange(1, xs.shape[0] + 1)
          y_ = ys - np.cumsum(np.isnan(xs), axis=0).T  # nan-adjusted
          solver._stepmon._x = xs = (
              np.nancumsum(xs, axis=0).T / y_
          ).T.tolist()
          solver._stepmon._y = ys = ys.tolist()
          del y_
          ave = xtype(xs[-1]) if multi else xs[-1][0]
          mon(N, ave)  # XXX: or use (ave, N)?
  
      if verbose and len(m) > size:
          print(solver.Terminated(info=True))  # XXX: also disp=True?
          print("%s: %s @ %s" % (label, ave, N))
  
      # downselect ave to the specified axis, where relevant
      if isinstance(ave, tuple):  # self.axes is not None
          for i, me in enumerate(ave):
              self._ave[i] = me
              self._var[i] = var[i]
              self._expect[i] = None
              self._err[i] = None
      else:
          ax = None if self.axes is None else axis
          self._ave[ax] = ave
          self._var[ax] = var
          self._expect[ax] = None
          self._err[ax] = None
  
      if full is None:  # short-circuit the solver
          return ave
      # solve for params that yield expected value
      if self.axes is None or axis is not None:
          # solve for expected value of objective (in measure space)
          solver = self._expected(axis, **kwds_)
          ax = None if self.axes is None else axis
          self._expect[ax] = solver
          self._err[ax] = me = abs(self._ave[ax] - solver.bestEnergy)
          if verbose:
              print(
                  "%s: misfit = %s, var = %s" % (ax, me, self._var[ax])
              )
          if full:
              return solver
          return ave  # NOTE: within misfit of solver.bestEnergy
      # else axis is None
      solvers = self._expected(axis, **kwds_)
      for ax, solver in enumerate(solvers):
          self._expect[ax] = solver
          self._err[ax] = me = abs(self._ave[ax] - solver.bestEnergy)
          if verbose:
              print(
                  "%s: misfit = %s, var = %s" % (ax, me, self._var[ax])
              )
      if full:
          return solvers
      return ave
  
imports: import mystic.cache
  from mystic.cache import cached
  from mystic.cache.archive import dict_archive, file_archive, read
  from mystic.math import almostEqual
  from mystic.math.discrete import product_measure
  from mystic.math.samples import random_samples
  from mystic.solvers import DifferentialEvolutionSolver2
  from mystic.monitors import Monitor
  from ouq_models import WrapModel
label_desc: Use image node_id 2 for calling the BaseOUQ obj's underlying member method code with example usage: obj.expected(axis) and returns: ave, ave, ave, solvers, solver