Exemple #1
0
def test_roundtrip():
    """Assert that forward/inverse Rosenblatt transforms is non-destructive."""
    mean = numpy.array([0.1, -0.5, 0])
    cov = numpy.array([[1.0, -0.9, 0.3], [-0.9, 1.0, 0.0], [0.3, 0.0, 1.0]])
    dist1 = chaospy.MvNormal(mean, cov, rotation=[0, 1, 2])
    dist2 = chaospy.MvNormal(mean, cov, rotation=[2, 1, 0])
    dist3 = chaospy.MvNormal(mean, cov, rotation=[2, 0, 1])

    mesh = numpy.mgrid[0.25:0.75:3j, 0.25:0.75:5j, 0.25:0.75:4j].reshape(3, -1)
    assert not numpy.allclose(dist1.fwd(dist2.inv(mesh)), mesh)
    assert numpy.allclose(dist1.fwd(dist1.inv(mesh)), mesh)
    assert numpy.allclose(dist2.fwd(dist2.inv(mesh)), mesh)
    assert numpy.allclose(dist3.fwd(dist3.inv(mesh)), mesh)
    def test_dimensionReduction(self):

        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        # Create stochastic collocation object
        collocation = StochasticCollocation(3, "Normal")

        # Create dimension reduction object
        threshold_factor = 0.9
        dominant_space = DimensionReduction(threshold_factor=threshold_factor,
                                            exact_Hessian=True)

        # Initialize chaospy distribution
        std_dev = 0.2 * np.ones(QoI.systemsize)
        x = np.ones(QoI.systemsize)
        jdist = cp.MvNormal(x, np.diag(std_dev))

        # Get the eigenmodes of the Hessian product and the dominant indices
        dominant_space.getDominantDirections(QoI, jdist)
        true_eigenvals = np.array([0.08, 0.02, 0.005, 0.00888888888888889])
        err_eigenvals = abs(dominant_space.iso_eigenvals - true_eigenvals)

        true_eigenvecs = np.array([[0.5, 0.5, -0.5, -0.5],
                                   [0.5, -0.5, 0.5,
                                    -0.5], [0.5, 0.5, 0.5, 0.5],
                                   [0.5, -0.5, -0.5, 0.5]])
        err_eigenvecs = abs(dominant_space.iso_eigenvecs - true_eigenvecs)

        self.assertTrue((err_eigenvals < 1.e-15).all())
        self.assertTrue((err_eigenvecs < 1.e-15).all())
        self.assertEqual(dominant_space.dominant_indices, [0, 1])
    def setup(self):

        print("In Setup!!")

        self.std_dev_xi = np.array([0.3, 0.2, 0.1])
        system_size = 3
        mean_xi = np.ones(system_size)

        # Inputs
        self.add_input('mean_xi', val=mean_xi)

        # Intermediate operations
        jdist = cp.MvNormal(mean_xi, np.diag(self.std_dev_xi))
        self.collocation_QoI = StochasticCollocation(system_size, "Normal")
        self.collocation_QoI_grad = StochasticCollocation(
            system_size, "Normal",
            system_size)  # Create a Stochastic collocation object
        self.QoI = examples.Paraboloid3D(system_size)  # Create QoI
        threshold_factor = 0.9
        self.dominant_space = DimensionReduction(threshold_factor,
                                                 exact_Hessian=True)
        self.dominant_space.getDominantDirections(self.QoI, jdist)

        # Outputs
        self.add_output('mean_QoI', 0.0)

        # Partial derivatives
        self.declare_partials('mean_QoI', 'mean_xi')
Exemple #4
0
    def test_hadamard_accuracy(self):
        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        mu = np.zeros(systemsize)
        std_dev = np.eye(systemsize)
        jdist = cp.MvNormal(mu, std_dev)

        active_subspace = ActiveSubspace(QoI, n_dominant_dimensions=4,
                                             n_monte_carlo_samples=10000,
                                             use_svd=True, read_rv_samples=False,
                                             write_rv_samples=False)
        active_subspace.getDominantDirections(QoI, jdist)

        mu_j_analytical = QoI.eval_analytical_QoI_mean(mu, cp.Cov(jdist))
        var_j_analytical = QoI.eval_analytical_QoI_variance(mu, cp.Cov(jdist))

        # Create reduced collocation object
        QoI_dict = {'Hadamard' : {'QoI_func' : QoI.eval_QoI,
                                  'output_dimensions' : 1,
                                  },
                    }
        sc_obj_active = StochasticCollocation2(jdist, 4, 'MvNormal', QoI_dict,
                                        include_derivs=False,
                                        reduced_collocation=True,
                                        dominant_dir=active_subspace.dominant_dir)
        sc_obj_active.evaluateQoIs(jdist)

        mu_j_active = sc_obj_active.mean(of=['Hadamard'])
        var_j_active = sc_obj_active.variance(of=['Hadamard'])
