def test_prior_conditioned_misfit_covariance_operator(self): num_dims = 3 rank = 2 num_qoi = 2 # define prior prior_mean = np.zeros((num_dims), float) prior_covariance = np.eye(num_dims) prior_hessian = np.eye(num_dims) prior_density = NormalDensity(prior_mean, covariance=prior_covariance) # define observations noise_sigma2 = 0.5 noise_covariance = np.eye(num_qoi)*noise_sigma2 noise_covariance_inv = np.linalg.inv(noise_covariance) noise_covariance_chol_factor = np.linalg.cholesky(noise_covariance) truth_sample = prior_density.generate_samples(1)[:, 0] Amatrix = get_low_rank_matrix(num_qoi, num_dims, rank) noise = np.dot( noise_covariance_chol_factor, np.random.normal(0., 1., num_qoi)) obs = np.dot(Amatrix, truth_sample)+noise # define mistit model misfit_model = QuadraticMisfitModel( num_dims, rank, num_qoi, obs, noise_covariance, Amatrix) # Get analytical mean and covariance exact_laplace_mean, exact_laplace_covariance = \ laplace_posterior_approximation_for_linear_models( misfit_model.Amatrix, prior_mean, prior_hessian, noise_covariance_inv, obs) objective = LogUnormalizedPosterior( misfit_model, misfit_model.gradient_set, prior_density.pdf, prior_density.log_pdf, prior_density.log_pdf_gradient) map_point, obj_min = find_map_point(objective, prior_mean) sample = map_point assert np.allclose(objective.gradient(sample), np.zeros(num_dims)) prior_covariance_sqrt_operator = CholeskySqrtCovarianceOperator( prior_density.covariance) misfit_hessian_operator = MisfitHessianVecOperator( misfit_model, sample, fd_eps=1e-7) standard_svd_opts = { 'num_singular_values': rank, 'num_extra_samples': 10} svd_opts = {'single_pass': False, 'standard_opts': standard_svd_opts} laplace_covariance_sqrt = get_laplace_covariance_sqrt_operator( prior_covariance_sqrt_operator, misfit_hessian_operator, svd_opts) identity = np.eye(num_dims) laplace_covariance_chol_factor = laplace_covariance_sqrt.apply( identity) laplace_covariance = np.dot( laplace_covariance_chol_factor, laplace_covariance_chol_factor.T) # print laplace_covariance # print exact_laplace_covariance assert np.allclose(laplace_covariance, exact_laplace_covariance)
def test_operator_diagonal(self): num_vars = 4 eval_concurrency = 2 randn = np.random.normal(0., 1., (num_vars, num_vars)) prior_covariance = np.dot(randn.T, randn) sqrt_covar_op = CholeskySqrtCovarianceOperator( prior_covariance, eval_concurrency) covariance_operator = CovarianceOperator(sqrt_covar_op) diagonal = get_operator_diagonal( covariance_operator, num_vars, eval_concurrency, transpose=None) assert np.allclose(diagonal, np.diag(prior_covariance))
def test_posterior_dense_matrix_covariance_operator(self): num_vars = 121 rank = 10 eval_concurrency = 20 #randn = np.random.normal(0.,1.,(num_vars,num_vars)) #prior_covariance = np.dot(randn.T,randn) prior_covariance = np.eye(num_vars) prior_sqrt_covariance_op = CholeskySqrtCovarianceOperator( prior_covariance, eval_concurrency) prior = MultivariateGaussian(prior_sqrt_covariance_op) comparison_tol = 6e-7 posterior_covariance_helper( prior, rank, comparison_tol, test_sampling=True)
def test_prior_covariance_operator_based_kle(self): from pyapprox.karhunen_loeve_expansion import correlation_function mesh = np.linspace(0., 1., 10) C = correlation_function(mesh[np.newaxis, :], 0.1, 'exp') #U,S,V = np.linalg.svd(C) #Csqrt = np.dot(U,np.dot(np.diag(np.sqrt(S)),V)) #assert np.allclose(np.dot(Csqrt,Csqrt),C) sqrt_covariance_operator = CholeskySqrtCovarianceOperator(C, 10) covariance_operator = CovarianceOperator( sqrt_covariance_operator) kle = KLE() standard_svd_opts = {'num_singular_values': mesh.shape[0], 'num_extra_samples': 10} svd_opts = {'single_pass': False, 'standard_opts': standard_svd_opts} kle.solve_eigenvalue_problem( covariance_operator, mesh.shape[0], 0., 'randomized-svd', svd_opts) rand_svd_eig_vals = kle.eig_vals.copy() kle.solve_eigenvalue_problem(C, mesh.shape[0], 0., 'eig') eig_eig_vals = kle.eig_vals.copy() assert np.allclose(rand_svd_eig_vals, eig_eig_vals)
def help_generate_and_save_laplace_posterior(self, fault_precentage): svd_history_filename = 'svd-history.npz' Lpost_op_filename = 'laplace_sqrt_operator.npz' prior_variance_filename = 'prior-pointwise-variance.npz' posterior_variance_filename = 'posterior-pointwise-variance.npz' if os.path.exists(svd_history_filename): os.remove(svd_history_filename) if os.path.exists(Lpost_op_filename): os.remove(Lpost_op_filename) if os.path.exists(prior_variance_filename): os.remove(prior_variance_filename) if os.path.exists(posterior_variance_filename): os.remove(posterior_variance_filename) num_vars = 121 rank = 20 eval_concurrency = 2 prior_covariance = np.eye(num_vars) prior_sqrt_covariance_op = CholeskySqrtCovarianceOperator( prior_covariance, eval_concurrency, fault_percentage=2) prior = MultivariateGaussian(prior_sqrt_covariance_op) misfit_model, noise_covariance_inv, obs = \ setup_quadratic_misfit_problem(prior,rank,noise_sigma2=1) # Get analytical mean and covariance prior_hessian = np.linalg.inv(prior_covariance) exact_laplace_mean, exact_laplace_covariance = \ laplace_posterior_approximation_for_linear_models( misfit_model.Amatrix, prior.mean, prior_hessian, noise_covariance_inv, obs) # instead of using optimization to find map point just use exact # map misfit_model.map_point = lambda: exact_laplace_mean num_singular_values = prior.num_vars() try: L_post_op = generate_and_save_laplace_posterior( prior, misfit_model, num_singular_values, svd_history_filename=svd_history_filename, Lpost_op_filename=Lpost_op_filename, num_extra_svd_samples=30, fd_eps=None) except: recovered_svd_data = np.load('randomized_svd_recovery_data.npz') X = recovered_svd_data['X'] Y = recovered_svd_data['Y'] I = np.where(np.all(np.isfinite(Y), axis=0))[0] X = X[:, I] Y = Y[:, I] Q, R = np.linalg.qr(Y) from pyapprox.randomized_svd import svd_using_orthogonal_basis U, S, V = svd_using_orthogonal_basis(None, Q, X, Y, True) U = U[:, :num_singular_values] S = S[:num_singular_values] L_post_op = LaplaceSqrtMatVecOperator(prior_sqrt_covariance_op, e_r=S, V_r=U) L_post_op.save(Lpost_op_filename) L_post_op_from_file = LaplaceSqrtMatVecOperator( prior_sqrt_covariance_op, filename=Lpost_op_filename) # turn off faults in prior to allow easy comparison prior_sqrt_covariance_op.fault_percentage = 0 L_post = L_post_op_from_file.apply(np.eye(num_vars), transpose=False) L_post_T = L_post_op_from_file.apply(np.eye(num_vars), transpose=True) assert_ndarray_allclose(L_post.T, L_post_T, rtol=1e-12) # Test posterior covariance operator produced matrix is the same # as the exact posterior covariance obtained using analytical formula post_covariance = np.dot(L_post, L_post_T) assert_ndarray_allclose(exact_laplace_covariance, post_covariance, rtol=5e-7, atol=0.) prior_pointwise_variance, posterior_pointwise_variance = \ generate_and_save_pointwise_variance( prior, L_post_op_from_file, prior_variance_filename=prior_variance_filename, posterior_variance_filename=posterior_variance_filename) assert_ndarray_allclose(np.diag(exact_laplace_covariance), posterior_pointwise_variance, rtol=3e-11, atol=0.) prior_pointwise_variance=\ np.load(prior_variance_filename)['prior_pointwise_variance'] posterior_pointwise_variance=\ np.load(posterior_variance_filename)['posterior_pointwise_variance'] assert_ndarray_allclose(np.diag(exact_laplace_covariance), posterior_pointwise_variance, rtol=3e-11, atol=0.)