def makePositive(grid, alpha): """ insert full grid points if they are negative and the father node is part of the sparse grid @param grid: @param alpha: """ # copy old sg function jgrid = copyGrid(grid) # evaluate the sparse grid function at all full grid points level = grid.getStorage().getMaxLevel() fg = Grid.createLinearGrid(grid.getDimension()) fg.getGenerator().full(level) # copy the old grid and use it as reference jgs = jgrid.getStorage() fgs = fg.getStorage() # run over all results and check where the function value # is lower than zero cnt = 1 while True: print("run %i: full grid size = %i" % (cnt, fgs.size())) gps = [] # insert those fg points, which are not yet positive values = computeNodalValues(fg, grid, alpha) for i in range(len(values)): gp = fgs.getPoint(i) if values[i] < 0 and not jgs.isContaining(gp): gps += insertPoint(jgrid, gp) gps += insertHierarchicalAncestors(jgrid, gp) jgrid.getStorage().recalcLeafProperty() # 1. compute nodal values for new grid points jnodalValues = computeNodalValues(jgrid, grid, alpha) # 2. set the new ones to zero jgs = jgrid.getStorage() for gp in gps: jnodalValues[jgs.getSequenceNumber(gp)] = 0. # 3. hierarchize jalpha = hierarchize(jgrid, jnodalValues) # stop loop if no points have been added if len(gps) == 0: break # 4. reset values for next loop grid = copyGrid(jgrid) alpha = DataVector(jalpha) cnt += 1 return jgrid, jalpha
def test_2DNormalDist_variance(self): # prepare data U = dists.J( [dists.Normal(2.0, .5, -1, 4), dists.Normal(1.0, .5, -1, 3)]) # U = dists.J([dists.Normal(0.5, .5, -1, 2), # dists.Normal(0.5, .4, -1, 2)]) # define linear transformation trans = JointTransformation() for a, b in U.getBounds(): trans.add(LinearTransformation(a, b)) # get a sparse grid approximation grid = Grid.createPolyGrid(U.getDim(), 10) grid.getGenerator().regular(5) gs = grid.getStorage() # now refine adaptively 5 times p = DataVector(gs.getDimension()) nodalValues = np.ndarray(gs.getSize()) # set function values in alpha for i in range(gs.getSize()): gs.getPoint(i).getStandardCoordinates(p) nodalValues[i] = U.pdf(trans.unitToProbabilistic(p.array())) # hierarchize alpha = hierarchize(grid, nodalValues) # # make positive # alpha_vec = DataVector(alpha) # createOperationMakePositive().makePositive(grid, alpha_vec) # alpha = alpha_vec.array() dist = SGDEdist(grid, alpha, bounds=U.getBounds()) fig = plt.figure() plotDensity2d(U) fig.show() fig = plt.figure() plotSG2d(dist.grid, dist.alpha, addContour=True, show_negative=True, show_grid_points=True) fig.show() print("2d: mean = %g ~ %g" % (U.mean(), dist.mean())) print("2d: var = %g ~ %g" % (U.var(), dist.var())) plt.show()
def test_1DNormalDist_variance(self): # prepare data U = dists.Normal(1, 2, -8, 8) # U = dists.Normal(0.5, .2, 0, 1) # define linear transformation trans = JointTransformation() a, b = U.getBounds() trans.add(LinearTransformation(a, b)) # get a sparse grid approximation grid = Grid.createPolyGrid(U.getDim(), 10) grid.getGenerator().regular(5) gs = grid.getStorage() # now refine adaptively 5 times p = DataVector(gs.getDimension()) nodalValues = np.ndarray(gs.getSize()) # set function values in alpha for i in range(gs.getSize()): gs.getPoint(i).getStandardCoordinates(p) nodalValues[i] = U.pdf(trans.unitToProbabilistic(p.array())) # hierarchize alpha = hierarchize(grid, nodalValues) dist = SGDEdist(grid, alpha, bounds=U.getBounds()) fig = plt.figure() plotDensity1d(U, alpha_value=0.1, mean_label="$\mathbb{E}", interval_label="$\alpha=0.1$") fig.show() fig = plt.figure() plotDensity1d(dist, alpha_value=0.1, mean_label="$\mathbb{E}", interval_label="$\alpha=0.1$") fig.show() print("1d: mean = %g ~ %g" % (U.mean(), dist.mean())) print("1d: var = %g ~ %g" % (U.var(), dist.var())) plt.show()
def discretizeFunction(f, bounds, level=2, hasBorder=False, *args, **kws): # define linear transformation to the unit hyper cube T = JointTransformation() for xlim in bounds: T.add(LinearTransformation(xlim[0], xlim[1])) # create grid dim = len(bounds) # create adequate grid if hasBorder: grid = Grid.createLinearBoundaryGrid(dim) else: grid = Grid.createLinearGrid(dim) # init storage grid.getGenerator().regular(level) gs = grid.getStorage() # discretize on given level p = DataVector(dim) nodalValues = DataVector(gs.getSize()) for i in range(gs.getSize()): gs.getCoordinates(gs.getPoint(i), p) # transform to the right space q = T.unitToProbabilistic(p.array()) # apply the given function nodalValues[i] = float(f(q)) # hierarchize alpha = hierarchize(grid, nodalValues) # estimate the l2 error err = estimateDiscreteL2Error(grid, alpha, f) # TODO: adaptive refinement return grid, alpha, err
def computeCoefficients(jgrid, grid, alpha, f): """ Interpolate function f, which depends on some sparse grid function (grid, alpha) on jgrid @param jgrid: Grid, new discretization @param grid: Grid, old discretization @param alpha: DataVector, surpluses for grid @param f: function, to be interpolated @return: DataVector, surpluses for jgrid """ jgs = jgrid.getStorage() # dehierarchization p = DataVector(jgs.getDimension()) A = DataMatrix(jgs.getSize(), jgs.getDimension()) for i in range(jgs.getSize()): jgs.getCoordinates(jgs.getPoint(i), p) A.setRow(i, p) nodalValues = evalSGFunctionMulti(grid, alpha, A.array()) # apply f to all grid points jnodalValues = DataVector(jgs.getSize()) for i in range(len(nodalValues)): A.getRow(i, p) # print( i, p.array(), nodalValues[i], alpha.min(), alpha.max() ) # if nodalValues[i] < -1e20 or nodalValues[i] > 1e20: # from pysgpp.extensions.datadriven.uq.operations import evalSGFunction, evalSGFunctionMultiVectorized # print( alpha.min(), alpha.max() ) # print( evalSGFunction(grid, alpha, p) ) # print( evalSGFunctionMulti(grid, alpha, DataMatrix([p.array()])) ) # print( evalSGFunctionMultiVectorized(grid, alpha, DataMatrix([p.array()])) ) # import ipdb; ipdb.set_trace() jnodalValues[i] = f(p.array(), nodalValues[i]) jalpha = hierarchize(jgrid, jnodalValues) return jalpha
def setUpClass(cls): super(MonteCarloStrategyTest, cls).setUpClass() builder = ParameterBuilder() up = builder.defineUncertainParameters() up.new().isCalled('x1').withUniformDistribution(0, 1) up.new().isCalled('x2').withUniformDistribution(0, 1) cls.params = builder.andGetResult() cls.numDims = cls.params.getStochasticDim() cls.samples = np.random.random((10000, 1)) cls.grid = Grid.createPolyGrid(cls.numDims, 2) cls.grid.getGenerator().regular(1) gs = cls.grid.getStorage() # interpolate parabola nodalValues = np.zeros(gs.getSize()) x = DataVector(cls.numDims) for i in range(gs.getSize()): gs.getCoordinates(gs.getPoint(i), x) nodalValues[i] = 16 * (1 - x[0]) * (1 - x[1]) cls.alpha = hierarchize(cls.grid, nodalValues)
def interpolateProduct(grid1, alpha1, grid2, alpha2, grid_result): nodalValues1 = dehierarchizeOnNewGrid(grid_result, grid1, alpha1) nodalValues2 = dehierarchizeOnNewGrid(grid_result, grid2, alpha2) nodalValues1 *= nodalValues2 return hierarchize(grid_result, nodalValues1)
def computeBilinearFormEntry(self, gs, gpi, basisi, gpj, basisj, d): # if not, compute it ans = 1 err = 0. # interpolating 1d sparse grid ngrid = Grid.createPolyBoundaryGrid(1, 2) ngrid.getGenerator().regular(2) ngs = ngrid.getStorage() nodalValues = DataVector(ngs.getSize()) for d in range(gpi.getDimension()): # get level index lid, iid = gpi.getLevel(d), gpi.getIndex(d) ljd, ijd = gpj.getLevel(d), gpj.getIndex(d) # compute left and right boundary of the support of both # basis functions xlowi, xhighi = getBoundsOfSupport(gs, lid, iid) xlowj, xhighj = getBoundsOfSupport(gs, ljd, ijd) xlow = max(xlowi, xlowj) xhigh = min(xhighi, xhighj) # same level, different index if lid == ljd and iid != ijd and lid > 0: return 0., 0. # the support does not overlap elif lid != ljd and xlow >= xhigh: return 0., 0. else: # ---------------------------------------------------- # do the 1d interpolation ... # define transformation function T = LinearTransformation(xlow, xhigh) for k in range(ngs.getSize()): x = ngs.getCoordinate(ngs.getPoint(k), 0) x = T.unitToProbabilistic(x) nodalValues[k] = basisi.eval(lid, iid, x) * \ basisj.eval(ljd, ijd, x) # ... by hierarchization v = hierarchize(ngrid, nodalValues) # discretize the following function def f(x, y): xp = T.unitToProbabilistic(x) return float(y * self._U[d].pdf(xp)) # sparse grid quadrature g, w, err1d = discretize(ngrid, v, f, refnums=0, level=5, useDiscreteL2Error=False) s = T.vol() * doQuadrature(g, w) # fig = plt.figure() # plotSG1d(ngrid, v) # x = np.linspace(xlow, ub, 100) # plt.plot(np.linspace(0, 1, 100), U[d].pdf(x)) # fig.show() # fig = plt.figure() # plotSG1d(g, w) # x = np.linspace(0, 1, 100) # plt.plot(x, # [evalSGFunction(ngrid, v, DataVector([xi])) * U[d].pdf(T.unitToProbabilistic(xi)) for xi in x]) # fig.show() # plt.show() # compute the integral of it # ---------------------------------------------------- ans *= s err += err1d[1] return ans, err
def computeBilinearFormEntry(self, gpi, basisi, gpj, basisj): # check if this entry already exists for key in [self.getKey(gpi, gpj), self.getKey(gpj, gpi)]: if key in self._map: return self._map[key] # if not, compute it ans = 1 err = 0. # interpolating 1d sparse grid ngrid = Grid.createPolyBoundaryGrid(1, 2) ngrid.createGridGenerator().regular(2) ngs = ngrid.getStorage() nodalValues = DataVector(ngs.size()) for d in xrange(gpi.dim()): # get level index lid, iid = gpi.getLevel(d), gpi.getIndex(d) ljd, ijd = gpj.getLevel(d), gpj.getIndex(d) # compute left and right boundary of the support of both # basis functions xlowi, xhighi = self.getBounds(lid, iid) xlowj, xhighj = self.getBounds(ljd, ijd) xlow = max(xlowi, xlowj) xhigh = min(xhighi, xhighj) # same level, different index if lid == ljd and iid != ijd and lid > 0: return 0., 0. # the support does not overlap elif lid != ljd and xlow >= xhigh: return 0., 0. else: # ---------------------------------------------------- # do the 1d interpolation ... # define transformation function T = LinearTransformation(xlow, xhigh) for k in xrange(ngs.size()): x = ngs.get(k).getCoord(0) x = T.unitToProbabilistic(x) nodalValues[k] = basisi.eval(lid, iid, x) * \ basisj.eval(ljd, ijd, x) # ... by hierarchization v = hierarchize(ngrid, nodalValues) # discretize the following function def f(x, y): xp = T.unitToProbabilistic(x) return float(y * self._U[d].pdf(xp)) # sparse grid quadrature g, w, err1d = discretize(ngrid, v, f, refnums=0, level=5, useDiscreteL2Error=False) s = T.vol() * doQuadrature(g, w) # fig = plt.figure() # plotSG1d(ngrid, v) # x = np.linspace(xlow, ub, 100) # plt.plot(np.linspace(0, 1, 100), U[d].pdf(x)) # fig.show() # fig = plt.figure() # plotSG1d(g, w) # x = np.linspace(0, 1, 100) # plt.plot(x, # [evalSGFunction(ngrid, v, DataVector([xi])) * U[d].pdf(T.unitToProbabilistic(xi)) for xi in x]) # fig.show() # plt.show() # compute the integral of it # ---------------------------------------------------- ans *= s err += err1d[1] return ans, err