コード例 #1
0
ファイル: sparse_grid.py プロジェクト: jsgphd/Sparse-Grids
def getIntegral(grid, level, index):
    # create new grid
    if grid.getType() in [LinearBoundary, LinearL0Boundary]:
        return np.power(2., -max(1, level))
    elif grid.getType() == Linear:
        # # employ 4/3 rule
        # if gp.isLeaf():
        #     q *= 4. / 3.
        return np.power(2., -level)
    elif grid.getType() == Poly:
        return getBasis(grid).getIntegral(level, index)
    elif grid.getType() == PolyBoundary:
        return getBasis(grid).getIntegral(level, index)
    else:
        raise AttributeError('unsupported grid type %s' % grid.getType())
コード例 #2
0
def getIntegral(grid, level, index):
    # create new grid
    if grid.getType() in [LinearBoundary, LinearL0Boundary]:
        return np.power(2., -max(1, level))
    elif grid.getType() == Linear:
        # # employ 4/3 rule
        # if gp.isLeaf():
        #     q *= 4. / 3.
        return np.power(2., -level)
    elif grid.getType() == Poly:
        return getBasis(grid).getIntegral(level, index)
    elif grid.getType() == PolyBoundary:
        return getBasis(grid).getIntegral(level, index)
    else:
        raise AttributeError('unsupported grid type %s' % grid.getType())
コード例 #3
0
ファイル: sparse_grid.py プロジェクト: pfluegdk/SGpp
def getIntegral(grid, level, index):
    # create new grid
    if grid.getType() in [
            GridType_LinearBoundary, GridType_LinearTruncatedBoundary,
            GridType_LinearL0Boundary
    ]:
        return np.power(2., -max(1, level))
    elif grid.getType() == GridType_Linear:
        # # employ 4/3 rule
        # if gp.isLeaf():
        #     q *= 4. / 3.
        return np.power(2., -level)
    elif grid.getType() in [
            GridType_ModLinear, GridType_LinearClenshawCurtis,
            GridType_LinearClenshawCurtisBoundary,
            GridType_ModLinearClenshawCurtis, GridType_Poly,
            GridType_PolyBoundary, GridType_ModPoly,
            GridType_PolyClenshawCurtis, GridType_PolyClenshawCurtisBoundary,
            GridType_ModPolyClenshawCurtis, GridType_Bspline,
            GridType_BsplineBoundary, GridType_ModBspline,
            GridType_BsplineClenshawCurtis, GridType_ModBsplineClenshawCurtis
    ]:
        return getBasis(grid).getIntegral(level, index)
    else:
        raise AttributeError('unsupported grid type %s' % grid.getType())
