Ejemplo n.º 1
0
class MeanSquaredOptRanking(Ranking):
    def __init__(self):
        super(self.__class__, self).__init__()
        self._linearForm = LinearGaussQuadratureStrategy()
        self._bilinearForm = BilinearGaussQuadratureStrategy()

    def update(self, grid, v, gpi, params, *args, **kws):
        """
        Compute ranking for variance estimation

        \argmax_{i \in \A} | v_i (2 A_i v_i - v_i b_i) |

        @param grid: Grid grid
        @param v: numpy array coefficients
        @param admissibleSet: AdmissibleSet
        """
        # update the quadrature operations
        self._linearForm.setGridType(grid.getType())
        self._bilinearForm.setGridType(grid.getType())
        U = params.getDistributions()
        T = params.getTransformations()
        self._linearForm.setDistributionAndTransformation(U, T)
        self._bilinearForm.setDistributionAndTransformation(U, T)

        # prepare list of grid points
        gs = grid.getStorage()
        gpsi = [None] * gs.getSize()
        for i in range(gs.getSize()):
            gpsi[i] = gs.getPoint(i)

        # compute stiffness matrix for next run
        basis = getBasis(grid)
        A, _ = self._bilinearForm.computeBilinearFormByList(
            gs, [gpi], basis, gpsi, basis)

        # update the ranking
        ix = gs.getSequenceNumber(gpi)
        return np.abs(v[ix] * (2 * np.dot(A, v) - v[ix] * A[0, ix]))
Ejemplo n.º 2
0
 def __init__(self):
     super(self.__class__, self).__init__()
     self._linearForm = LinearGaussQuadratureStrategy()
     self._bilinearForm = BilinearGaussQuadratureStrategy()
Ejemplo n.º 3
0
    def test_variance_opt(self):
        # parameters
        level = 4

        gridConfig = RegularGridConfiguration()
        gridConfig.type_ = GridType_Linear
        gridConfig.maxDegree_ = 2  # max(2, level + 1)
        gridConfig.boundaryLevel_ = 0
        gridConfig.dim_ = 2

        # mu = np.ones(gridConfig.dim_) * 0.5
        # cov = np.diag(np.ones(gridConfig.dim_) * 0.1 / 10.)
        # dist = MultivariateNormal(mu, cov, 0, 1)  # problems in 3d/l2
        # f = lambda x: dist.pdf(x)
        def f(x):
            return np.prod(4 * x * (1 - x))

        def f(x):
            return np.arctan(
                50 *
                (x[0] - .35)) + np.pi / 2 + 4 * x[1]**3 + np.exp(x[0] * x[1] -
                                                                 1)

        # --------------------------------------------------------------------------
        # define parameters
        paramsBuilder = ParameterBuilder()
        up = paramsBuilder.defineUncertainParameters()
        for idim in range(gridConfig.dim_):
            up.new().isCalled("x_%i" % idim).withBetaDistribution(3, 3, 0, 1)
        params = paramsBuilder.andGetResult()
        U = params.getIndependentJointDistribution()
        T = params.getJointTransformation()
        # --------------------------------------------------------------------------

        grid = pysgpp.Grid.createGrid(gridConfig)
        gs = grid.getStorage()
        grid.getGenerator().regular(level)
        nodalValues = np.ndarray(gs.getSize())

        p = DataVector(gs.getDimension())
        for i in range(gs.getSize()):
            gp = gs.getCoordinates(gs.getPoint(i), p)
            nodalValues[i] = f(p.array())

        # --------------------------------------------------------------------------
        alpha_vec = pysgpp.DataVector(nodalValues)
        pysgpp.createOperationHierarchisation(grid).doHierarchisation(
            alpha_vec)
        alpha = alpha_vec.array()
        checkInterpolation(grid, alpha, nodalValues, epsilon=1e-13)
        # --------------------------------------------------------------------------

        quad = AnalyticEstimationStrategy()
        mean = quad.mean(grid, alpha, U, T)["value"]
        var = quad.var(grid, alpha, U, T, mean)["value"]

        if self.verbose:
            print("mean: %g" % mean)
            print("var : %g" % var)
            print("-" * 80)

        # drop arbitrary grid points and compute the mean and the variance
        # -> just use leaf nodes for simplicity
        bilinearForm = BilinearGaussQuadratureStrategy(grid.getType())
        bilinearForm.setDistributionAndTransformation(U.getDistributions(),
                                                      T.getTransformations())
        linearForm = LinearGaussQuadratureStrategy(grid.getType())
        linearForm.setDistributionAndTransformation(U.getDistributions(),
                                                    T.getTransformations())

        i = np.random.randint(0, gs.getSize())
        gpi = gs.getPoint(i)
        # --------------------------------------------------------------------------
        # check refinement criterion
        ranking = ExpectationValueOptRanking()
        mean_rank = ranking.rank(grid, gpi, alpha, params)
        if self.verbose:
            print("rank mean: %g" % (mean_rank, ))
        # --------------------------------------------------------------------------
        # check refinement criterion
        ranking = VarianceOptRanking()
        var_rank = ranking.rank(grid, gpi, alpha, params)
        if self.verbose:
            print("rank var:  %g" % (var_rank, ))
        # --------------------------------------------------------------------------
        # remove one grid point and update coefficients
        toBeRemoved = IndexList()
        toBeRemoved.push_back(i)
        ixs = gs.deletePoints(toBeRemoved)
        gpsj = []
        new_alpha = np.ndarray(gs.getSize())
        for j in range(gs.getSize()):
            new_alpha[j] = alpha[ixs[j]]
            gpsj.append(gs.getPoint(j))
        # --------------------------------------------------------------------------
        # compute the mean and the variance of the new grid
        mean_trunc = quad.mean(grid, new_alpha, U, T)["value"]
        var_trunc = quad.var(grid, new_alpha, U, T, mean_trunc)["value"]
        basis = getBasis(grid)

        # compute the covariance
        A, _ = bilinearForm.computeBilinearFormByList(gs, [gpi], basis, gpsj,
                                                      basis)
        b, _ = linearForm.computeLinearFormByList(gs, gpsj, basis)

        mean_uwi_phii = np.dot(new_alpha, A[0, :])
        mean_phii, _ = linearForm.getLinearFormEntry(gs, gpi, basis)
        mean_uwi = np.dot(new_alpha, b)
        cov_uwi_phii = mean_uwi_phii - mean_phii * mean_uwi

        # compute the variance of phi_i
        firstMoment, _ = linearForm.getLinearFormEntry(gs, gpi, basis)
        secondMoment, _ = bilinearForm.getBilinearFormEntry(
            gs, gpi, basis, gpi, basis)
        var_phii = secondMoment - firstMoment**2

        # update the ranking
        var_estimated = var_trunc + alpha[i]**2 * var_phii + 2 * alpha[
            i] * cov_uwi_phii

        mean_diff = np.abs(mean_trunc - mean)
        var_diff = np.abs(var_trunc - var)

        if self.verbose:
            print("-" * 80)
            print("diff: |var - var_estimated| = %g" %
                  (np.abs(var - var_estimated), ))
            print("diff: |var - var_trunc|     = %g = %g = var opt ranking" %
                  (var_diff, var_rank))
            print("diff: |mean - mean_trunc|   = %g = %g = mean opt ranking" %
                  (mean_diff, mean_rank))

        self.assertTrue(np.abs(var - var_estimated) < 1e-14)
        self.assertTrue(np.abs(mean_diff - mean_rank) < 1e-14)
        self.assertTrue(np.abs(var_diff - var_rank) < 1e-14)