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 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'])
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 test_SVD_equivalence(self): systemsize = 4 eigen_decayrate = 2.0 # Create Hadmard Quadratic object QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) # Create the joint distribution jdist = cp.J(cp.Uniform(-1,1), cp.Uniform(-1,1), cp.Uniform(-1,1), cp.Uniform(-1,1)) active_subspace_eigen = ActiveSubspace(QoI, n_dominant_dimensions=1, n_monte_carlo_samples=10000, use_svd=False, read_rv_samples=False, write_rv_samples=True) active_subspace_eigen.getDominantDirections(QoI, jdist) active_subspace_svd = ActiveSubspace(QoI, n_dominant_dimensions=1, n_monte_carlo_samples=10000, use_svd=True, read_rv_samples=True, write_rv_samples=False) active_subspace_svd.getDominantDirections(QoI, jdist) # Check the iso_eigenvals np.testing.assert_almost_equal(active_subspace_eigen.iso_eigenvals, active_subspace_svd.iso_eigenvals) # check the iso_eigenvecs self.assertTrue(active_subspace_eigen.iso_eigenvecs.shape, active_subspace_svd.iso_eigenvecs.shape) for i in range(active_subspace_eigen.iso_eigenvecs.shape[1]): arr1 = active_subspace_eigen.iso_eigenvecs[:,i] arr2 = active_subspace_svd.iso_eigenvecs[:,i] if np.allclose(arr1, arr2) == False: np.testing.assert_almost_equal(arr1, -arr2)
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_syntheticEigenValues(self): systemsize = 2 eigen_decayrate = 0.5 # Create Hadmard Quadratic object QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) true_value = np.array([1, 1/np.sqrt(2)]) self.assertTrue((QoI.eigen_vals == true_value).all())
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)
def test_evalQoI(self): systemsize = 4 eigen_decayrate = 2.0 QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) mu = np.ones(systemsize) xi = np.ones(systemsize) fval = QoI.eval_QoI(mu, xi) true_value = 16.0 err = abs(fval - true_value) self.assertTrue(err < 1.e-14)
def test_syntheticEigenVectors(self): systemsize = 4 eigen_decayrate = 0.5 QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) true_value = 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]]) error_vals = QoI.eigen_vectors - true_value self.assertTrue((error_vals < 1.e-15).all())
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)
def test_eval_analytical_QoI_mean(self): systemsize = 4 eigen_decayrate = 2.0 QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) mu = np.ones(systemsize) Sigma = 0.2*np.eye(systemsize) # Covariance matrix fval = QoI.eval_analytical_QoI_mean(mu, Sigma) # Check against stochastic collocation collocation = StochasticCollocation(3, "Normal") sigma = np.diagonal(np.sqrt(Sigma)) # Standard deviation vector QoI_func = QoI.eval_QoI mu_j = collocation.normal.mean(mu, sigma, QoI_func) err = abs(fval - mu_j) self.assertTrue(err < 1.e-14)
def test_evalQoIGradient(self): systemsize = 4 eigen_decayrate = 2.0 QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) mu = np.random.rand(systemsize) xi = np.random.rand(systemsize) grad_val = QoI.eval_QoIGradient(mu, xi) # Check against finite difference def func(x): deviation = x - mu return QoI.eval_QoI(mu, deviation) grad_fd = nd.Gradient(func)(mu + xi) error_vals = abs(grad_val - grad_fd) self.assertTrue((error_vals < 1.e-10).all())
def test_evalQoIHessian(self): systemsize = 4 eigen_decayrate = 2.0 QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) mu = np.zeros(systemsize) xi = np.zeros(systemsize) Hessian = QoI.eval_QoIHessian(mu, xi) # Check against finite difference def func(x): deviation = x - mu return QoI.eval_QoI(mu, deviation) Hess_fd = nd.Hessian(func)(mu + xi) error_vals = abs(Hessian - Hess_fd) self.assertTrue((error_vals < 1.e-10).all())
def test_on_Hadamard_Quadratic(self): systemsize = 4 eigen_decayrate = 2.0 # Create Hadmard Quadratic object QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) # Create the joint distribution jdist = cp.J(cp.Uniform(-1,1), cp.Uniform(-1,1), cp.Uniform(-1,1), cp.Uniform(-1,1)) # Create the active subspace object active_subspace = ActiveSubspace(QoI, n_dominant_dimensions=2, n_monte_carlo_samples=100000) active_subspace.getDominantDirections(QoI, jdist) # Expected C Hessian = QoI.eval_QoIHessian(np.zeros(systemsize), np.zeros(systemsize)) C = np.matmul(Hessian, Hessian) / 3 err = C - active_subspace.C_tilde self.assertTrue((abs(err) < 1.e-2).all())
def test_reducedCollocation(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) QoI_func = QoI.eval_QoI # Check the mean mu_j = collocation.normal.reduced_mean(QoI_func, jdist, dominant_space) true_value_mu_j = 4.05 err = abs(mu_j - true_value_mu_j) self.assertTrue(err < 1.e-13) # Check the variance red_var_j = collocation.normal.reduced_variance( QoI_func, jdist, dominant_space, mu_j) # var_j = collocation.normal.variance(QoI_func, jdist, mu_j) analytical_var_j = QoI.eval_analytical_QoI_variance(x, cp.Cov(jdist)) err = abs(analytical_var_j - red_var_j) self.assertTrue(err < 1.e-4)
def test_dimensionReduction_arnoldi_enlarge(self): systemsize = 128 eigen_decayrate = 1.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_exactHess = DimensionReduction( threshold_factor=threshold_factor, exact_Hessian=True) dominant_space_arnoldi = DimensionReduction(exact_Hessian=False, n_arnoldi_sample=71) # Initialize chaospy distribution std_dev = np.random.rand(QoI.systemsize) x = np.random.rand(QoI.systemsize) jdist = cp.MvNormal(x, np.diag(std_dev)) # Get the eigenmodes of the Hessian product and the dominant indices dominant_space_exactHess.getDominantDirections(QoI, jdist) dominant_space_arnoldi.getDominantDirections(QoI, jdist) # Print iso_eigenvals sort_ind1 = dominant_space_exactHess.iso_eigenvals.argsort()[::-1] sort_ind2 = dominant_space_arnoldi.iso_eigenvals.argsort()[::-1] lambda_exact = dominant_space_exactHess.iso_eigenvals[sort_ind1] lambda_arnoldi = dominant_space_arnoldi.iso_eigenvals[sort_ind2] energy_err = np.linalg.norm(lambda_arnoldi[0:10] - lambda_exact[0:10]) / np.linalg.norm( lambda_exact[0:10]) self.assertTrue(energy_err < 1.e-8)
def run_hadamard(systemsize, eigen_decayrate, std_dev, n_eigenmodes): n_collocation_pts = 3 # Create Hadmard Quadratic object QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate) # Initialize chaospy distribution x = np.random.rand(QoI.systemsize) jdist = cp.MvNormal(x, np.diag(std_dev)) threshold_factor = 1.0 use_exact_Hessian = False if use_exact_Hessian: dominant_space = DimensionReduction(threshold_factor=threshold_factor, exact_Hessian=True) dominant_space.getDominantDirections(QoI, jdist) dominant_dir = dominant_space.iso_eigenvecs[:, 0:n_eigenmodes] else: 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) dominant_dir = dominant_space.dominant_dir # print "dominant_indices = ", dominant_space.dominant_indices # Create stochastic collocation object # collocation = StochasticCollocation(n_collocation_pts, "Normal") 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_dir) sc_obj.evaluateQoIs(jdist) # Collocate # mu_j = collocation.normal.reduced_mean(QoI, jdist, dominant_space) mu_j = sc_obj.mean(of=['Hadamard']) var_j = sc_obj.variance(of=['Hadamard']) std_dev_j = np.sqrt(var_j['Hadamard']) # print "mu_j = ", mu_j # Evaluate the analytical value of the Hadamard Quadratic covariance = cp.Cov(jdist) mu_analytic = QoI.eval_analytical_QoI_mean(x, covariance) var_analytic = QoI.eval_analytical_QoI_variance(x, covariance) std_dev_analytic = np.sqrt(var_analytic) # print "mu_analytic = ", mu_analytic relative_error_mu = np.linalg.norm( (mu_j['Hadamard'] - mu_analytic) / mu_analytic) relative_err_var = np.linalg.norm( (var_j['Hadamard'] - var_analytic) / var_analytic) relative_err_std_dev = np.linalg.norm( (std_dev_j - std_dev_analytic) / std_dev_analytic) # print "relative_error = ", relative_error return relative_error_mu, relative_err_var, relative_err_std_dev