Exemple #5
0
def run_hadamard(systemsize, eigen_decayrate, std_dev, n_sample):
    # n_collocation_pts = 2

    # Create Hadmard Quadratic object
    QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

    # Create stochastic collocation object
    # collocation = StochasticCollocation(n_collocation_pts, "Normal")

    # Initialize chaospy distribution
    x = np.random.randn(QoI.systemsize)
    jdist = cp.MvNormal(x, np.diag(std_dev))

    threshold_factor = 0.5
    dominant_space_exact = DimensionReduction(
        threshold_factor=threshold_factor, exact_Hessian=True)
    dominant_space = DimensionReduction(threshold_factor=threshold_factor,
                                        exact_Hessian=False,
                                        n_arnoldi_sample=n_sample)

    dominant_space.getDominantDirections(QoI, jdist, max_eigenmodes=20)
    dominant_space_exact.getDominantDirections(QoI, jdist)

    # Sort the exact eigenvalues in descending order
    sort_ind = dominant_space_exact.iso_eigenvals.argsort()[::-1]

    # Compare the eigenvalues of the 10 most dominant spaces
    lambda_exact = dominant_space_exact.iso_eigenvals[sort_ind]
    error_arr = dominant_space.iso_eigenvals[0:10] - lambda_exact[0:10]
    # print 'error_arr = ', error_arr
    rel_error_norm = np.linalg.norm(error_arr) / np.linalg.norm(
        lambda_exact[0:10])

    return rel_error_norm
    def calcMarginals(self, jdist):
        """
        Compute the marginal density object for the dominant space. The current
        implementation is only for Gaussian distribution.
        """

        marginal_size = len(self.dominant_indices)
        orig_mean = cp.E(jdist)
        orig_covariance = cp.Cov(jdist)

        # Step 1: Rotate the mean & covariance matrix of the the original joint
        # distribution along the eigenve
        dominant_vecs = self.iso_eigenvecs[:, self.dominant_indices]
        marginal_mean = np.dot(dominant_vecs.T, orig_mean)
        marginal_covariance = np.matmul(
            dominant_vecs.T, np.matmul(orig_covariance, dominant_vecs))

        # Step 2: Create the new marginal distribution
        if marginal_size == 1:  # Univariate distributions have to be treated separately
            marginal_std_dev = np.sqrt(np.asscalar(marginal_covariance))
            self.marginal_distribution = cp.Normal(np.asscalar(marginal_mean),
                                                   marginal_std_dev)
        else:
            self.marginal_distribution = cp.MvNormal(marginal_mean,
                                                     marginal_covariance)
    def test_derivatives_scalarQoI(self):
        systemsize = 3
        mu = mean_3dim  # np.random.randn(systemsize)
        std_dev = std_dev_3dim  # np.diag(np.random.rand(systemsize))
        jdist = cp.MvNormal(mu, std_dev)
        # Create QoI Object
        QoI = examples.Paraboloid3D(systemsize)

        # Create the Stochastic Collocation object
        deriv_dict = {
            'xi': {
                'dQoI_func': QoI.eval_QoIGradient,
                'output_dimensions': systemsize
            }
        }
        QoI_dict = {
            'paraboloid': {
                'quadrature_degree': 3,
                'reduced_collocation': False,
                'QoI_func': QoI.eval_QoI,
                'output_dimensions': 1,
                'include_derivs': True,
                'deriv_dict': deriv_dict
            }
        }
        sc_obj = StochasticCollocation3(jdist, 'MvNormal', QoI_dict)
        sc_obj.evaluateQoIs(jdist)
        dmu_j = sc_obj.dmean(of=['paraboloid'], wrt=['xi'])
        # dvar_j = sc_obj.dvariance(of=['paraboloid'], wrt=['xi'])

        # Analytical dmu_j
        dmu_j_analytical = np.array([100 * mu[0], 50 * mu[1], 2 * mu[2]])
        err = abs(
            (dmu_j['paraboloid']['xi'] - dmu_j_analytical) / dmu_j_analytical)
        self.assertTrue((err < 1.e-12).all())
