Example #1
0
    def test_evaluate_multivariate_orthonormal_polynomial(self):
        num_vars = 2
        alpha = 0.
        beta = 0.
        degree = 2
        deriv_order = 1
        probability_measure = True

        ab = jacobi_recurrence(degree + 1,
                               alpha=alpha,
                               beta=beta,
                               probability=probability_measure)

        x, w = np.polynomial.legendre.leggauss(degree)
        samples = cartesian_product([x] * num_vars, 1)
        weights = outer_product([w] * num_vars)

        indices = compute_hyperbolic_indices(num_vars, degree, 1.0)

        # sort lexographically to make testing easier
        I = np.lexsort((indices[0, :], indices[1, :], indices.sum(axis=0)))
        indices = indices[:, I]

        basis_matrix = evaluate_multivariate_orthonormal_polynomial(
            samples, indices, ab, deriv_order)

        exact_basis_vals_1d = []
        exact_basis_derivs_1d = []
        for dd in range(num_vars):
            x = samples[dd, :]
            exact_basis_vals_1d.append(
                np.asarray([1 + 0. * x, x, 0.5 * (3. * x**2 - 1)]).T)
            exact_basis_derivs_1d.append(
                np.asarray([0. * x, 1.0 + 0. * x, 3. * x]).T)
            exact_basis_vals_1d[-1] /= np.sqrt(1. /
                                               (2 * np.arange(degree + 1) + 1))
            exact_basis_derivs_1d[-1] /= np.sqrt(
                1. / (2 * np.arange(degree + 1) + 1))

        exact_basis_matrix = np.asarray([
            exact_basis_vals_1d[0][:, 0], exact_basis_vals_1d[0][:, 1],
            exact_basis_vals_1d[1][:, 1], exact_basis_vals_1d[0][:, 2],
            exact_basis_vals_1d[0][:, 1] * exact_basis_vals_1d[1][:, 1],
            exact_basis_vals_1d[1][:, 2]
        ]).T

        # x1 derivative
        exact_basis_matrix = np.vstack(
            (exact_basis_matrix,
             np.asarray([
                 0. * x, exact_basis_derivs_1d[0][:, 1], 0. * x,
                 exact_basis_derivs_1d[0][:, 2],
                 exact_basis_derivs_1d[0][:, 1] * exact_basis_vals_1d[1][:, 1],
                 0. * x
             ]).T))

        # x2 derivative
        exact_basis_matrix = np.vstack(
            (exact_basis_matrix,
             np.asarray([
                 0. * x, 0. * x, exact_basis_derivs_1d[1][:, 1], 0. * x,
                 exact_basis_vals_1d[0][:, 1] * exact_basis_derivs_1d[1][:, 1],
                 exact_basis_derivs_1d[1][:, 2]
             ]).T))

        def func(x):
            return evaluate_multivariate_orthonormal_polynomial(
                x, indices, ab, 0)

        basis_matrix_derivs = basis_matrix[samples.shape[1]:]
        basis_matrix_derivs_fd = np.empty_like(basis_matrix_derivs)
        for ii in range(samples.shape[1]):
            basis_matrix_derivs_fd[ii::samples.shape[1], :] = approx_fprime(
                samples[:, ii:ii + 1], func, 1e-7)
        assert np.allclose(exact_basis_matrix[samples.shape[1]:],
                           basis_matrix_derivs_fd)

        assert np.allclose(exact_basis_matrix, basis_matrix)
