def test_pce_sensitivities_of_sobol_g_function(self): nsamples = 2000 nvars, degree = 3, 8 a = np.array([1, 2, 5])[:nvars] univariate_variables = [uniform(0, 1)] * nvars variable = pya.IndependentMultivariateRandomVariable( univariate_variables) var_trans = pya.AffineRandomVariableTransformation(variable) poly = pya.PolynomialChaosExpansion() poly_opts = pya.define_poly_options_from_variable_transformation( var_trans) poly.configure(poly_opts) indices = pya.tensor_product_indices([degree] * nvars) poly.set_indices(indices) #print('No. PCE Terms',indices.shape[1]) samples = pya.generate_independent_random_samples( var_trans.variable, nsamples) samples = (np.cos(np.random.uniform(0, np.pi, (nvars, nsamples))) + 1) / 2 values = sobol_g_function(a, samples) basis_matrix = poly.basis_matrix(samples) weights = 1 / np.sum(basis_matrix**2, axis=1)[:, np.newaxis] coef = np.linalg.lstsq(basis_matrix * weights, values * weights, rcond=None)[0] poly.set_coefficients(coef) nvalidation_samples = 1000 validation_samples = pya.generate_independent_random_samples( var_trans.variable, nvalidation_samples) validation_values = sobol_g_function(a, validation_samples) poly_validation_vals = poly(validation_samples) rel_error = np.linalg.norm(poly_validation_vals - validation_values ) / np.linalg.norm(validation_values) print('Rel. Error', rel_error) pce_main_effects, pce_total_effects =\ pya.get_main_and_total_effect_indices_from_pce( poly.get_coefficients(), poly.get_indices()) interaction_terms, pce_sobol_indices = get_sobol_indices( poly.get_coefficients(), poly.get_indices(), max_order=3) mean, variance, main_effects, total_effects, sobol_indices = \ get_sobol_g_function_statistics(a, interaction_terms) assert np.allclose(poly.mean(), mean, atol=1e-2) # print((poly.variance(),variance)) assert np.allclose(poly.variance(), variance, atol=1e-2) # print(pce_main_effects,main_effects) assert np.allclose(pce_main_effects, main_effects, atol=1e-2) # print(pce_total_effects,total_effects) assert np.allclose(pce_total_effects, total_effects, atol=1e-2) assert np.allclose(pce_sobol_indices, sobol_indices, atol=1e-2)
def test_pce_sensitivities_of_ishigami_function(self): nsamples = 1500 nvars, degree = 3, 18 univariate_variables = [uniform(-np.pi, 2 * np.pi)] * nvars variable = pya.IndependentMultivariateRandomVariable( univariate_variables) var_trans = pya.AffineRandomVariableTransformation(variable) poly = pya.PolynomialChaosExpansion() poly_opts = pya.define_poly_options_from_variable_transformation( var_trans) poly.configure(poly_opts) indices = pya.compute_hyperbolic_indices(nvars, degree, 1.0) poly.set_indices(indices) #print('No. PCE Terms',indices.shape[1]) samples = pya.generate_independent_random_samples( var_trans.variable, nsamples) values = ishigami_function(samples) basis_matrix = poly.basis_matrix(samples) coef = np.linalg.lstsq(basis_matrix, values, rcond=None)[0] poly.set_coefficients(coef) nvalidation_samples = 1000 validation_samples = pya.generate_independent_random_samples( var_trans.variable, nvalidation_samples) validation_values = ishigami_function(validation_samples) poly_validation_vals = poly(validation_samples) abs_error = np.linalg.norm(poly_validation_vals - validation_values ) / np.sqrt(nvalidation_samples) #print('Abs. Error',abs_error) pce_main_effects, pce_total_effects =\ pya.get_main_and_total_effect_indices_from_pce( poly.get_coefficients(), poly.get_indices()) mean, variance, main_effects, total_effects, sobol_indices, \ sobol_interaction_indices = get_ishigami_funciton_statistics() assert np.allclose(poly.mean(), mean) assert np.allclose(poly.variance(), variance) assert np.allclose(pce_main_effects, main_effects) assert np.allclose(pce_total_effects, total_effects) interaction_terms, pce_sobol_indices = get_sobol_indices( poly.get_coefficients(), poly.get_indices(), max_order=3) assert np.allclose(pce_sobol_indices, sobol_indices)
def test_marginalize_polynomial_chaos_expansions(self): univariate_variables = [uniform(-1, 2), norm(0, 1), uniform(-1, 2)] variable = pya.IndependentMultivariateRandomVariable( univariate_variables) var_trans = pya.AffineRandomVariableTransformation(variable) num_vars = len(univariate_variables) poly = pya.PolynomialChaosExpansion() poly_opts = pya.define_poly_options_from_variable_transformation( var_trans) poly.configure(poly_opts) degree = 2 indices = pya.compute_hyperbolic_indices(num_vars, degree, 1) poly.set_indices(indices) poly.set_coefficients(np.ones((indices.shape[1], 1))) pce_main_effects, pce_total_effects =\ pya.get_main_and_total_effect_indices_from_pce( poly.get_coefficients(), poly.get_indices()) print(poly.num_terms()) for ii in range(num_vars): # Marginalize out 2 variables xx = np.linspace(-1, 1, 101) inactive_idx = np.hstack( (np.arange(ii), np.arange(ii + 1, num_vars))) marginalized_pce = pya.marginalize_polynomial_chaos_expansion( poly, inactive_idx, center=True) mvals = marginalized_pce(xx[None, :]) variable_ii = variable.all_variables()[ii:ii + 1] var_trans_ii = pya.AffineRandomVariableTransformation(variable_ii) poly_ii = pya.PolynomialChaosExpansion() poly_opts_ii = \ pya.define_poly_options_from_variable_transformation( var_trans_ii) poly_ii.configure(poly_opts_ii) indices_ii = compute_hyperbolic_indices(1, degree, 1.) poly_ii.set_indices(indices_ii) poly_ii.set_coefficients(np.ones((indices_ii.shape[1], 1))) pvals = poly_ii(xx[None, :]) # import matplotlib.pyplot as plt # plt.plot(xx, pvals) # plt.plot(xx, mvals, '--') # plt.show() assert np.allclose(mvals, pvals - poly.mean()) assert np.allclose(poly_ii.variance() / poly.variance(), pce_main_effects[ii]) poly_ii.coefficients /= np.sqrt(poly.variance()) assert np.allclose(poly_ii.variance(), pce_main_effects[ii]) # Marginalize out 1 variable xx = pya.cartesian_product([xx] * 2) inactive_idx = np.array([ii]) marginalized_pce = pya.marginalize_polynomial_chaos_expansion( poly, inactive_idx, center=True) mvals = marginalized_pce(xx) variable_ii = variable.all_variables()[:ii] +\ variable.all_variables()[ii+1:] var_trans_ii = pya.AffineRandomVariableTransformation(variable_ii) poly_ii = pya.PolynomialChaosExpansion() poly_opts_ii = \ pya.define_poly_options_from_variable_transformation( var_trans_ii) poly_ii.configure(poly_opts_ii) indices_ii = pya.compute_hyperbolic_indices(2, degree, 1.) poly_ii.set_indices(indices_ii) poly_ii.set_coefficients(np.ones((indices_ii.shape[1], 1))) pvals = poly_ii(xx) assert np.allclose(mvals, pvals - poly.mean())