Exemple #8
0
 def multivariate(mean, cov, size):
     # rule must be of 'L', 'M', 'H', 'K' or 'S'
     res = chaospy.MvNormal(mean, cov).sample(size=size,
                                              rule=rule or 'L')
     res = np.moveaxis(res, 0, res.ndim - 1)
     np.random.shuffle(res)
     return res
    def test_nonrv_derivatives(self):
        # This test checks the analytical derivative w.r.t complex step
        systemsize = 2
        n_parameters = 2
        mu = mean_2dim  # np.random.randn(systemsize)
        std_dev = std_dev_2dim  # np.diag(np.random.rand(systemsize))
        jdist = cp.MvNormal(mu, std_dev)
        QoI = examples.PolyRVDV(data_type=complex)
        # Create the Stochastic Collocation object
        deriv_dict = {
            'dv': {
                'dQoI_func': QoI.eval_QoIGradient_dv,
                'output_dimensions': n_parameters
            }
        }
        QoI_dict = {
            'PolyRVDV': {
                'QoI_func': QoI.eval_QoI,
                'output_dimensions': 1,
                'deriv_dict': deriv_dict
            }
        }
        dv = np.random.randn(systemsize) + 0j
        QoI.set_dv(dv)
        sc_obj = StochasticCollocation2(jdist,
                                        3,
                                        'MvNormal',
                                        QoI_dict,
                                        include_derivs=True,
                                        data_type=complex)
        sc_obj.evaluateQoIs(jdist, include_derivs=True)
        dmu_j = sc_obj.dmean(of=['PolyRVDV'], wrt=['dv'])
        dvar_j = sc_obj.dvariance(of=['PolyRVDV'], wrt=['dv'])
        dstd_dev = sc_obj.dStdDev(of=['PolyRVDV'], wrt=['dv'])

        # Lets do complex step
        pert = complex(0, 1e-30)
        dmu_j_complex = np.zeros(n_parameters, dtype=complex)
        dvar_j_complex = np.zeros(n_parameters, dtype=complex)
        dstd_dev_complex = np.zeros(n_parameters, dtype=complex)
        for i in range(0, n_parameters):
            dv[i] += pert
            QoI.set_dv(dv)
            sc_obj.evaluateQoIs(jdist, include_derivs=False)
            mu_j = sc_obj.mean(of=['PolyRVDV'])
            var_j = sc_obj.variance(of=['PolyRVDV'])
            std_dev_j = np.sqrt(var_j['PolyRVDV'][0, 0])
            dmu_j_complex[i] = mu_j['PolyRVDV'].imag / pert.imag
            dvar_j_complex[i] = var_j['PolyRVDV'].imag / pert.imag
            dstd_dev_complex[i] = std_dev_j.imag / pert.imag
            dv[i] -= pert

        err1 = dmu_j['PolyRVDV']['dv'] - dmu_j_complex
        self.assertTrue((err1 < 1.e-13).all())

        err2 = dvar_j['PolyRVDV']['dv'] - dvar_j_complex
        self.assertTrue((err2 < 1.e-13).all())

        err3 = dstd_dev['PolyRVDV']['dv'] - dstd_dev_complex
        self.assertTrue((err2 < 1.e-13).all())
    def test_scalarQoI(self):
        systemsize = 3
        mu = np.random.rand(systemsize)
        std_dev = np.diag(np.random.rand(systemsize))
        jdist = cp.MvNormal(mu, std_dev)
        # Create QoI Object
        QoI = Paraboloid3D(systemsize)

        # Create the Monte Carlo object
        QoI_dict = {
            'paraboloid': {
                'QoI_func': QoI.eval_QoI,
                'output_dimensions': 1,
            }
        }
        nsample = 1000000
        mc_obj = MonteCarlo(nsample, jdist, QoI_dict)
        mc_obj.getSamples(jdist)
        # Get the mean and variance using Monte Carlo
        mu_js = mc_obj.mean(jdist, of=['paraboloid'])
        var_js = mc_obj.variance(jdist, of=['paraboloid'])

        # Analytical mean
        mu_j_analytical = QoI.eval_QoI_analyticalmean(mu, cp.Cov(jdist))
        err = abs((mu_js['paraboloid'] - mu_j_analytical) / mu_j_analytical)
        self.assertTrue(err < 1e-3)
        # Analytical variance
        var_j_analytical = QoI.eval_QoI_analyticalvariance(mu, cp.Cov(jdist))
        err = abs((var_js['paraboloid'] - var_j_analytical) / var_j_analytical)
        # print('var_js paraboloid = ', var_js['paraboloid'], '\n')
        self.assertTrue(err < 1e-2)
    def test_multipleQoI(self):

        # This tests for multiple QoIs. We only compute the mean in this test,
        # because it is only checking if it can do multiple loops

        systemsize = 2
        theta = 0
        mu = mean_2dim  # np.random.randn(systemsize)
        std_dev = std_dev_2dim  # np.diag(np.random.rand(systemsize))
        jdist = cp.MvNormal(mu, std_dev)
        QoI1 = examples.Paraboloid2D(systemsize, (theta, ))
        QoI2 = examples.PolyRVDV()
        QoI_dict = {
            'paraboloid2': {
                'QoI_func': QoI1.eval_QoI,
                'output_dimensions': 1,
            },
            'PolyRVDV': {
                'QoI_func': QoI2.eval_QoI,
                'output_dimensions': 1,
            }
        }
        sc_obj = StochasticCollocation2(jdist, 3, 'MvNormal', QoI_dict)
        sc_obj.evaluateQoIs(jdist)
        mu_js = sc_obj.mean(of=['paraboloid2', 'PolyRVDV'])

        # Compare against known values
        # 1. Paraboloid2D, we use nested loops
        mu_j1_analytical = QoI1.eval_QoI_analyticalmean(mu, cp.Cov(jdist))
        err = abs(
            (mu_js['paraboloid2'][0] - mu_j1_analytical) / mu_j1_analytical)
        self.assertTrue(err < 1.e-15)