Example #2
0
    def test_evaluate_multivariate_mixed_basis_pce(self):
        degree = 2
        deriv_order = 1
        probability_measure = True

        gauss_mean, gauss_var = -1, 4
        univariate_variables = [
            uniform(-1, 2),
            norm(gauss_mean, np.sqrt(gauss_var)),
            uniform(0, 3)
        ]
        variable = IndependentMultivariateRandomVariable(univariate_variables)
        var_trans = AffineRandomVariableTransformation(variable)
        num_vars = len(univariate_variables)

        poly = PolynomialChaosExpansion()
        poly_opts = define_poly_options_from_variable_transformation(var_trans)
        poly.configure(poly_opts)

        univariate_quadrature_rules = [
            partial(gauss_jacobi_pts_wts_1D, alpha_poly=0, beta_poly=0),
            gauss_hermite_pts_wts_1D,
            partial(gauss_jacobi_pts_wts_1D, alpha_poly=0, beta_poly=0)
        ]
        samples, weights = get_tensor_product_quadrature_rule(
            degree + 1, num_vars, univariate_quadrature_rules,
            var_trans.map_from_canonical_space)

        indices = compute_hyperbolic_indices(num_vars, degree, 1.0)

        # sort lexographically to make testing easier
        indices = sort_indices_lexiographically(indices)
        poly.set_indices(indices)

        basis_matrix = poly.basis_matrix(samples, {'deriv_order': 1})
        vals_basis_matrix = basis_matrix[:samples.shape[1], :]
        inner_products = (vals_basis_matrix.T * weights).dot(vals_basis_matrix)
        assert np.allclose(inner_products, np.eye(basis_matrix.shape[1]))

        exact_basis_vals_1d = []
        exact_basis_derivs_1d = []
        for dd in range(num_vars):
            x = samples[dd, :].copy()
            if dd == 0 or dd == 2:
                if dd == 2:
                    # y = x/3
                    # z = 2*y-1=2*x/3-1=2/3*x-3/2*2/3=2/3*(x-3/2)=(x-3/2)/(3/2)
                    loc, scale = 3 / 2, 3 / 2
                    x = (x - loc) / scale
                exact_basis_vals_1d.append(
                    np.asarray([1 + 0. * x, x, 0.5 * (3. * x**2 - 1)]).T)
                exact_basis_derivs_1d.append(
                    np.asarray([0. * x, 1.0 + 0. * x, 3. * x]).T)
                exact_basis_vals_1d[-1] /= np.sqrt(
                    1. / (2 * np.arange(degree + 1) + 1))
                exact_basis_derivs_1d[-1] /= np.sqrt(
                    1. / (2 * np.arange(degree + 1) + 1))
                # account for affine transformation in derivs
                if dd == 2:
                    exact_basis_derivs_1d[-1] /= scale
            if dd == 1:
                loc, scale = gauss_mean, np.sqrt(gauss_var)
                x = (x - loc) / scale
                exact_basis_vals_1d.append(
                    np.asarray([1 + 0. * x, x, x**2 - 1]).T)
                exact_basis_derivs_1d.append(
                    np.asarray([0. * x, 1.0 + 0. * x, 2. * x]).T)
                exact_basis_vals_1d[-1] /= np.sqrt(
                    sp.factorial(np.arange(degree + 1)))
                exact_basis_derivs_1d[-1] /= np.sqrt(
                    sp.factorial(np.arange(degree + 1)))
                # account for affine transformation in derivs
                exact_basis_derivs_1d[-1] /= scale

        exact_basis_matrix = np.asarray([
            exact_basis_vals_1d[0][:, 0], exact_basis_vals_1d[0][:, 1],
            exact_basis_vals_1d[1][:, 1], exact_basis_vals_1d[2][:, 1],
            exact_basis_vals_1d[0][:, 2],
            exact_basis_vals_1d[0][:, 1] * exact_basis_vals_1d[1][:, 1],
            exact_basis_vals_1d[1][:, 2],
            exact_basis_vals_1d[0][:, 1] * exact_basis_vals_1d[2][:, 1],
            exact_basis_vals_1d[1][:, 1] * exact_basis_vals_1d[2][:, 1],
            exact_basis_vals_1d[2][:, 2]
        ]).T

        # x1 derivative
        exact_basis_matrix = np.vstack(
            (exact_basis_matrix,
             np.asarray([
                 0. * x, exact_basis_derivs_1d[0][:, 1], 0. * x, 0 * x,
                 exact_basis_derivs_1d[0][:, 2],
                 exact_basis_derivs_1d[0][:, 1] * exact_basis_vals_1d[1][:, 1],
                 0. * x,
                 exact_basis_derivs_1d[0][:, 1] * exact_basis_vals_1d[2][:, 1],
                 0. * x, 0. * x
             ]).T))

        # x2 derivative
        exact_basis_matrix = np.vstack(
            (exact_basis_matrix,
             np.asarray([
                 0. * x, 0. * x, exact_basis_derivs_1d[1][:, 1], 0. * x, 0 * x,
                 exact_basis_derivs_1d[1][:, 1] * exact_basis_vals_1d[0][:, 1],
                 exact_basis_derivs_1d[1][:, 2], 0. * x,
                 exact_basis_derivs_1d[1][:, 1] * exact_basis_vals_1d[2][:, 1],
                 0. * x
             ]).T))

        # x3 derivative
        exact_basis_matrix = np.vstack(
            (exact_basis_matrix,
             np.asarray([
                 0. * x, 0. * x, 0. * x, exact_basis_derivs_1d[2][:, 1], 0 * x,
                 0 * x, 0 * x,
                 exact_basis_derivs_1d[2][:, 1] * exact_basis_vals_1d[0][:, 1],
                 exact_basis_derivs_1d[2][:, 1] * exact_basis_vals_1d[1][:, 1],
                 exact_basis_derivs_1d[2][:, 2]
             ]).T))

        func = poly.basis_matrix
        exact_basis_matrix_derivs = exact_basis_matrix[samples.shape[1]:]
        basis_matrix_derivs_fd = np.empty_like(exact_basis_matrix_derivs)
        for ii in range(samples.shape[1]):
            basis_matrix_derivs_fd[ii::samples.shape[1], :] = approx_fprime(
                samples[:, ii:ii + 1], func)

        # print(np.linalg.norm(
        #    exact_basis_matrix_derivs-basis_matrix_derivs_fd,
        #    ord=np.inf))
        assert np.allclose(exact_basis_matrix_derivs,
                           basis_matrix_derivs_fd,
                           atol=1e-7,
                           rtol=1e-7)
        assert np.allclose(exact_basis_matrix, basis_matrix)