コード例 #4
0
def computeBilinearFormQuad(grid, U):
    gs = grid.getStorage()
    basis = getBasis(grid)
    A = DataMatrix(gs.size(), gs.size())

    level = DataMatrix(gs.size(), gs.dim())
    index = DataMatrix(gs.size(), gs.dim())
    gs.getLevelIndexArraysForEval(level, index)

    s = np.ndarray(gs.dim(), dtype='float')
    # run over all rows
    for i in xrange(gs.size()):
        gpi = gs.get(i)
        # run over all columns
        for j in xrange(i, gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.get(j)
            for d in xrange(gs.dim()):
                # get level index
                lid, iid = level.get(i, d), index.get(i, d)
                ljd, ijd = level.get(j, d), index.get(j, d)

                # compute left and right boundary of the support of both
                # basis functions
                lb = max([(iid - 1) / lid, (ijd - 1) / ljd])
                ub = min([(iid + 1) / lid, (ijd + 1) / ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    lid, iid = gpi.getLevel(d), int(iid)
                    ljd, ijd = gpj.getLevel(d), int(ijd)

                    # ----------------------------------------------------
                    # use scipy for integration

                    def f(x):
                        return basis.eval(lid, iid, x) * \
                            basis.eval(ljd, ijd, x) * \
                            U[d].pdf(x)

                    s[d], _ = quad(f, lb, ub, epsabs=1e-8)
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            A.set(j, i, A.get(i, j))

    return A
コード例 #5
0
def computeBilinearFormQuad(grid, U):
    gs = grid.getStorage()
    basis = getBasis(grid)
    A = DataMatrix(gs.size(), gs.size())

    level = DataMatrix(gs.size(), gs.dim())
    index = DataMatrix(gs.size(), gs.dim())
    gs.getLevelIndexArraysForEval(level, index)

    s = np.ndarray(gs.dim(), dtype='float')
    # run over all rows
    for i in xrange(gs.size()):
        gpi = gs.get(i)
        # run over all columns
        for j in xrange(i, gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.get(j)
            for d in xrange(gs.dim()):
                # get level index
                lid, iid = level.get(i, d), index.get(i, d)
                ljd, ijd = level.get(j, d), index.get(j, d)

                # compute left and right boundary of the support of both
                # basis functions
                lb = max([(iid - 1) / lid, (ijd - 1) / ljd])
                ub = min([(iid + 1) / lid, (ijd + 1) / ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    lid, iid = gpi.getLevel(d), int(iid)
                    ljd, ijd = gpj.getLevel(d), int(ijd)
                    # ----------------------------------------------------
                    # use scipy for integration

                    def f(x):
                        return basis.eval(lid, iid, x) * \
                            basis.eval(ljd, ijd, x) * \
                            U[d].pdf(x)

                    s[d], _ = quad(f, lb, ub, epsabs=1e-8)
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            A.set(j, i, A.get(i, j))

    return A
コード例 #6
0
def computeBFQuad(grid, U, admissibleSet, n=100):
    """
    @param grid: Grid
    @param U: list of distributions
    @param admissibleSet: AdmissibleSet
    @param n: int, number of MC samples
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    A = DataMatrix(admissibleSet.getSize(), gs.size())
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.dim(), dtype='float')
    # run over all rows
    for i, gpi in enumerate(admissibleSet.values()):
        # run over all columns
        for j in xrange(gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.get(j)
            for d in xrange(gs.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
                xlow = max([(iid - 1) * 2 ** -lid, (ijd - 1) * 2 ** -ljd])
                xhigh = min([(iid + 1) * 2 ** -lid, (ijd + 1) * 2 ** -ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and xlow >= xhigh:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # use scipy for integration
                    def f(x):
                        return basis.eval(lid, iid, x) * \
                            basis.eval(ljd, ijd, x) * \
                            U[d].pdf(x)

                    s[d], _ = quad(f, xlow, xhigh, epsabs=1e-8)
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            if gs.seq(gpi) == j:
                b[i] = A.get(i, j)
    return A, b
コード例 #7
0
def computeBFQuad(grid, U, admissibleSet, n=100):
    """
    @param grid: Grid
    @param U: list of distributions
    @param admissibleSet: AdmissibleSet
    @param n: int, number of MC samples
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    A = DataMatrix(admissibleSet.getSize(), gs.size())
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.getDimension(), dtype='float')
    # run over all rows
    for i, gpi in enumerate(admissibleSet.values()):
        # run over all columns
        for j in range(gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.getPoint(j)
            for d in range(gs.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
                xlow = max([(iid - 1) * 2 ** -lid, (ijd - 1) * 2 ** -ljd])
                xhigh = min([(iid + 1) * 2 ** -lid, (ijd + 1) * 2 ** -ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and xlow >= xhigh:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # use scipy for integration
                    def f(x):
                        return basis.eval(lid, iid, x) * \
                            basis.eval(ljd, ijd, x) * \
                            U[d].pdf(x)

                    s[d], _ = quad(f, xlow, xhigh, epsabs=1e-8)
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            if gs.getSequenceNumber(gpi) == j:
                b[i] = A.get(i, j)
    return A, b
コード例 #8
0
 def computeLinearForm(self, grid):
     """
     Compute bilinear form for the current grid
     @param grid: Grid
     @return numpy array
     """
     gs = grid.getStorage()
     basis = getBasis(grid)
     v = np.ndarray(gs.size())
     err = 0.
     # run over all rows
     for i in range(gs.size()):
         gpi = gs.getPoint(i)
         # compute bilinear form for one entry
         v[i], erri = self.getLinearFormEntry(gs, gpi, basis)
         err += erri
     return v, err
コード例 #9
0
 def computeLinearForm(self, grid):
     """
     Compute bilinear form for the current grid
     @param grid: Grid
     @return DataVector
     """
     gs = grid.getStorage()
     basis = getBasis(grid)
     v = DataVector(gs.size())
     err = 0.
     # run over all rows
     for i in xrange(gs.size()):
         gpi = gs.get(i)
         # compute bilinear form for one entry
         v[i], erri = self.getLinearFormEntry(gpi, basis)
         err += erri
     return v, err
コード例 #10
0
 def computeLinearForm(self, grid):
     """
     Compute bilinear form for the current grid
     @param grid: Grid
     @return DataVector
     """
     gs = grid.getStorage()
     basis = getBasis(grid)
     v = DataVector(gs.size())
     err = 0.
     # run over all rows
     for i in xrange(gs.size()):
         gpi = gs.get(i)
         # compute bilinear form for one entry
         v[i], erri = self.getLinearFormEntry(gpi, basis)
         err += erri
     return v, err
コード例 #11
0
def computeExpectationValueEstimation(grid, U, admissibleSet):
    """
    Compute
    (b)_i = \int phi_i dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @param admissibleSet: AdmissibleSet
    @return: DataVector
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.dim(), dtype='float')

    # run over all rows
    p = DataVector(gs.dim())
    for i, gpi in enumerate(admissibleSet.values()):
        gpi.getCoords(p)
        for d in xrange(gs.dim()):
            # get level index
            lid, iid = gpi.getLevel(d), gpi.getIndex(d)
            xlow = (iid - 1) * 2**-lid
            xhigh = (iid + 1) * 2**-lid

            # ----------------------------------------------------
            # use scipy integration
            def f(x):
                return basis.eval(lid, iid, x) * U[d].pdf(x)

            s[d], _ = quad(f, xlow, xhigh, epsabs=1e-8)
            # ----------------------------------------------------
        b[i] = float(np.prod(s))
    return b
コード例 #12
0
def computeExpectationValueEstimation(grid, U, admissibleSet):
    """
    Compute
    (b)_i = \int phi_i dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @param admissibleSet: AdmissibleSet
    @return: DataVector
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.dim(), dtype='float')

    # run over all rows
    p = DataVector(gs.dim())
    for i, gpi in enumerate(admissibleSet.values()):
        gpi.getCoords(p)
        for d in xrange(gs.dim()):
            # get level index
            lid, iid = gpi.getLevel(d), gpi.getIndex(d)
            xlow = (iid - 1) * 2 ** -lid
            xhigh = (iid + 1) * 2 ** -lid

            # ----------------------------------------------------
            # use scipy integration
            def f(x):
                return basis.eval(lid, iid, x) * U[d].pdf(x)
            s[d], _ = quad(f, xlow, xhigh, epsabs=1e-8)
            # ----------------------------------------------------
        b[i] = float(np.prod(s))
    return b
コード例 #13
0
def computeBilinearForm(grid, U):
    """
    Compute bilinear form
    (A)_ij = \int phi_i phi_j dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @return: DataMatrix
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    ngrid = Grid.createPolyBoundaryGrid(1, 2)
    # ngrid = Grid.createLinearBoundaryGrid(1)
    ngrid.getGenerator().regular(gs.getMaxLevel() + 1)
    ngs = ngrid.getStorage()
    nodalValues = DataVector(ngs.size())

    level = DataMatrix(gs.size(), gs.getDimension())
    index = DataMatrix(gs.size(), gs.getDimension())
    gs.getLevelIndexArraysForEval(level, index)

    A = DataMatrix(gs.size(), gs.size())
    s = np.ndarray(gs.getDimension(), dtype='float')

    # run over all rows
    for i in range(gs.size()):
        gpi = gs.getPoint(i)
        # run over all columns
        for j in range(i, gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.getPoint(j)
            # run over all dimensions
            for d in range(gs.getDimension()):
                # get level index
                lid, iid = level.get(i, d), index.get(i, d)
                ljd, ijd = level.get(j, d), index.get(j, d)

                # compute left and right boundary of the support of both
                # basis functions
                lb = max([((iid - 1) / lid), ((ijd - 1) / ljd)])
                ub = min([((iid + 1) / lid), ((ijd + 1) / ljd)])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # do the 1d interpolation ...
                    lid, iid = gpi.getLevel(d), int(iid)
                    ljd, ijd = gpj.getLevel(d), int(ijd)
                    for k in range(ngs.size()):
                        x = ngs.getCoordinate(ngs.getPoint(k), 0)
                        nodalValues[k] = max(0, basis.eval(lid, iid, x)) * \
                            max(0, basis.eval(ljd, ijd, x))
                    # ... by hierarchization
                    v = hierarchize(ngrid, nodalValues)

                    def f(x, y):
                        return float(y * U[d].pdf(x[0]))

                    g, w, _ = discretize(ngrid, v, f, refnums=0)
                    # compute the integral of it
                    s[d] = doQuadrature(g, w)
                    # ----------------------------------------------------
            # store result in matrix
            A.set(i, j, float(np.prod(s)))
            A.set(j, i, A.get(i, j))

    return A
コード例 #14
0
def computeBF(grid, U, admissibleSet):
    """
    Compute bilinear form
    (A)_ij = \int phi_i phi_j dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @param admissibleSet: AdmissibleSet
    @return: DataMatrix
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    ngrid = Grid.createPolyBoundaryGrid(1, 2)
    ngrid.createGridGenerator().regular(2)
    ngs = ngrid.getStorage()
    nodalValues = DataVector(ngs.size())

    A = DataMatrix(admissibleSet.getSize(), gs.size())
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.dim(), dtype='float')

#     # pre compute basis evaluations
#     basis_eval = {}
#     for li in xrange(1, gs.getMaxLevel() + 1):
#         for i in xrange(1, 2 ** li + 1, 2):
#             # add value with it self
#             x = 2 ** -li * i
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#
#             # left side
#             x = 2 ** -(li + 1) * (2 * i - 1)
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#             # right side
#             x = 2 ** -(li + 1) * (2 * i + 1)
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#
#             # add values for hierarchical lower nodes
#             for lj in xrange(li + 1, gs.getMaxLevel() + 1):
#                 a = 2 ** (lj - li)
#                 j = a * i - a + 1
#                 while j < a * i + a:
#                     # center
#                     x = 2 ** -lj * j
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     # left side
#                     x = 2 ** -(lj + 1) * (2 * j - 1)
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     # right side
#                     x = 2 ** -(lj + 1) * (2 * j + 1)
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     j += 2
#
#     print len(basis_eval)

    # run over all rows
    for i, gpi in enumerate(admissibleSet.values()):
        # run over all columns
        for j in xrange(gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.get(j)
            for d in xrange(gs.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
                lb = max([(iid - 1) * 2 ** -lid, (ijd - 1) * 2 ** -ljd])
                ub = min([(iid + 1) * 2 ** -lid, (ijd + 1) * 2 ** -ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # do the 1d interpolation ...
                    # define transformation function
                    T = LinearTransformation(lb, ub)
                    for k in xrange(ngs.size()):
                        x = ngs.get(k).getCoord(0)
                        x = T.unitToProbabilistic(x)
                        nodalValues[k] = basis.eval(lid, iid, x) * \
                            basis.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 * U[d].pdf(xp))

                    # sparse grid quadrature
                    g, w, _ = discretize(ngrid, v, f, refnums=0, level=5,
                                         useDiscreteL2Error=False)
                    s[d] = doQuadrature(g, w) * (ub - lb)
#                     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
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            if gs.seq(gpi) == j:
                b[i] = A.get(i, j)
    return A, b
コード例 #15
0
def __doMarginalize(grid, alpha, dd, measure=None):
    gs = grid.getStorage()

    dim = gs.dim()

    if dim < 2:
        raise AttributeError("The grid has to be at least of dimension 2")

    if dd >= dim:
        raise AttributeError("The grid has only %i dimensions, so I can't \
                             integrate over %i" % (dim, dd))

    # create new grid
    n_dim = dim - 1
    n_grid = createGrid(grid, n_dim)
    n_gs = n_grid.getStorage()

    # insert grid points
    n_gp = HashGridIndex(n_dim)
    for i in xrange(gs.size()):
        gp = gs.get(i)
        for d in range(dim):
            if d == dd:
                # omit marginalization direction
                continue
            elif d < dd:
                n_gp.set(d, gp.getLevel(d), gp.getIndex(d))
            else:
                n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d))

        # insert grid point
        if not n_gs.has_key(n_gp):
            n_gs.insert(n_gp)

    n_gs.recalcLeafProperty()

    # create coefficient vector
    n_alpha = DataVector(n_gs.size())
    n_alpha.setAll(0.0)

    # set function values for n_alpha
    for i in xrange(gs.size()):
        gp = gs.get(i)

        for d in range(dim):
            if d == dd:
                dd_level = gp.getLevel(d)
                dd_index = gp.getIndex(d)
            elif d < dd:
                n_gp.set(d, gp.getLevel(d), gp.getIndex(d))
            else:
                n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d))

        if not n_gs.has_key(n_gp):
            raise Exception("This should not happen!")

        # compute the integral of the given basis
        if measure is None:
            q, err = getIntegral(grid, dd_level, dd_index), 0.
        else:
            dist, trans = measure[0][dd], measure[1][dd]
            lf = LinearGaussQuadratureStrategy([dist], [trans])
            basis = getBasis(grid)
            gpdd = HashGridIndex(1)
            gpdd.set(0, dd_level, dd_index)
            q, err = lf.computeLinearFormByList([gpdd], basis)
            q = q[0]

        # search for the corresponding index
        j = n_gs.seq(n_gp)
        n_alpha[j] += alpha[i] * q

    return n_grid, n_alpha, err
コード例 #16
0
def computeBilinearForm(grid, U):
    """
    Compute bilinear form
    (A)_ij = \int phi_i phi_j dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @return: DataMatrix
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    ngrid = Grid.createPolyBoundaryGrid(1, 2)
    # ngrid = Grid.createLinearBoundaryGrid(1)
    ngrid.createGridGenerator().regular(gs.getMaxLevel() + 1)
    ngs = ngrid.getStorage()
    nodalValues = DataVector(ngs.size())

    level = DataMatrix(gs.size(), gs.dim())
    index = DataMatrix(gs.size(), gs.dim())
    gs.getLevelIndexArraysForEval(level, index)

    A = DataMatrix(gs.size(), gs.size())
    s = np.ndarray(gs.dim(), dtype='float')

    # run over all rows
    for i in xrange(gs.size()):
        gpi = gs.get(i)
        # run over all columns
        for j in xrange(i, gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.get(j)
            # run over all dimensions
            for d in xrange(gs.dim()):
                # get level index
                lid, iid = level.get(i, d), index.get(i, d)
                ljd, ijd = level.get(j, d), index.get(j, d)

                # compute left and right boundary of the support of both
                # basis functions
                lb = max([(iid - 1) / lid, (ijd - 1) / ljd])
                ub = min([(iid + 1) / lid, (ijd + 1) / ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # do the 1d interpolation ...
                    lid, iid = gpi.getLevel(d), int(iid)
                    ljd, ijd = gpj.getLevel(d), int(ijd)
                    for k in xrange(ngs.size()):
                        x = ngs.get(k).getCoord(0)
                        nodalValues[k] = max(0, basis.eval(lid, iid, x)) * \
                            max(0, basis.eval(ljd, ijd, x))
                    # ... by hierarchization
                    v = hierarchize(ngrid, nodalValues)

                    def f(x, y):
                        return float(y * U[d].pdf(x[0]))

                    g, w, _ = discretize(ngrid, v, f, refnums=0)
                    # compute the integral of it
                    s[d] = doQuadrature(g, w)
                    # ----------------------------------------------------
            # store result in matrix
            A.set(i, j, float(np.prod(s)))
            A.set(j, i, A.get(i, j))

    return A
コード例 #17
0
ファイル: marginalization.py プロジェクト: pfluegdk/SGpp
def __doMarginalize(grid, alpha, linearForm, dd, measure=None):
    gs = grid.getStorage()

    dim = gs.getDimension()

    if dim < 2:
        raise AttributeError("The grid has to be at least of dimension 2")

    if dd >= dim:
        raise AttributeError("The grid has only %i dimensions, so I can't \
                             integrate over %i" % (dim, dd))

    # create new grid
    n_dim = dim - 1
    n_grid = createGrid(grid, n_dim)
    n_gs = n_grid.getStorage()

    # insert grid points
    n_gp = HashGridPoint(n_dim)
    for i in range(gs.getSize()):
        gp = gs.getPoint(i)
        for d in range(dim):
            if d == dd:
                # omit marginalization direction
                continue
            elif d < dd:
                n_gp.set(d, gp.getLevel(d), gp.getIndex(d))
            else:
                n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d))

        # insert grid point
        if not n_gs.isContaining(n_gp):
            n_gs.insert(n_gp)

    n_gs.recalcLeafProperty()

    # create coefficient vector
    n_alpha = np.zeros(n_gs.getSize())

    basis = getBasis(grid)
    # set function values for n_alpha
    for i in range(gs.getSize()):
        gp = gs.getPoint(i)

        for d in range(dim):
            if d == dd:
                dd_level = gp.getLevel(d)
                dd_index = gp.getIndex(d)
            elif d < dd:
                n_gp.set(d, gp.getLevel(d), gp.getIndex(d))
            else:
                n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d))

        if not n_gs.isContaining(n_gp):
            raise Exception("This should not happen!")

        # compute the integral of the given basis
        if measure is None:
            q, err = getIntegral(grid, dd_level, dd_index), 0.
        else:
            dist, trans = measure[0][dd], measure[1][dd]
            linearForm.setDistributionAndTransformation([dist], [trans])
            gpdd = HashGridPoint(1)
            gpdd.set(0, dd_level, dd_index)
            q, err = linearForm.computeLinearFormByList(gs, [gpdd], basis)
            q = q[0] * trans.vol()
            err *= trans.vol()

        # search for the corresponding index
        j = n_gs.getSequenceNumber(n_gp)
        n_alpha[j] += alpha[i] * q

    return n_grid, n_alpha, err
コード例 #18
0
def computeBF(grid, U, admissibleSet):
    """
    Compute bilinear form
    (A)_ij = \int phi_i phi_j dU(x)
    on measure U, which is in this case supposed to be a lebesgue measure.
    @param grid: Grid, sparse grid
    @param U: list of distributions, Lebeasgue measure
    @param admissibleSet: AdmissibleSet
    @return: DataMatrix
    """
    gs = grid.getStorage()
    basis = getBasis(grid)
    # interpolate phi_i phi_j on sparse grid with piecewise polynomial SG
    # the product of two piecewise linear functions is a piecewise
    # polynomial one of degree 2.
    ngrid = Grid.createPolyBoundaryGrid(1, 2)
    ngrid.getGenerator().regular(2)
    ngs = ngrid.getStorage()
    nodalValues = DataVector(ngs.size())

    A = DataMatrix(admissibleSet.getSize(), gs.size())
    b = DataVector(admissibleSet.getSize())
    s = np.ndarray(gs.getDimension(), dtype='float')

#     # pre compute basis evaluations
#     basis_eval = {}
#     for li in xrange(1, gs.getMaxLevel() + 1):
#         for i in xrange(1, 2 ** li + 1, 2):
#             # add value with it self
#             x = 2 ** -li * i
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#
#             # left side
#             x = 2 ** -(li + 1) * (2 * i - 1)
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#             # right side
#             x = 2 ** -(li + 1) * (2 * i + 1)
#             basis_eval[(li, i, li, i, x)] = basis.eval(li, i, x) * \
#                 basis.eval(li, i, x)
#
#             # add values for hierarchical lower nodes
#             for lj in xrange(li + 1, gs.getMaxLevel() + 1):
#                 a = 2 ** (lj - li)
#                 j = a * i - a + 1
#                 while j < a * i + a:
#                     # center
#                     x = 2 ** -lj * j
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     # left side
#                     x = 2 ** -(lj + 1) * (2 * j - 1)
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     # right side
#                     x = 2 ** -(lj + 1) * (2 * j + 1)
#                     basis_eval[(li, i, lj, j, x)] = basis.eval(li, i, x) * \
#                         basis.eval(lj, j, x)
#                     basis_eval[(lj, j, li, i, x)] = basis_eval[(li, i, lj, j, x)]
#                     j += 2
#
#     print len(basis_eval)

    # run over all rows
    for i, gpi in enumerate(admissibleSet.values()):
        # run over all columns
        for j in range(gs.size()):
            # print "%i/%i" % (i * gs.size() + j + 1, gs.size() ** 2)
            gpj = gs.getPoint(j)
            for d in range(gs.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
                lb = max([(iid - 1) * 2 ** -lid, (ijd - 1) * 2 ** -ljd])
                ub = min([(iid + 1) * 2 ** -lid, (ijd + 1) * 2 ** -ljd])

                # same level, different index
                if lid == ljd and iid != ijd:
                    s[d] = 0.
                # the support does not overlap
                elif lid != ljd and lb >= ub:
                    s[d] = 0.
                else:
                    # ----------------------------------------------------
                    # do the 1d interpolation ...
                    # define transformation function
                    T = LinearTransformation(lb, ub)
                    for k in range(ngs.size()):
                        x = ngs.getCoordinate(ngs.getPoint(k), 0)
                        x = T.unitToProbabilistic(x)
                        nodalValues[k] = basis.eval(lid, iid, x) * \
                            basis.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 * U[d].pdf(xp))

                    # sparse grid quadrature
                    g, w, _ = discretize(ngrid, v, f, refnums=0, level=5,
                                         useDiscreteL2Error=False)
                    s[d] = doQuadrature(g, w) * (ub - lb)
#                     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
                    # ----------------------------------------------------
            A.set(i, j, float(np.prod(s)))
            if gs.getSequenceNumber(gpi) == j:
                b[i] = A.get(i, j)
    return A, b