def run_hadamard(systemsize, eigen_decayrate, std_dev, n_eigenmodes):
    n_collocation_pts = 2

    # Create Hadmard Quadratic object
    QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

    # # Create stochastic collocation object
    # collocation = StochasticCollocation(n_collocation_pts, "Normal")

    # Initialize chaospy distribution
    x = np.random.rand(QoI.systemsize)
    jdist = cp.MvNormal(x, np.diag(std_dev))

    threshold_factor = 0.5
    dominant_space = DimensionReduction(threshold_factor=threshold_factor,
                                        exact_Hessian=False,
                                        n_arnoldi_sample=71,
                                        min_eigen_accuracy=1.e-2)
    dominant_space.getDominantDirections(QoI,
                                         jdist,
                                         max_eigenmodes=n_eigenmodes)

    # if systemsize == 64:
    # print('x = \n', repr(x))
    # print('std_dev = \n', repr(std_dev))
    # print('iso_eigenvals = ', dominant_space.iso_eigenvals)
    # print("dominant_indices = ", dominant_space.dominant_indices)

    # Collocate
    # collocation = StochasticCollocation(n_collocation_pts, "Normal")
    # mu_j = collocation.normal.reduced_mean(QoI.eval_QoI, jdist, dominant_space)
    # print "mu_j = ", mu_j

    QoI_dict = {
        'Hadamard': {
            'QoI_func': QoI.eval_QoI,
            'output_dimensions': 1,
        },
    }
    sc_obj = StochasticCollocation2(jdist,
                                    n_collocation_pts,
                                    'MvNormal',
                                    QoI_dict,
                                    include_derivs=False,
                                    reduced_collocation=True,
                                    dominant_dir=dominant_space.dominant_dir)
    sc_obj.evaluateQoIs(jdist)
    mu_j_dict = sc_obj.mean(of=['Hadamard'])
    mu_j = mu_j_dict['Hadamard']

    # Evaluate the analytical value of the Hadamard Quadratic
    covariance = cp.Cov(jdist)
    mu_analytic = QoI.eval_analytical_QoI_mean(x, covariance)
    # print "mu_analytic = ", mu_analytic

    relative_error = np.linalg.norm((mu_j - mu_analytic) / mu_analytic)
    # print "relative_error = ", relative_error

    return relative_error
    def test_dimensionReduction_arnoldi_partial(self):

        # Compute 21 major the eigenmodes of an isoprobabilistic Hadamard
        # quadratic system using Arnoldi sampling and verify against the exact
        # computation

        systemsize = 64
        eigen_decayrate = 2.0
        num_sample = 51

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        # Initialize chaospy distribution
        std_dev = np.random.rand(QoI.systemsize)
        sqrt_Sigma = np.diag(std_dev)
        mu = np.random.rand(QoI.systemsize)
        jdist = cp.MvNormal(mu, sqrt_Sigma)

        # Estimate the eigenmodes of the Hessenberg matrix using Arnoldi
        perturbation_size = 1.e-6
        arnoldi = ArnoldiSampling(perturbation_size, num_sample)
        eigenvals = np.zeros(num_sample-1)
        eigenvecs = np.zeros([QoI.systemsize, num_sample-1])
        mu_iso = np.zeros(QoI.systemsize)
        mu_iso[:] = 0.0
        gdata0 = np.zeros([QoI.systemsize, num_sample])
        gdata0[:,0] = np.dot(QoI.eval_QoIGradient(mu, np.zeros(QoI.systemsize)),
                            sqrt_Sigma)
        dim, error_estimate = arnoldi.arnoldiSample(QoI, jdist, mu_iso, gdata0,
                                                    eigenvals, eigenvecs)

        # Compute the exact eigenmodes
        Hessian = QoI.eval_QoIHessian(mu, np.zeros(QoI.systemsize))
        Hessian_Product = np.matmul(sqrt_Sigma, np.matmul(Hessian, sqrt_Sigma))
        exact_eigenvals, exact_eigenvecs = np.linalg.eig(Hessian_Product)

        # Sort in descending order
        sort_ind1 = exact_eigenvals.argsort()[::-1]
        sort_ind2 = eigenvals.argsort()[::-1]
        lambda_exact = exact_eigenvals[sort_ind1]
        lambda_arnoldi = eigenvals[sort_ind2]

        # Compare the eigenvalues
        for i in range(0, num_sample-1):
            if i < 10:
                self.assertAlmostEqual(lambda_arnoldi[i], lambda_exact[i], places=6)
            else:
                # print "lambda_exact[i] = ", lambda_exact[i], "lambda_arnoldi[i] = ", lambda_arnoldi[i]
                self.assertAlmostEqual(lambda_arnoldi[i], lambda_exact[i], places=1)

        # Compare the eigenvectors
        V_exact = exact_eigenvecs[:, sort_ind1]
        V_arnoldi = eigenvecs[:, sort_ind2]
        for i in range(0, num_sample-1):
            product = abs(np.dot(V_exact[:,i], V_arnoldi[:,i]))
            if i < 10:
                self.assertAlmostEqual(product, 1.0, places=6)
