def monte_carlo_integrate(f, lb, ub, n=10000): #XXX ok default for n? """ Returns the integral of an m-dimensional function f from lb to ub using a Monte Carlo integration of n points Inputs: f -- a function that takes a list and returns a number. lb -- a list of lower bounds ub -- a list of upper bounds n -- the number of points to sample [Default is n=10000] References: 1. "A Primer on Scientific Programming with Python", by Hans Petter Langtangen, page 443-445, 2014. 2. http://en.wikipedia.org/wiki/Monte_Carlo_integration 3. http://math.fullerton.edu/mathews/n2003/MonteCarloMod.html """ from mystic.math.stats import volume from mystic.math.samples import random_samples vol = volume(lb, ub) x = [random_samples(lb, ub, npts=1) for k in range(1, n+1)] r = map(f, x) #FIXME: , nnodes=nnodes, launcher=launcher) s = sum(r)[0] I = (vol/n)*s return float(I)
def monte_carlo_integrate(f, lb, ub, n=10000): #XXX ok default for n? """ Returns the integral of an m-dimensional function f from lb to ub using a Monte Carlo integration of n points Inputs: f -- a function that takes a list and returns a number. lb -- a list of lower bounds ub -- a list of upper bounds n -- the number of points to sample [Default is n=10000] References: This code is adapted from A Primer on Scientific Programming with Python by Hans Petter Langtangen, page 443-445. Also, see http://en.wikipedia.org/wiki/Monte_Carlo_integration and http://math.fullerton.edu/mathews/n2003/MonteCarloMod.html """ from mystic.math.stats import volume from mystic.math.samples import random_samples vol = volume(lb, ub) x = [random_samples(lb, ub, npts=1) for k in range(1, n + 1)] r = map(f, x) #FIXME: , nnodes=nnodes, launcher=launcher) s = sum(r)[0] I = (vol / k) * s return float(I)
def samplepts(lb, ub, npts, dist=None): """ takes lower and upper bounds (e.g. lb = [0,3], ub = [2,4]) produces a list of sample points s = [[1,3],[1,4],[2,3],[2,4]] Inputs: lb -- a list of the lower bounds ub -- a list of the upper bounds npts -- number of sample points dist -- a mystic.math.Distribution instance (or list of Distributions) """ from mystic.math.samples import random_samples q = random_samples(lb, ub, npts, dist) return q.T.tolist()
def samplepts(lb,ub,npts,dist=None): """ takes lower and upper bounds (e.g. lb = [0,3], ub = [2,4]) produces a list of sample points s = [[1,3],[1,4],[2,3],[2,4]] Inputs: lb -- a list of the lower bounds ub -- a list of the upper bounds npts -- number of sample points dist -- a mystic.math.Distribution instance """ from mystic.math.samples import random_samples q = random_samples(lb,ub,npts,dist) return q.T.tolist()
def samplepts(lb,ub,npts): """ takes upper and lower bounds (e.g. ub = [2,4], lb = [0,3]) produces a list of sample points s = [[1,3],[1,4],[2,3],[2,4]] Inputs: lower bounds -- a list of the lower bounds upper bounds -- a list of the upper bounds npts -- number of sample points """ from mystic.math.samples import random_samples q = random_samples(lb,ub,npts) q = [list(i) for i in q] q = zip(*q) return [list(i) for i in q]
def samplepts(lb, ub, npts): """ takes upper and lower bounds (e.g. ub = [2,4], lb = [0,3]) produces a list of sample points s = [[1,3],[1,4],[2,3],[2,4]] Inputs: lower bounds -- a list of the lower bounds upper bounds -- a list of the upper bounds npts -- number of sample points """ from mystic.math.samples import random_samples q = random_samples(lb, ub, npts) q = [list(i) for i in q] q = zip(*q) return [list(i) for i in q]
def __call__(self, axis=None, **kwds): """apply the reducer to the sampled statistical quantity Input: axis: int, the index of y on which to find bound (all, by default) Additional Input: reducer: function to reduce a list to a single value (e.g. mean, max) dist: a mystic.tools.Distribution instance (or list of Distributions) npts: number of sample points [default = 10000] clip: if True, clip at bounds, else resample [default = False] Returns: sampled statistical quantity, for the specified axis, reduced to a float """ #XXX: return what? "energy and solution?" reduced? reducer = kwds.pop('reducer', None) if kwds.get('npts', None) is None: kwds.pop('npts', None) s = random_samples(self.lb, self.ub, **kwds).T fobj = cached(archive=dict_archive())(self.objective) #XXX: bad idea? self._pts = fobj.__cache__( ) #XXX: also bad idea? include from *_bounds? objective = lambda rv: fobj(self.constraint(rv), axis=axis) import multiprocess.dummy as mp #FIXME: process pickle/recursion Error pool = mp.Pool() # len(s) map = pool.map #TODO: don't hardwire map s = map(objective, s) #NOTE: s = [(...),(...)] or [...] pool.close() pool.join() if axis is None and self.axes is not None: # apply per axis if reducer is None: return tuple(sum(si) / len(si) for si in zip(*s)) #XXX: better tuple(reducer(s, axis=0).tolist()) if numpy ufunc? return tuple(reducer(si) for si in zip(*s)) s = tuple(s) return sum(s) / len(s) if reducer is None else reducer(s)
def test_calculate_methods(npts=2): upper_bounds = [1.0] lower_bounds = [0.0] # ------------------------------------- # generate initial coordinates, weights # ------------------------------------- # get a random distribution of points if disp: print("generate random points and weights") coordinates = samplepts(lower_bounds, upper_bounds, npts) D0 = D = [i[0] for i in coordinates] if disp: print("positions: %s" % D) # calculate sample range R0 = R = spread(D) if disp: print("range: %s" % R) # select weights randomly in [0,1], then normalize so sum(weights) = 1 wts = random_samples([0], [1], npts)[0] weights = normalize(wts, 0.0, zsum=True) if disp: print("weights (when normalized to 0.0): %s" % weights) assert almostEqual(sum(weights), 0.0, tol=1e-15) weights = normalize(wts, 1.0) assert almostEqual(sum(weights), 1.0, tol=1e-15) if disp: print("weights (when normalized to 1.0): %s" % weights) w = norm(weights) if disp: print("norm: %s" % w) assert almostEqual(w, sum(weights) / npts) # calculate sample mean m0 = m = mean(D, weights) if disp: print("mean: %s" % m) if disp: print("") # ------------------------------------- # modify coordinates, maintaining mean & range # ------------------------------------- # get new random distribution if disp: print("modify positions, maintaining mean and range") coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] # impose a range and mean on the points D = impose_spread(R, D, weights) D = impose_mean(m, D, weights) # print results if disp: print("positions: %s" % D) R = spread(D) if disp: print("range: %s" % R) assert almostEqual(R, R0) m = mean(D, weights) if disp: print("mean: %s" % m) assert almostEqual(m, m0) if disp: print("") # ------------------------------------- # modify weights, maintaining mean & norm # ------------------------------------- # select weights randomly in [0,1] if disp: print("modify weights, maintaining mean and range") wts = random_samples([0], [1], npts)[0] # print intermediate results #print("weights: %s" % wts) #sm = mean(D, wts) #print("tmp mean: %s" % sm) #print("") # impose mean and weight norm on the points D = impose_mean(m, D, wts) DD, weights = impose_weight_norm(D, wts) # print results if disp: print("weights: %s" % weights) w = norm(weights) if disp: print("norm: %s" % w) assert almostEqual(w, sum(weights) / npts) if disp: print("positions: %s" % DD) R = spread(DD) if disp: print("range: %s" % R) assert almostEqual(R, R0) sm = mean(DD, weights) if disp: print("mean: %s" % sm) assert almostEqual(sm, m0) sv = variance(DD, weights) if disp: print("var: %s" % sv) assert not almostEqual(sv, R) assert almostEqual(sv, 0.0, tol=.3) # ------------------------------------- # modify variance, maintaining mean # ------------------------------------- if disp: print("\nmodify variance, maintaining mean") DD = impose_variance(R, DD, weights) sm = mean(DD, weights) if disp: print("mean: %s" % sm) assert almostEqual(sm, m0) sv = variance(DD, weights) if disp: print("var: %s" % sv) assert almostEqual(sv, R)
def test_calculate_methods(npts=2): upper_bounds = [1.0] lower_bounds = [0.0] # ------------------------------------- # generate initial coordinates, weights # ------------------------------------- # get a random distribution of points print "generate random points and weights" coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] print "positions: %s" % D # calculate sample range R = spread(D) print "range: %s" % R # select weights randomly in [0,1], then normalize so sum(weights) = 1 wts = random_samples([0], [1], npts)[0] weights = normalize(wts, 0.0, zsum=True) print "weights (when normalized to 0.0): %s" % weights weights = normalize(wts) print "weights (when normalized to 1.0): %s" % weights w = norm(weights) print "norm: %s" % w # calculate sample mean m = mean(D, weights) print "mean: %s" % m print "" # ------------------------------------- # modify coordinates, maintaining mean & range # ------------------------------------- # get new random distribution print "modify positions, maintaining mean and range" coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] # impose a range and mean on the points D = impose_spread(R, D, weights) D = impose_mean(m, D, weights) # print results print "positions: %s" % D R = spread(D) print "range: %s" % R m = mean(D, weights) print "mean: %s" % m print "" # ------------------------------------- # modify weights, maintaining mean & norm # ------------------------------------- # select weights randomly in [0,1] print "modify weights, maintaining mean and range" wts = random_samples([0], [1], npts)[0] # print intermediate results #print "weights: %s" % wts #sm = mean(D, wts) #print "tmp mean: %s" % sm #print "" # impose mean and weight norm on the points D = impose_mean(m, D, wts) DD, weights = impose_weight_norm(D, wts) # print results print "weights: %s" % weights w = norm(weights) print "norm: %s" % w print "positions: %s" % DD R = spread(DD) print "range: %s" % R sm = mean(DD, weights) print "mean: %s" % sm sv = variance(DD, weights) print "var: %s" % sv # ------------------------------------- # modify variance, maintaining mean # ------------------------------------- print "\nmodify variance, maintaining mean" DD = impose_variance(R, DD, weights) sm = mean(DD, weights) print "mean: %s" % sm sv = variance(DD, weights) print "var: %s" % sv
else: param_string += ", " print " parameters: %s" % param_string # get diameter for entire cuboid lb,ub = [lower_bounds],[upper_bounds] cuboid_volume = volume(lb[0],ub[0]) params0, subdiams0, diam0, probmass0 = test_cuboids(lb,ub,RVstart,RVend,\ cuboid_volume) SOLVED_PARAMETERS, SUB_DIAMETERS = params0, subdiams0 TOTAL_DIAMETERS, PROBABILITY_MASS = diam0, probmass0 if DEBUG: print "\nSTATUS = %s" % STATUS if not DEBUG: pts = random_samples(lb[0],ub[0]) pof = sampled_pof(model,pts) print "Exact PoF: %s" % pof # prepare new set of random samples (across entire domain) as 'data' if not PER_AI: pts = random_samples(lb[0],ub[0],num_sample_points) for i in range(len(lb)): print "\n" print " lower bounds: %s" % lb[i] print " upper bounds: %s" % ub[i] for solved in params0[0]: print "solved: %s" % solved print "subdiameters (squared): %s" % subdiams0[0] print "diameter (squared): %s" % diam0[0] print " probability mass: %s" % probmass0[0]
def test_calculate_methods(npts=2): upper_bounds = [1.0] lower_bounds = [0.0] # ------------------------------------- # generate initial coordinates, weights # ------------------------------------- # get a random distribution of points if disp: print "generate random points and weights" coordinates = samplepts(lower_bounds, upper_bounds, npts) D0 = D = [i[0] for i in coordinates] if disp: print "positions: %s" % D # calculate sample range R0 = R = spread(D) if disp: print "range: %s" % R # select weights randomly in [0,1], then normalize so sum(weights) = 1 wts = random_samples([0],[1], npts)[0] weights = normalize(wts, 0.0, zsum=True) if disp: print "weights (when normalized to 0.0): %s" % weights assert almostEqual(sum(weights), 0.0, tol=1e-15) weights = normalize(wts) assert almostEqual(sum(weights), 1.0, tol=1e-15) if disp: print "weights (when normalized to 1.0): %s" % weights w = norm(weights) if disp: print "norm: %s" % w assert almostEqual(w, sum(weights)/npts) # calculate sample mean m0 = m = mean(D,weights) if disp: print "mean: %s" % m if disp: print "" # ------------------------------------- # modify coordinates, maintaining mean & range # ------------------------------------- # get new random distribution if disp: print "modify positions, maintaining mean and range" coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] # impose a range and mean on the points D = impose_spread(R, D, weights) D = impose_mean(m, D, weights) # print results if disp: print "positions: %s" % D R = spread(D) if disp: print "range: %s" % R assert almostEqual(R, R0) m = mean(D, weights) if disp: print "mean: %s" % m assert almostEqual(m, m0) if disp: print "" # ------------------------------------- # modify weights, maintaining mean & norm # ------------------------------------- # select weights randomly in [0,1] if disp: print "modify weights, maintaining mean and range" wts = random_samples([0],[1], npts)[0] # print intermediate results #print "weights: %s" % wts #sm = mean(D, wts) #print "tmp mean: %s" % sm #print "" # impose mean and weight norm on the points D = impose_mean(m, D, wts) DD, weights = impose_weight_norm(D, wts) # print results if disp: print "weights: %s" % weights w = norm(weights) if disp: print "norm: %s" % w assert almostEqual(w, sum(weights)/npts) if disp: print "positions: %s" % DD R = spread(DD) if disp: print "range: %s" % R assert almostEqual(R, R0) sm = mean(DD, weights) if disp: print "mean: %s" % sm assert almostEqual(sm, m0) sv = variance(DD, weights) if disp: print "var: %s" % sv assert not almostEqual(sv, R) assert almostEqual(sv, 0.0, tol=.2) # ------------------------------------- # modify variance, maintaining mean # ------------------------------------- if disp: print "\nmodify variance, maintaining mean" DD = impose_variance(R, DD, weights) sm = mean(DD, weights) if disp: print "mean: %s" % sm assert almostEqual(sm, m0) sv = variance(DD, weights) if disp: print "var: %s" % sv assert almostEqual(sv, R)
def test_calculate_methods(npts=2): upper_bounds = [1.0] lower_bounds = [0.0] # ------------------------------------- # generate initial coordinates, weights # ------------------------------------- # get a random distribution of points print "generate random points and weights" coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] print "positions: %s" % D # calculate sample range R = spread(D) print "range: %s" % R # select weights randomly in [0,1], then normalize so sum(weights) = 1 wts = random_samples([0],[1], npts)[0] weights = normalize(wts, 0.0, zsum=True) print "weights (when normalized to 0.0): %s" % weights weights = normalize(wts) print "weights (when normalized to 1.0): %s" % weights w = norm(weights) print "norm: %s" % w # calculate sample mean m = mean(D,weights) print "mean: %s" % m print "" # ------------------------------------- # modify coordinates, maintaining mean & range # ------------------------------------- # get new random distribution print "modify positions, maintaining mean and range" coordinates = samplepts(lower_bounds, upper_bounds, npts) D = [i[0] for i in coordinates] # impose a range and mean on the points D = impose_spread(R, D, weights) D = impose_mean(m, D, weights) # print results print "positions: %s" % D R = spread(D) print "range: %s" % R m = mean(D, weights) print "mean: %s" % m print "" # ------------------------------------- # modify weights, maintaining mean & norm # ------------------------------------- # select weights randomly in [0,1] print "modify weights, maintaining mean and range" wts = random_samples([0],[1], npts)[0] # print intermediate results #print "weights: %s" % wts #sm = mean(D, wts) #print "tmp mean: %s" % sm #print "" # impose mean and weight norm on the points D = impose_mean(m, D, wts) DD, weights = impose_weight_norm(D, wts) # print results print "weights: %s" % weights w = norm(weights) print "norm: %s" % w print "positions: %s" % DD R = spread(DD) print "range: %s" % R sm = mean(DD, weights) print "mean: %s" % sm sv = variance(DD, weights) print "var: %s" % sv # ------------------------------------- # modify variance, maintaining mean # ------------------------------------- print "\nmodify variance, maintaining mean" DD = impose_variance(R, DD, weights) sm = mean(DD, weights) print "mean: %s" % sm sv = variance(DD, weights) print "var: %s" % sv