Exemple #14
0
def test_rotation():
    """Make sure various rotations do not affect results."""
    mean = numpy.array([0, 10, 0])
    cov = numpy.array([[1.0, -0.2, 0.3], [-0.2, 1.0, 0.0], [0.3, 0.0, 1.0]])
    mesh = numpy.mgrid[-1:1:2j, 9:11:3j, -1:1:4j]
    dist1 = chaospy.MvNormal(mean, cov, rotation=[0, 1, 2])
    dist2 = chaospy.MvNormal(mean, cov, rotation=[2, 1, 0])
    dist3 = chaospy.MvNormal(mean, cov, rotation=[2, 0, 1])

    # PDF should be unaffected by rotation.
    assert numpy.allclose(dist1.pdf(mesh), dist2.pdf(mesh))
    assert numpy.allclose(dist1.pdf(mesh), dist3.pdf(mesh))
    assert numpy.allclose(dist2.pdf(mesh), dist3.pdf(mesh))

    # One axis is constant. Verify that is the case for each rotation.
    assert numpy.all(dist1.fwd(mesh)[0, :, 0, 0] == dist1.fwd(mesh)[0].T)
    assert numpy.all(dist2.fwd(mesh)[2, 0, 0, :] == dist2.fwd(mesh)[2])
    assert numpy.all(dist3.fwd(mesh)[2, 0, 0, :] == dist2.fwd(mesh)[2])
Exemple #15
0
def objfunc(xdict):
    mu = xdict['xvars']
    funcs = {}
    jdist = cp.MvNormal(mu, std_dev)
    QoI_func = QoI.eval_QoI
    funcs['obj'] = collocation.normal.reduced_mean(QoI_func, jdist,
                                                   dominant_space)
    fail = False
    return funcs, fail
    def compute(self, inputs, outputs):

        print("In compute")

        mu = inputs['mean_xi']
        # print("mu = ", mu)
        jdist = cp.MvNormal(mu, np.diag(self.std_dev_xi))
        QoI_func = self.QoI.eval_QoI
        outputs['mean_QoI'] = self.collocation_QoI.normal.reduced_mean(
            QoI_func, jdist, self.dominant_space)
Exemple #17
0
def sens(xdict, funcs):
    mu = xdict['xvars']
    jdist = cp.MvNormal(mu, std_dev)
    QoI_func = QoI.eval_QoIGradient
    funcsSens = {}
    funcsSens['obj', 'xvars'] = collocation_grad.normal.reduced_mean(
        QoI_func, jdist, dominant_space)

    fail = False
    return funcsSens, fail
    def compute_partials(self, inputs, J):

        print("In compute_partials")

        mu = inputs['mean_xi']
        jdist = cp.MvNormal(mu, np.diag(self.std_dev_xi))
        QoI_func = self.QoI.eval_QoIGradient
        val = self.collocation_QoI_grad.normal.reduced_mean(
            QoI_func, jdist, self.dominant_space)
        J['mean_QoI',
          'mean_xi'] = val  # self.collocation.normal.reduced_mean(QoI_func, jdist, self.dominant_space)
Exemple #19
0
def test_sampling_statistics():
    """Assert that given mean and covariance matches sample statistics."""
    mean = [100, 10, 10, 100]
    cov = [[10, -9, 3, -1], [-9, 20, 1, -2], [3, 1, 30, 4], [-1, -2, 4, 40]]
    dist = chaospy.MvNormal(mean, cov, rotation=[3, 0, 2, 1])
    samples = dist.sample(100000)
    assert numpy.allclose(numpy.mean(samples, axis=-1),
                          mean,
                          atol=1e-2,
                          rtol=1e-3), numpy.mean(samples, axis=-1).round(3)
    assert numpy.allclose(numpy.cov(samples), cov, atol=1e-1,
                          rtol=1e-2), numpy.cov(samples).round(3)
    def test_arnoldiSample_complete(self):

        # Compute all of the eigenmodes of an isoprobabilistic Hadamard
        # quadratic system using Arnoldi sampling and verify against the exact
        # computation

        systemsize = 16
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        # Initialize chaospy distribution
        std_dev = np.random.rand(QoI.systemsize)
        sqrt_Sigma = np.diag(std_dev)
        mu = np.random.rand(QoI.systemsize)
        jdist = cp.MvNormal(mu, sqrt_Sigma)

        # Estimate the eigenmodes of the Hessenberg matrix using Arnoldi
        perturbation_size = 1.e-6
        num_sample = QoI.systemsize+1
        arnoldi = ArnoldiSampling(perturbation_size, num_sample)
        eigenvals = np.zeros(num_sample-1)
        eigenvecs = np.zeros([QoI.systemsize, num_sample-1])
        mu_iso = np.zeros(QoI.systemsize)
        mu_iso[:] = 0.0
        gdata0 = np.zeros([QoI.systemsize, num_sample])
        gdata0[:,0] = np.dot(QoI.eval_QoIGradient(mu, np.zeros(QoI.systemsize)),
                            sqrt_Sigma)
        dim, error_estimate = arnoldi.arnoldiSample(QoI, jdist, mu_iso, gdata0,
                                                    eigenvals, eigenvecs)

        # Compute the exact eigenmodes
        Hessian = QoI.eval_QoIHessian(mu, np.zeros(QoI.systemsize))
        Hessian_Product = np.matmul(sqrt_Sigma, np.matmul(Hessian, sqrt_Sigma))
        exact_eigenvals, exact_eigenvecs = np.linalg.eig(Hessian_Product)

        # Sort in descending order
        sort_ind1 = exact_eigenvals.argsort()[::-1]
        sort_ind2 = eigenvals.argsort()[::-1]

        # Compare the eigenvalues
        err_eigenvals = abs(exact_eigenvals[sort_ind1] -
                            eigenvals[sort_ind2])
        self.assertTrue((err_eigenvals < 1.e-7).all())

        # Compare the eigenvectors
        V_exact = exact_eigenvecs[:, sort_ind1]
        V_arnoldi = eigenvecs[:, sort_ind2]
        product = np.zeros(QoI.systemsize)
        for i in range(0, systemsize):
            product[i] = abs(np.dot(V_exact[:,i], V_arnoldi[:,i]))
            self.assertAlmostEqual(product[i], 1.0, places=7)
Exemple #21
0
def test_slicing():
    """Test if slicing of distribution works as expected."""
    dist = chaospy.MvNormal(mu=[1, 2],
                            sigma=[[4, -1], [-1, 3]],
                            rotation=[1, 0])
    with pytest.raises(IndexError):
        dist[-2]
    with pytest.raises(IndexError):
        dist[2]
    with pytest.raises(IndexError):
        dist["illigal_index"]
    assert dist[-1] == dist[1]
    assert dist[1].mom(1) == 2
Exemple #22
0
def test_sampling():
    """Assert that inverse mapping results in samples with the correct statistics."""
    mean = numpy.array([100, 10, 50])
    cov = numpy.array([[10, -8, 4], [-8, 20, 2], [4, 2, 30]])
    samples_u = chaospy.Uniform().sample((3, 100000))
    for rotation in [(0, 1, 2), (2, 1, 0), (2, 0, 1)]:
        dist = chaospy.MvNormal(mean, cov, rotation=rotation)
        samples_ = dist.inv(samples_u)
        assert numpy.allclose(numpy.mean(samples_, axis=-1),
                              mean,
                              atol=1e-3,
                              rtol=1e-3)
        assert numpy.allclose(numpy.cov(samples_), cov, atol=1e-2, rtol=1e-2)
    def test_deterministic_model(self):
        # Check if the quantity of interest is being computed as expected
        uq_systemsize = 6
        mu_orig = np.array(
            [mean_Ma, mean_TSFC, mean_W0, mean_E, mean_G, mean_mrho])
        std_dev = np.diag([0.005, 0.00607 / 3600, 0.2, 5.e9, 1.e9, 50])
        jdist = cp.MvNormal(mu_orig, std_dev)

        rv_dict = {
            'Mach_number': mean_Ma,
            'CT': mean_TSFC,
            'W0': mean_W0,
            'E': mean_E,  # surface RV
            'G': mean_G,  # surface RV
            'mrho': mean_mrho,  # surface RV
        }

        input_dict = {
            'n_twist_cp': 3,
            'n_thickness_cp': 3,
            'n_CM': 3,
            'n_thickness_intersects': 10,
            'n_constraints': 1 + 10 + 1 + 3 + 3,
            'ndv': 3 + 3 + 2,
            'mesh_dict': mesh_dict,
            'rv_dict': rv_dict
        }

        QoI = examples.OASScanEagleWrapper(uq_systemsize,
                                           input_dict,
                                           include_dict_rv=True)

        # Check the value at the starting point
        fval = QoI.eval_QoI(mu_orig, np.zeros(uq_systemsize))
        true_val = 5.229858093218218
        err = abs(fval - true_val)
        self.assertTrue(err < 1.e-6)

        # Check if plugging back value also yields the expected results
        QoI.p['oas_scaneagle.wing.twist_cp'] = np.array([2.60830137, 10., 5.])
        QoI.p['oas_scaneagle.wing.thickness_cp'] = np.array(
            [0.001, 0.001, 0.001])
        QoI.p['oas_scaneagle.wing.sweep'] = [18.89098985]
        QoI.p['oas_scaneagle.alpha'] = [2.19244059]
        fval = QoI.eval_QoI(mu_orig, np.zeros(uq_systemsize))
        true_val = 4.735819672292367
        err = abs(fval - true_val)
        self.assertTrue(err < 1.e-6)
    def test_reduced_montecarlo(self):
        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = HadamardQuadratic(systemsize, eigen_decayrate)
        true_eigenvals = np.array([0.08, 0.02, 0.005, 0.00888888888888889])
        true_eigenvecs = np.array([[0.5, 0.5, -0.5, -0.5],
                                   [0.5, -0.5, 0.5,
                                    -0.5], [0.5, 0.5, 0.5, 0.5],
                                   [0.5, -0.5, -0.5, 0.5]])
        dominant_dir = true_eigenvecs[:, 0:3]

        QoI_dict = {
            'hadamard4_2': {
                'QoI_func': QoI.eval_QoI,
                'output_dimensions': 1,
            }
        }

        # Create the distribution
        mu = np.ones(systemsize)
        std_dev = 0.2 * np.eye(systemsize)
        jdist = cp.MvNormal(mu, std_dev)
        # Create the Monte Carlo object
        nsample = 100000
        mc_obj = MonteCarlo(nsample,
                            jdist,
                            QoI_dict,
                            reduced_collocation=True,
                            dominant_dir=dominant_dir,
                            include_derivs=False)
        mc_obj.getSamples(jdist, include_derivs=False)
        mu_j_mc = mc_obj.mean(jdist, of=['hadamard4_2'])

        # Compare against a reduced stochastic collocation object
        sc_obj = StochasticCollocation2(jdist,
                                        3,
                                        'MvNormal',
                                        QoI_dict,
                                        reduced_collocation=True,
                                        dominant_dir=dominant_dir)
        sc_obj.evaluateQoIs(jdist)
        mu_j_sc = sc_obj.mean(of=['hadamard4_2'])

        rel_err = abs((mu_j_mc['hadamard4_2'] - mu_j_sc['hadamard4_2']) /
                      mu_j_sc['hadamard4_2'])
        self.assertTrue(rel_err[0] < 1.e-3)
Exemple #25
0
def test_dist_addition_wrappers():
    dists = [
        chaospy.J(chaospy.Normal(2), chaospy.Normal(2), chaospy.Normal(3)),  # ShiftScale
        chaospy.J(chaospy.Uniform(1, 3), chaospy.Uniform(1, 3), chaospy.Uniform(1, 5)),  # LowerUpper
        chaospy.MvNormal([2, 2, 3], numpy.eye(3)),  # MeanCovariance
    ]
    for dist in dists:
        joint = chaospy.Add([1, 1, 3], dist)

        assert numpy.allclose(joint.inv([0.5, 0.5, 0.5]), [3, 3, 6])
        assert numpy.allclose(joint.fwd([3, 3, 6]), [0.5, 0.5, 0.5])
        density = joint.pdf([2, 2, 2], decompose=True)
        assert numpy.isclose(density[0], density[1]), (dist, density)
        assert not numpy.isclose(density[0], density[2]), dist
        assert numpy.isclose(joint[0].inv([0.5]), 3)
        assert numpy.isclose(joint[0].fwd([3]), 0.5)
Exemple #26
0
 def x_cond(n, subset_j, subsetj_conditional, xjc):
     if subsetj_conditional is None:
         cov_int = np.array(cov)
         cov_int = cov_int.take(subset_j, axis=1)
         cov_int = cov_int[subset_j]
         distribution = cp.MvNormal(mean[subset_j], cov_int)
         return distribution.sample(n)
     else:
         return _r_condmvn(
             n,
             mean=mean,
             cov=cov,
             dependent_ind=subset_j,
             given_ind=subsetj_conditional,
             x_given=xjc,
         )
def test_operator_slicing():
    dists = [
        chaospy.Normal([2, 2, 3]),  # ShiftScale
        chaospy.Uniform(1, [3, 3, 5]),  # LowerUpper
        chaospy.MvNormal([2, 2, 3], numpy.eye(3)),  # MeanCovariance
        chaospy.J(chaospy.Uniform(1, 3), chaospy.Uniform(1, [3, 5])),  # Joint
    ]
    for dist in dists:

        assert numpy.allclose(dist.inv([0.5, 0.5, 0.5]), [2, 2, 3])
        assert numpy.allclose(dist.fwd([2, 2, 3]), [0.5, 0.5, 0.5])
        density = dist.pdf([2, 2, 2], decompose=True)
        assert numpy.isclose(density[0], density[1]), dist
        assert not numpy.isclose(density[0], density[2]), dist
        assert numpy.isclose(dist[0].inv([0.5]), 2)
        assert numpy.isclose(dist[0].fwd([2]), 0.5)
Exemple #28
0
    def test_evaluation(self):
        uq_systemsize = 5
        mean_v = 248.136  # Mean value of input random variable
        mean_alpha = 5  #
        mean_Ma = 0.84
        mean_re = 1.e6
        mean_rho = 0.38
        mean_cg = np.zeros((3))

        std_dev = np.eye(uq_systemsize)
        mu_init = np.array([mean_v, mean_alpha, mean_Ma, mean_re, mean_rho])
        rv_dict = {
            'v': mean_v,
            'alpha': mean_alpha,
            'Mach_number': mean_Ma,
            're': mean_re,
            'rho': mean_rho,
        }

        QoI = examples.OASAerodynamicWrapper(uq_systemsize, rv_dict)
        jdist = cp.MvNormal(mu_init, std_dev)
        fval = QoI.eval_QoI(mu_init, np.zeros(uq_systemsize))

        # Check the values
        expected_CD = 0.03721668965447261
        expected_CL = 0.5123231521985626
        expected_CM = np.array([0., -0.1793346481832254, 0.])
        self.assertAlmostEqual(QoI.p['oas_example1.aero_point_0.CD'][0],
                               expected_CD,
                               places=13)
        self.assertAlmostEqual(QoI.p['oas_example1.aero_point_0.CL'][0],
                               expected_CL,
                               places=13)
        # np.testing.assert_array_almost_equal(QoI.p['oas_example1.aero_point_0.CM'][1], expected_CM, decimal=12)

        # Check the gradients
        grad = QoI.eval_QoIGradient(mu_init, np.zeros(uq_systemsize))
        expected_dCD = np.array([0., 0.00245012, 0.00086087, -0., 0.])
        expected_dCL = np.array([-0., 0.07634319, -0., -0., -0.])
        np.testing.assert_array_almost_equal(
            QoI.deriv['oas_example1.aero_point_0.CD', 'mu'][0],
            expected_dCD,
            decimal=7)
        np.testing.assert_array_almost_equal(
            QoI.deriv['oas_example1.aero_point_0.CL', 'mu'][0],
            expected_dCL,
            decimal=7)
Exemple #29
0
def test_segmented_mappings():
    """Assert that conditional distributions in various rotation works as expected."""
    mean_ref = numpy.array([1, 10, 100])
    covariance = numpy.array([[1, 0.4, -0.5], [0.4, 2, 0], [-0.5, 0, 3]])

    for rot in [(0, 1, 2), (2, 1, 0), (2, 0, 1)]:
        dist = chaospy.MvNormal(mean_ref, covariance, rotation=rot)
        mean = mean_ref[numpy.array(rot)]
        samples = dist.sample(100)
        isamples = dist.fwd(samples)
        density = dist.pdf(samples, decompose=True)

        caches = [{}, {
            (rot[0], dist): (samples[rot[0]], isamples[rot[0]])
        }, {
            (rot[0], dist): (samples[rot[0]], isamples[rot[0]]),
            (rot[1], dist): (samples[rot[1]], isamples[rot[1]])
        }]
        for idx, cache in zip(rot, caches):
            assert numpy.allclose(
                dist._get_fwd(samples[idx], idx, cache=cache.copy()),
                isamples[idx])
            assert numpy.allclose(
                dist._get_inv(isamples[idx], idx, cache=cache.copy()),
                samples[idx])
            assert numpy.allclose(
                dist._get_pdf(samples[idx], idx, cache=cache.copy()),
                density[idx])
            if cache:
                with pytest.raises(chaospy.StochasticallyDependentError):
                    dist[idx].fwd(samples[idx])
                with pytest.raises(chaospy.StochasticallyDependentError):
                    dist[idx].inv(isamples[idx])
                with pytest.raises(chaospy.StochasticallyDependentError):
                    dist[idx].pdf(samples[idx])
            else:
                assert numpy.allclose(dist[idx].fwd(samples[idx]),
                                      isamples[idx])
                assert numpy.allclose(dist[idx].inv(isamples[idx]),
                                      samples[idx])
                assert numpy.allclose(dist[idx].pdf(samples[idx]),
                                      density[idx])
                assert dist[idx].mom(1, allow_approx=False) == mean_ref[idx]
            assert numpy.isclose(dist[idx].mom(1, allow_approx=False),
                                 mean_ref[idx])
            with pytest.raises(chaospy.StochasticallyDependentError):
                dist[idx].ttr(1)
    def test_reduced_normalStochasticCollocation3D(self):

        # This is not a very good test because we are comparing the reduced collocation
        # against the analytical expected value. The only hting it tells us is that
        # the solution is within the ball park of actual value. We still need to
        # come up with a better test.

        systemsize = 3
        mu = mean_3dim  # np.random.randn(systemsize)
        std_dev = std_dev_3dim  # abs(np.diag(np.random.randn(systemsize)))
        jdist = cp.MvNormal(mu, std_dev)
        # Create QoI Object
        QoI = examples.Paraboloid3D(systemsize)
        dominant_dir = np.array([[1.0, 0.0], [0.0, 1.0], [0.0, 0.0]],
                                dtype=np.float)
        # Create the Stochastic Collocation object
        deriv_dict = {
            'xi': {
                'dQoI_func': QoI.eval_QoIGradient,
                'output_dimensions': systemsize
            }
        }
        QoI_dict = {
            'paraboloid': {
                'QoI_func': QoI.eval_QoI,
                'output_dimensions': 1,
                'deriv_dict': deriv_dict
            }
        }
        sc_obj = StochasticCollocation2(jdist,
                                        3,
                                        'MvNormal',
                                        QoI_dict,
                                        reduced_collocation=True,
                                        dominant_dir=dominant_dir)
        sc_obj.evaluateQoIs(jdist)
        mu_js = sc_obj.mean(of=['paraboloid'])
        var_js = sc_obj.variance(of=['paraboloid'])
        # Analytical mean
        mu_j_analytical = QoI.eval_QoI_analyticalmean(mu, cp.Cov(jdist))
        err = abs((mu_js['paraboloid'][0] - mu_j_analytical) / mu_j_analytical)
        self.assertTrue(err < 1e-1)
        # Analytical variance
        var_j_analytical = QoI.eval_QoI_analyticalvariance(mu, cp.Cov(jdist))
        err = abs(
            (var_js['paraboloid'][0, 0] - var_j_analytical) / var_j_analytical)
        self.assertTrue(err < 0.01)