def setUp(self): # Define the parameter space (Lambda) self.input_dim = 2 self.input_set_rbf = sample.sample_set(self.input_dim) self.input_set_ffd = sample.sample_set(self.input_dim) self.input_set_cfd = sample.sample_set(self.input_dim) self.input_set_centers = sample.sample_set(self.input_dim) self.output_dim = 2 self.output_set_rbf = sample.sample_set(self.output_dim) self.output_set_ffd = sample.sample_set(self.output_dim) self.output_set_cfd = sample.sample_set(self.output_dim) self.lam_domain = np.zeros((self.input_dim, 2)) self.lam_domain[:, 0] = np.zeros(self.input_dim) self.lam_domain[:, 1] = np.ones(self.input_dim) self.input_set_rbf.set_domain(self.lam_domain) self.input_set_ffd.set_domain(self.lam_domain) self.input_set_cfd.set_domain(self.lam_domain) # Choose random centers to cluster points around self.num_centers = 100 np.random.seed(0) self.centers = (self.lam_domain[:, 1] - self.lam_domain[:, 0]) * \ np.random.random((self.num_centers, self.input_dim)) + \ self.lam_domain[:, 0] self.input_set_centers.set_values(self.centers) self.num_close = self.input_dim + 1 self.rvec = 0.01 * np.ones(self.input_dim) self.input_set_rbf = grad.sample_l1_ball(self.input_set_centers, self.num_close, self.rvec) self.input_set_ffd = grad.pick_ffd_points(self.input_set_centers, self.rvec) self.input_set_cfd = grad.pick_cfd_points(self.input_set_centers, self.rvec) # Define a vector valued function f : [0,1]x[0,1] -> [x^2, y^2] def f(x): f = np.zeros(x.shape) f[:, 0] = x[:, 0]**2 f[:, 1] = x[:, 1]**2 return f self.output_set_rbf.set_values(f(self.input_set_rbf.get_values())) self.output_set_ffd.set_values(f(self.input_set_ffd.get_values())) self.output_set_cfd.set_values(f(self.input_set_cfd.get_values())) self.cluster_disc_rbf = sample.discretization( self.input_set_rbf, self.output_set_rbf) self.cluster_disc_ffd = sample.discretization( self.input_set_ffd, self.output_set_ffd) self.cluster_disc_cfd = sample.discretization( self.input_set_cfd, self.output_set_cfd) self.G_exact = np.zeros([self.num_centers, self.output_dim, self.input_dim]) self.G_exact[:, 0, 0] = 2 * self.centers[:, 0] self.G_exact[:, 1, 1] = 2 * self.centers[:, 1]
def setUp(self): # Define the parameter space (Lambda) self.input_dim = 2 self.input_set_rbf = sample.sample_set(self.input_dim) self.input_set_ffd = sample.sample_set(self.input_dim) self.input_set_cfd = sample.sample_set(self.input_dim) self.input_set_centers = sample.sample_set(self.input_dim) self.output_dim = 2 self.output_set_rbf = sample.sample_set(self.output_dim) self.output_set_ffd = sample.sample_set(self.output_dim) self.output_set_cfd = sample.sample_set(self.output_dim) self.lam_domain = np.zeros((self.input_dim, 2)) self.lam_domain[:, 0] = np.zeros(self.input_dim) self.lam_domain[:, 1] = np.ones(self.input_dim) self.input_set_rbf.set_domain(self.lam_domain) self.input_set_ffd.set_domain(self.lam_domain) self.input_set_cfd.set_domain(self.lam_domain) # Choose random centers to cluster points around self.num_centers = 100 np.random.seed(0) self.centers = (self.lam_domain[:, 1] - self.lam_domain[:, 0]) * \ np.random.random((self.num_centers, self.input_dim)) + \ self.lam_domain[:, 0] self.input_set_centers.set_values(self.centers) self.num_close = self.input_dim + 1 self.rvec = 0.01 * np.ones(self.input_dim) self.input_set_rbf = grad.sample_l1_ball(self.input_set_centers, self.num_close, self.rvec) self.input_set_ffd = grad.pick_ffd_points(self.input_set_centers, self.rvec) self.input_set_cfd = grad.pick_cfd_points(self.input_set_centers, self.rvec) # Define a vector valued function f : [0,1]x[0,1] -> [x^2, y^2] def f(x): f = np.zeros(x.shape) f[:, 0] = x[:, 0]**2 f[:, 1] = x[:, 1]**2 return f self.output_set_rbf.set_values(f(self.input_set_rbf.get_values())) self.output_set_ffd.set_values(f(self.input_set_ffd.get_values())) self.output_set_cfd.set_values(f(self.input_set_cfd.get_values())) self.cluster_disc_rbf = sample.discretization(self.input_set_rbf, self.output_set_rbf) self.cluster_disc_ffd = sample.discretization(self.input_set_ffd, self.output_set_ffd) self.cluster_disc_cfd = sample.discretization(self.input_set_cfd, self.output_set_cfd) self.G_exact = np.zeros( [self.num_centers, self.output_dim, self.input_dim]) self.G_exact[:, 0, 0] = 2 * self.centers[:, 0] self.G_exact[:, 1, 1] = 2 * self.centers[:, 1]
def check_show_data_domain_2D(self, ref_markers, ref_colors, triangles, save, filenames): """ Check to see that the :meth:`bet.postTools.plotDomains.show_data_domain_2D` ran without generating an error. """ Q_ref = self.disc._output_sample_set.get_values()[:, [0, 1]] Q_ref = Q_ref[[1, 4], :] data_obj_temp = sample.sample_set(2) data_obj_temp.set_values( self.disc._output_sample_set.get_values()[:, [0, 1]]) disc_obj_temp = sample.discretization( self.disc._input_sample_set, data_obj_temp) try: plotDomains.show_data_domain_2D( disc_obj_temp, Q_ref, ref_markers, ref_colors, triangles=triangles, save=save, filenames=filenames) go = True except (RuntimeError, TypeError, NameError): go = False nptest.assert_equal(go, True)
def check_show_param(self, samples, sample_nos, p_ref, save, lnums, showdim): """ Check to see that the :meth:`bet.postTools.plotDomains.scatter_rhoD` ran without generating an error. """ try: input_sample_set_temp = sample.sample_set(samples.shape[1]) input_sample_set_temp.set_values(samples) disc_obj_temp = sample.discretization(input_sample_set_temp, self.disc._output_sample_set) plotDomains.scatter_rhoD(disc_obj_temp, p_ref, sample_nos, 'input', self.rho_D, lnums, None, showdim, save, False) go = True except (RuntimeError, TypeError, NameError) as error: print("ERROR:", error) print("samples shape:", samples.shape) print("param ref:", p_ref) print("samples nums:", sample_nos) print("save:", save) print("lnums:", lnums) print("showdim:", showdim) go = False nptest.assert_equal(go, True)
def setUp(self): """ Set up problem. """ import numpy.random as rnd rnd.seed(1) self.inputs = samp.sample_set(1) self.outputs = samp.sample_set(1) self.lam_domain = np.zeros((1, 2)) self.lam_domain[:, 0] = 0.0 self.lam_domain[:, 1] = 1.0 self.inputs.set_domain(self.lam_domain) self.inputs.set_values(rnd.rand(100,)) self.num_l_emulate = 1001 self.inputs = bsam.random_sample_set('r', self.inputs.get_domain(), num_samples=1001, globalize=True) self.outputs.set_values(2.0*self.inputs._values) Q_ref = np.mean(self.outputs._values, axis=0) self.inputs_emulated = bsam.random_sample_set('r', self.inputs.get_domain(), num_samples=self.num_l_emulate, globalize=True) self.output_prob = simpleFunP.regular_partition_uniform_distribution_rectangle_scaled( self.outputs, Q_ref=Q_ref, rect_scale=0.2, cells_per_dimension=1) self.disc = samp.discretization(input_sample_set=self.inputs, output_sample_set=self.outputs, output_probability_set=self.output_prob, emulated_input_sample_set=self.inputs_emulated)
def postprocess(station_nums, ref_num): filename = 'P_q' + str(station_nums[0] + 1) + '_q' + str(station_nums[1] + 1) if len(station_nums) == 3: filename += '_q' + str(station_nums[2] + 1) filename += '_ref_' + str(ref_num + 1) data = Q[:, station_nums] output_sample_set = sample.sample_set(data.shape[1]) output_sample_set.set_values(data) q_ref = Q_ref[ref_num, station_nums] # Create Simple function approximation # Save points used to parition D for simple function approximation and the # approximation itself (this can be used to make close comparisions...) output_probability_set = sfun.regular_partition_uniform_distribution_rectangle_scaled(\ output_sample_set, q_ref, rect_scale=0.15, cells_per_dimension=np.ones((data.shape[1],))) my_disc = sample.discretization(input_sample_set, output_sample_set, output_probability_set) # Calclate P on the actual samples with assumption that voronoi cells have # equal size input_sample_set.estimate_volume_mc() print "Calculating prob" calcP.prob(my_disc) sample.save_discretization(my_disc, filename, "prob_solution")
def setUp(self): """ Set up problem. """ import numpy.random as rnd rnd.seed(1) self.inputs = samp.sample_set(1) self.outputs = samp.sample_set(1) self.lam_domain = np.zeros((1, 2)) self.lam_domain[:, 0] = 0.0 self.lam_domain[:, 1] = 1.0 self.inputs.set_domain(self.lam_domain) self.inputs.set_values(rnd.rand(100, )) self.num_l_emulate = 1001 self.inputs = bsam.random_sample_set('r', self.inputs.get_domain(), num_samples=1001, globalize=True) self.outputs.set_values(2.0 * self.inputs._values) Q_ref = np.mean(self.outputs._values, axis=0) self.inputs_emulated = bsam.random_sample_set( 'r', self.inputs.get_domain(), num_samples=self.num_l_emulate, globalize=True) self.output_prob = simpleFunP.regular_partition_uniform_distribution_rectangle_scaled( self.outputs, Q_ref=Q_ref, rect_scale=0.2, cells_per_dimension=1) self.disc = samp.discretization( input_sample_set=self.inputs, output_sample_set=self.outputs, output_probability_set=self.output_prob, emulated_input_sample_set=self.inputs_emulated)
def setUp(self): self.input_dim = 2 self.input_set = sample.sample_set(self.input_dim) self.input_set_centers = sample.sample_set(self.input_dim) self.output_dim_return = 2 self.num_optsets_return = 5 self.radius = 0.01 np.random.seed(0) self.num_centers = 10 self.centers = np.random.random((self.num_centers, self.input_dim)) self.input_set_centers.set_values(self.centers) self.input_set = grad.sample_l1_ball(self.input_set_centers, self.input_dim + 1, self.radius) self.output_dim = 28 self.output_set = sample.sample_set(self.output_dim) coeffs = np.zeros((self.input_dim, 2*self.input_dim)) coeffs = np.append(coeffs, np.random.random((self.input_dim, self.output_dim - 3 * self.input_dim)), axis=1) self.coeffs = np.append(coeffs, np.eye(self.input_dim), axis=1) self.output_set.set_values(self.input_set._values.dot(self.coeffs)) self.my_disc = sample.discretization(self.input_set, self.output_set) self.center_disc = grad.calculate_gradients_rbf(\ self.my_disc, self.num_centers) self.input_set_centers = self.center_disc.get_input_sample_set() self.inner_prod_tol = 0.9 self.measskew_tol = np.inf
def setUp(self): self.input_dim = 2 self.input_set = sample.sample_set(self.input_dim) self.input_set_centers = sample.sample_set(self.input_dim) self.output_dim_return = 2 self.num_optsets_return = 5 self.radius = 0.01 np.random.seed(0) self.num_centers = 10 self.centers = np.random.random((self.num_centers, self.input_dim)) self.input_set_centers.set_values(self.centers) self.input_set = grad.sample_l1_ball(self.input_set_centers, self.input_dim + 1, self.radius) self.output_dim = 28 self.output_set = sample.sample_set(self.output_dim) coeffs = np.zeros((self.input_dim, 2 * self.input_dim)) coeffs = np.append(coeffs, np.random.random( (self.input_dim, self.output_dim - 3 * self.input_dim)), axis=1) self.coeffs = np.append(coeffs, np.eye(self.input_dim), axis=1) self.output_set.set_values(self.input_set._values.dot(self.coeffs)) self.my_disc = sample.discretization(self.input_set, self.output_set) self.center_disc = grad.calculate_gradients_rbf(\ self.my_disc, self.num_centers) self.input_set_centers = self.center_disc.get_input_sample_set() self.inner_prod_tol = 0.9 self.measskew_tol = np.inf
def test_calculate_gradients_cfd(self): """ Test :meth:`bet.sensitivity.gradients.calculate_gradients_cfd`. """ self.output_set = sample.sample_set(self.output_dim) self.cluster_set = grad.pick_cfd_points(self.input_set_centers, self.rvec) num_centers = self.input_set_centers.check_num() self.output_set.set_values(self.cluster_set._values.dot(self.coeffs)) self.cluster_disc = sample.discretization(self.cluster_set, self.output_set) self.center_disc = grad.calculate_gradients_cfd(self.cluster_disc) self.jacobians = self.center_disc._input_sample_set._jacobians # Test the method returns the correct size tensor self.assertEqual(self.jacobians.shape, (self.num_centers, self.output_dim, self.input_dim)) # Test that each vector is normalized or a zero vector normG = np.linalg.norm(self.jacobians, ord=1, axis=2) # If its a zero vectors, make it the unit vector in input_dim self.jacobians[normG==0] = 1.0/self.input_dim nptest.assert_array_almost_equal(np.linalg.norm(self.jacobians, ord=1, axis=2), np.ones((self.jacobians.shape[0], self.jacobians.shape[1])))
def postprocess(station_nums, ref_num): filename = 'P_q'+str(station_nums[0]+1)+'_q'+str(station_nums[1]+1) if len(station_nums) == 3: filename += '_q'+str(station_nums[2]+1) filename += '_ref_'+str(ref_num+1) data = Q[:, station_nums] output_sample_set = sample.sample_set(data.shape[1]) output_sample_set.set_values(data) q_ref = Q_ref[ref_num, station_nums] # Create Simple function approximation # Save points used to parition D for simple function approximation and the # approximation itself (this can be used to make close comparisions...) output_probability_set = sfun.regular_partition_uniform_distribution_rectangle_scaled(\ output_sample_set, q_ref, rect_scale=0.15, cells_per_dimension=np.ones((data.shape[1],))) my_disc = sample.discretization(input_sample_set, output_sample_set, output_probability_set) # Calclate P on the actual samples with assumption that voronoi cells have # equal size input_sample_set.estimate_volume_mc() print "Calculating prob" calcP.prob(my_disc) sample.save_discretization(my_disc, filename, "prob_solution")
def test_discretization(self): r""" Support for passing discretization objects. """ dl = sample.discretization(self.left_set, self.right_set) dr = sample.discretization(self.right_set, self.left_set) mm = compP.compare(dl, dr) nptest.assert_array_equal(self.mtrc.get_left()._values, mm.get_left()._values) nptest.assert_array_equal(self.mtrc.get_right()._values, mm.get_right()._values) mm.set_right(dr) # assuming input sample set mm.set_left(dl) nptest.assert_array_equal(self.mtrc.get_left()._values, mm.get_left()._values) nptest.assert_array_equal(self.mtrc.get_right()._values, mm.get_right()._values)
def test_methods(self): calcP.prob_from_sample_set_with_emulated_volumes(self.set_old, self.set_new, self.set_em) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) calcP.prob_from_sample_set(self.set_old, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) disc = samp.discretization(input_sample_set=self.set_old, output_sample_set=self.set_old) calcP.prob_from_discretization_input(disc, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) num_em = self.set_em.check_num() probs = np.zeros((num_em,)) probs[0:-1] = 1.0/float(num_em-1) self.set_em.set_probabilities(probs) self.set_em.global_to_local() disc = samp.discretization(input_sample_set=self.set_old, output_sample_set=self.set_old, emulated_input_sample_set=self.set_em) calcP.prob_from_discretization_input(disc, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75])
def test_methods(self): calcP.prob_from_sample_set_with_emulated_volumes( self.set_old, self.set_new, self.set_em) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) calcP.prob_from_sample_set(self.set_old, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) disc = samp.discretization(input_sample_set=self.set_old, output_sample_set=self.set_old) calcP.prob_from_discretization_input(disc, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75]) num_em = self.set_em.check_num() probs = np.zeros((num_em, )) probs[0:-1] = 1.0 / float(num_em - 1) self.set_em.set_probabilities(probs) self.set_em.global_to_local() disc = samp.discretization(input_sample_set=self.set_old, output_sample_set=self.set_old, emulated_input_sample_set=self.set_em) calcP.prob_from_discretization_input(disc, self.set_new) nptest.assert_almost_equal(self.set_new._probabilities, [0.25, 0.75])
def postprocess(station_nums, ref_num): filename = 'P_q' + str(station_nums[0] + 1) + \ '_q' + str(station_nums[1] + 1) if len(station_nums) == 3: filename += '_q' + str(station_nums[2] + 1) filename += '_ref_' + str(ref_num + 1) data = Q[:, station_nums] output_sample_set = sample.sample_set(data.shape[1]) output_sample_set.set_values(data) q_ref = Q_ref[ref_num, station_nums] # Create Simple function approximation # Save points used to parition D for simple function approximation and the # approximation itself (this can be used to make close comparisions...) output_probability_set = sfun.regular_partition_uniform_distribution_rectangle_scaled( output_sample_set, q_ref, rect_scale=0.15, cells_per_dimension=np.ones((data.shape[1], ))) num_l_emulate = 1e4 set_emulated = bsam.random_sample_set('r', lam_domain, num_l_emulate) my_disc = sample.discretization(input_sample_set, output_sample_set, output_probability_set, emulated_input_sample_set=set_emulated) print("Finished emulating lambda samples") # Calculate P on lambda emulate print("Calculating prob_on_emulated_samples") calcP.prob_on_emulated_samples(my_disc) sample.save_discretization(my_disc, filename, "prob_on_emulated_samples_solution") # Calclate P on the actual samples with assumption that voronoi cells have # equal size input_sample_set.estimate_volume_mc() print("Calculating prob") calcP.prob(my_disc) sample.save_discretization(my_disc, filename, "prob_solution") # Calculate P on the actual samples estimating voronoi cell volume with MC # integration calcP.prob_with_emulated_volumes(my_disc) print("Calculating prob_with_emulated_volumes") sample.save_discretization(my_disc, filename, "prob_with_emulated_volumes_solution")
def test_sort_by_rho(self): """ Test :meth:`bet.postProcess.postTools.sort_by_rho`. """ disc = sample.discretization(input_sample_set=self.data, output_sample_set=self.data.copy()) (self.data1, _) = postTools.sort_by_rho(disc) self.assertGreater(np.min(self.data1.get_input_sample_set(). get_probabilities()), 0.0) nptest.assert_almost_equal(np.sum(self.data1.get_input_sample_set(). get_probabilities()), 1.0) (self.data2, _) = postTools.sort_by_rho(self.data) self.assertGreater(np.min(self.data2.get_probabilities()), 0.0) nptest.assert_almost_equal(np.sum(self.data2.get_probabilities()), 1.0)
def setUp(self): self.inputs = samp.sample_set(3) self.outputs = samp.sample_set(2) self.inputs.set_values(np.loadtxt(data_path + "/3to2_samples.txt.gz")) self.outputs.set_values(np.loadtxt(data_path + "/3to2_data.txt.gz")) Q_ref = np.array([0.422, 0.9385]) self.output_prob = simpleFunP.regular_partition_uniform_distribution_rectangle_scaled( self.outputs, Q_ref=Q_ref, rect_scale=0.2, cells_per_dimension=1) self.inputs.set_domain(np.array([[0.0, 1.0], [0.0, 1.0], [0.0, 1.0]])) import numpy.random as rnd rnd.seed(1) self.inputs_emulated = bsam.random_sample_set('r', self.inputs.get_domain(), num_samples=1001, globalize=True) self.disc = samp.discretization(input_sample_set=self.inputs, output_sample_set=self.outputs, output_probability_set=self.output_prob, emulated_input_sample_set=self.inputs_emulated)
def sample_prob(percentile, sample_set, sort=True, descending=False): """ This calculates the highest/lowest probability samples whose probability sum to a given value. A new sample_set with the samples corresponding to these highest/lowest probability samples is returned along with the number of samples and the indices. This uses :meth:`~bet.postProcess.sort_by_rho`. The ``descending`` flag determines whether or not to calcuate the highest/lowest. :param percentile: ratio of highest probability samples to select :type percentile: float :param sample_set: Object containing samples and probabilities :type sample_set: :class:`~bet.sample.sample_set_base` or :class:`~bet.sample.discretization` :type indices: :class:`numpy.ndarray` of shape (num_samples,) :param indices: sorting indices :param bool sort: Flag whether or not to sort :param bool descending: Flag order of sorting :param sample_set_out: Object containing sorted samples and probabilities :type sample_set_out: :class:`~bet.sample.sample_set` or :class:`~bet.sample.discretization` :rtype: tuple :returns: ( num_samples, sample_set_out, data) """ if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None else: raise bad_object("Improper sample object") if sort: (sample_set, indices) = sort_by_rho(sample_set) if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None if descending: P_samples = P_samples[::-1] samples = samples[::-1] if lam_vol is not None: lam_vol = lam_vol[::-1] if data is not None: data = data[::-1] indices = indices[::-1] P_sum = np.cumsum(P_samples) num_samples = np.sum(np.logical_and(0.0 < P_sum, P_sum <= percentile)) P_samples = P_samples[0:num_samples] samples = samples[0:num_samples, :] if lam_vol is not None: lam_vol = lam_vol[0:num_samples] if data is not None: if len(data.shape) == 1: data = np.expand_dims(data, axis=1) data = data[0:num_samples, :] if isinstance(sample_set, sample.discretization): samples_out = sample.sample_set(sample_set._input_sample_set.get_dim()) data_out = sample.sample_set(sample_set._output_sample_set.get_dim()) sample_set_out = sample.discretization(samples_out, data_out) sample_set_out._input_sample_set.set_values(samples) sample_set_out._input_sample_set.set_probabilities(P_samples) sample_set_out._input_sample_set.set_volumes(lam_vol) sample_set_out._output_sample_set.set_values(data) else: sample_set_out = sample.sample_set(sample_set.get_dim()) sample_set_out.set_values(samples) sample_set_out.set_probabilities(P_samples) sample_set_out.set_volumes(lam_vol) return (num_samples, sample_set_out, indices[0:num_samples])
def calculate_gradients_cfd(cluster_discretization, normalize=True): """ Approximate gradient vectors at ``num_centers, centers.shape[0]`` points in the parameter space for each QoI map. THIS METHOD IS DEPENDENT ON USING :meth:~bet.sensitivity.pick_cfd_points TO CHOOSE SAMPLES FOR THE CFD STENCIL AROUND EACH CENTER. THE ORDERING MATTERS. :param cluster_discretization: Must contain input and output values for the sample clusters. :type cluster_discretization: :class:`~bet.sample.discretization` :param boolean normalize: If normalize is True, normalize each gradient vector :rtype: :class:`~bet.sample.discretization` :returns: A new :class:`~bet.sample.discretization` that contains only the centers of the clusters and their associated ``_jacobians`` which are tensor representation of the gradient vectors of each QoI map at each point in centers :class:`numpy.ndarray` of shape (num_samples, output_dim, input_dim) """ if cluster_discretization._input_sample_set.get_values() is None \ or cluster_discretization._output_sample_set.get_values() is None: raise ValueError("You must have values to use this method.") samples = cluster_discretization._input_sample_set.get_values() data = cluster_discretization._output_sample_set.get_values() input_dim = cluster_discretization._input_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() output_dim = cluster_discretization._output_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() input_dim = cluster_discretization._input_sample_set.get_dim() num_centers = num_model_samples / (2*input_dim + 1) # Find radii_vec from the first cluster of samples radii_vec = samples[num_centers:num_centers + input_dim, :] - samples[0, :] radii_vec = util.fix_dimensions_vector_2darray(radii_vec.diagonal()) # Clean the data data = util.clean_data(data[num_centers:]) gradient_tensor = np.zeros([num_centers, output_dim, input_dim]) radii_vec = np.tile(np.repeat(radii_vec, output_dim, axis=1), [num_centers, 1]) # Construct indices for CFD gradient approxiation inds = np.repeat(range(0, 2 * input_dim * num_centers, 2 * input_dim), input_dim) + np.tile(range(0, input_dim), num_centers) inds = np.array([inds, inds+input_dim]).transpose() gradient_mat = (data[inds[:, 0]] - data[inds[:, 1]]) * (0.5 / radii_vec) # Reshape and organize gradient_tensor = np.reshape(gradient_mat.transpose(), [output_dim, input_dim, num_centers], order='F').transpose(2, 0, 1) if normalize: # Compute the norm of each vector norm_gradient_tensor = np.linalg.norm(gradient_tensor, ord=1, axis=2) # If it is a zero vector (has 0 norm), set norm=1, avoid divide by zero norm_gradient_tensor[norm_gradient_tensor == 0] = 1.0 # Normalize each gradient vector gradient_tensor = gradient_tensor/np.tile(norm_gradient_tensor, (input_dim, 1, 1)).transpose(1, 2, 0) center_input_sample_set = sample.sample_set(input_dim) center_input_sample_set.set_values(samples[:num_centers, :]) if cluster_discretization._input_sample_set.get_domain() is not None: center_input_sample_set.set_domain(cluster_discretization.\ _input_sample_set.get_domain()) center_input_sample_set.set_jacobians(gradient_tensor) center_output_sample_set = sample.sample_set(output_dim) center_output_sample_set.set_values(data[:num_centers, :]) if cluster_discretization._output_sample_set.get_domain() is not None: center_output_sample_set.set_domain(cluster_discretization.\ _output_sample_set.get_domain()) #center_output_sample_set.set_jacobians(gradient_tensor.transpose()) center_discretization = sample.discretization(center_input_sample_set, center_output_sample_set) return center_discretization
def sort_by_rho(sample_set): """ This sorts the samples within the sample_set by probability density. If a discretization object is given, then the QoI data is also sorted to maintain the correspondence. Any volumes present in the input space (or just the sample object) are also sorted. :param sample_set: Object containing samples and probabilities :type sample_set: :class:`~bet.sample.sample_set_base` or :class:`~bet.sample.discretization` :param indices: sorting indices :type indices: :class:`numpy.ndarray` of shape (num_samples,) :param sample_set_out: Object containing sorted samples and probabilities :type sample_set_out: :class:`~bet.sample.sample_set` or :class:`~bet.sample.discretization` :rtype: tuple :returns: (sample_set_out, indicices) """ if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None else: raise bad_object("Improper sample object") nnz = np.sum(P_samples > 0) if lam_vol is None: indices = np.argsort(P_samples)[::-1][0:nnz] else: indices = np.argsort(P_samples / lam_vol)[::-1][0:nnz] P_samples = P_samples[indices] samples = samples[indices, :] if lam_vol is not None: lam_vol = lam_vol[indices] if data is not None: data = data[indices, :] if isinstance(sample_set, sample.discretization): samples_out = sample.sample_set(sample_set._input_sample_set.get_dim()) data_out = sample.sample_set(sample_set._output_sample_set.get_dim()) sample_set_out = sample.discretization(samples_out, data_out) sample_set_out._input_sample_set.set_values(samples) sample_set_out._input_sample_set.set_probabilities(P_samples) sample_set_out._input_sample_set.set_volumes(lam_vol) sample_set_out._output_sample_set.set_values(data) else: sample_set_out = sample.sample_set(sample_set.get_dim()) sample_set_out.set_values(samples) sample_set_out.set_probabilities(P_samples) sample_set_out.set_volumes(lam_vol) return (sample_set_out, indices)
def show_data_domain_multi(sample_disc, Q_ref=None, Q_nums=None, img_folder='figs/', ref_markers=None, ref_colors=None, showdim=None, file_extension=".png", markersize=75): r""" Plots 2-D projections of the data domain D using a triangulation based on the first two coordinates (parameters) of the generating samples where :math:`Q={q_1, q_i}` for ``i=Q_nums``, with a marker for various :math:`Q_{ref}`. :param sample_disc: Object containing the samples to plot :type sample_disc: :class:`~bet.sample.discretization` :param Q_ref: reference data value :type Q_ref: :class:`numpy.ndarray` of shape (M, mdim) :param list Q_nums: dimensions of the QoI to plot :param string img_folder: folder to save the plots to :param list ref_markers: list of marker types for :math:`Q_{ref}` :param list ref_colors: list of colors for :math:`Q_{ref}` :param showdim: default 1. If int then flag to show all combinations with a given dimension (:math:`q_i`) or if ``all`` show all combinations. :type showdim: int or string :param string file_extension: file extension """ if not isinstance(sample_disc, sample.discretization): raise bad_object("Improper sample object") # Set the default marker and colors if ref_markers is None: ref_markers = markers if ref_colors is None: ref_colors = colors data_obj = sample_disc._output_sample_set sample_obj = sample_disc._input_sample_set if Q_ref is None: Q_ref = data_obj._reference_value # If no specific coordinate numbers are given for the data coordinates # (e.g. i, where \q_i is a coordinate in the data space), then # set them to be the the counting numbers. if Q_nums is None: Q_nums = list(range(data_obj.get_dim())) # If no specific coordinate number of choice is given set to be the first # coordinate direction. if showdim is None: showdim = 0 # Create a folder for these figures if it doesn't already exist if not os.path.isdir(img_folder): os.mkdir(img_folder) # Make sure the shape of Q_ref is correct if Q_ref is not None: Q_ref = util.fix_dimensions_data(Q_ref, data_obj.get_dim()) # Create the triangulization to use to define the topology of the samples # in the data space from the first two parameters in the parameter space triangulation = tri.Triangulation(sample_obj.get_values()[:, 0], sample_obj.get_values()[:, 1]) triangles = triangulation.triangles # Create plots of the showdim^th QoI (q_{showdim}) with all other QoI (q_i) if isinstance(showdim, int): for i in Q_nums: if i != showdim: xlabel = r'$q_{' + str(showdim + 1) + r'}$' ylabel = r'$q_{' + str(i + 1) + r'}$' filenames = [img_folder + 'domain_q' + str(showdim + 1) + '_q' + str(i + 1), img_folder + 'q' + str(showdim + 1) + '_q' + str(i + 1) + '_domain_Q_cs'] data_obj_temp = sample.sample_set(2) data_obj_temp.set_values( data_obj.get_values()[:, [showdim, i]]) sample_disc_temp = sample.discretization( sample_obj, data_obj_temp) if Q_ref is not None: show_data_domain_2D(sample_disc_temp, Q_ref[:, [showdim, i]], ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) else: show_data_domain_2D(sample_disc_temp, None, ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) # Create plots of all combinations of QoI in 2D elif showdim == 'all' or showdim == 'ALL': for x, y in combinations(Q_nums, 2): xlabel = r'$q_{' + str(x + 1) + r'}$' ylabel = r'$q_{' + str(y + 1) + r'}$' filenames = [img_folder + 'domain_q' + str(x + 1) + '_q' + str(y + 1), img_folder + 'q' + str(x + 1) + '_q' + str(y + 1) + '_domain_Q_cs'] data_obj_temp = sample.sample_set(2) data_obj_temp.set_values(data_obj.get_values()[:, [x, y]]) sample_disc_temp = sample.discretization(sample_obj, data_obj_temp) if Q_ref is not None: show_data_domain_2D(sample_disc_temp, Q_ref[:, [x, y]], ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) else: show_data_domain_2D(sample_disc_temp, None, ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize)
def generate_for_input_set(self, input_sample_set, order=0): """ Generates a surrogate discretization based on the input discretization, for a user-defined input sample set. The output sample set values and error estimates are piecewise polynomially defined over input sample set cells from the input discretization. For order 0, both are piecewise constant. For order 1, values are piecewise linear (assuming Jacobians exist), and error estimates are piecewise constant. :param input_sample_set: input sample set for surrogate discretization :type set_old: :class:`~bet.sample.sample_set_base` :param order: Polynomial order :type order: int :rtype: :class:`~bet.sample.discretization` :returns: discretization defining the surrogate model """ # Check inputs if order not in [0, 1]: msg = "Order must be 0 or 1." raise calculateError.wrong_argument_type(msg) input_sample_set.check_num() if input_sample_set._dim != self.input_disc._input_sample_set._dim: msg = "Dimensions of input sets are not equal." raise sample.dim_not_matching(msg) # Give properties from input discretization. if input_sample_set._domain is None: if self.input_disc._input_sample_set._domain is not None: input_sample_set.set_domain(self.input_disc.\ _input_sample_set._domain) if input_sample_set._p_norm is None: if self.input_disc._input_sample_set._p_norm is not None: input_sample_set.set_p_norm(self.input_disc.\ _input_sample_set._p_norm) # Setup dummy discretizion to get pointers # Assumes Voronoi sample set for now output_sample_set = sample.sample_set(self.input_disc.\ _output_sample_set._dim) self.dummy_disc = self.input_disc.copy() self.dummy_disc.set_emulated_input_sample_set(input_sample_set) self.dummy_disc.set_emulated_ii_ptr(globalize=False) if order == 0: # define new values based on piecewise constants new_values_local = self.input_disc._output_sample_set.\ _values[self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_values_local(new_values_local) elif order == 1: # define new values based on piecewise linears using Jacobians if self.input_disc._input_sample_set._jacobians is None: if self.input_disc._input_sample_set._jacobians_local is None: msg = "The input discretization must" msg += " have jacobians defined." raise calculateError.wrong_argument_type(msg) else: self.input_disc._input_sample_set.local_to_global() jac_local = self.input_disc._input_sample_set._jacobians[\ self.dummy_disc._emulated_ii_ptr_local] diff_local = self.input_disc._input_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] - \ input_sample_set._values_local new_values_local = self.input_disc._output_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] new_values_local += np.einsum('ijk,ik->ij', jac_local, diff_local) output_sample_set.set_values_local(new_values_local) # if they exist, define error estimates with piecewise constants if self.input_disc._output_sample_set._error_estimates is not None: new_ee = self.input_disc._output_sample_set._error_estimates[\ self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_error_estimates_local(new_ee) # create discretization object for the surrogate self.surrogate_discretization = sample.discretization(input_sample_set\ =input_sample_set, output_sample_set=output_sample_set, output_probability_set=self.input_disc._output_probability_set) return self.surrogate_discretization
def calculate_gradients_rbf(cluster_discretization, num_centers=None, num_neighbors=None, RBF=None, ep=None, normalize=True): r""" Approximate gradient vectors at ``num_centers, centers.shape[0]`` points in the parameter space for each QoI map using a radial basis function interpolation method. :param cluster_discretization: Must contain input and output values for the sample clusters. :type cluster_discretization: :class:`~bet.sample.discretization` :param int num_centers: The number of cluster centers. :param int num_neighbors: Number of nearest neighbors to use in gradient approximation. Default value is ``input_dim + 2`` :param string RBF: Choice of radial basis function. Default is Gaussian :param float ep: Choice of shape parameter for radial basis function. Default value is 1.0 :param boolean normalize: If normalize is True, normalize each gradient vector :rtype: :class:`~bet.sample.discretization` :returns: A new :class:`~bet.sample.discretization` that contains only the centers of the clusters and their associated ``_jacobians`` which are tensor representation of the gradient vectors of each QoI map at each point in centers :class:`numpy.ndarray` of shape (num_samples, output_dim, input_dim) """ if cluster_discretization._input_sample_set.get_values() is None \ or cluster_discretization._output_sample_set.get_values() is None: raise ValueError("You must have values to use this method.") samples = cluster_discretization._input_sample_set.get_values() data = cluster_discretization._output_sample_set.get_values() input_dim = cluster_discretization._input_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() output_dim = cluster_discretization._output_sample_set.get_dim() if num_neighbors is None: num_neighbors = input_dim + 2 if ep is None: ep = 1.0 if RBF is None: RBF = 'Gaussian' # If centers is None we assume the user chose clusters of size # input_dim + 2 if num_centers is None: num_centers = num_model_samples / (input_dim + 2) centers = samples[:num_centers, :] rbf_tensor = np.zeros([num_centers, num_model_samples, input_dim]) gradient_tensor = np.zeros([num_centers, output_dim, input_dim]) # For each center, interpolate the data using the rbf chosen and # then evaluate the partial derivative of that interpolant at the desired # point. for c in range(num_centers): # Find the k nearest neighbors and their distances to centers[c,:] [r, nearest] = cluster_discretization._input_sample_set.query(\ centers[c, :], k=num_neighbors) r = np.tile(r, (input_dim, 1)) # Compute the linf distances to each of the nearest neighbors diffVec = (centers[c, :] - samples[nearest, :]).transpose() # Compute the l2 distances between pairs of nearest neighbors distMat = spatial.distance_matrix(samples[nearest, :], samples[nearest, :]) # Solve for the rbf weights using interpolation conditions and # evaluate the partial derivatives rbf_mat_values = \ np.linalg.solve(radial_basis_function(distMat, RBF), radial_basis_function_dxi(r, diffVec, RBF, ep) \ .transpose()).transpose() # Construct the finite difference matrices rbf_tensor[c, nearest, :] = rbf_mat_values.transpose() gradient_tensor = rbf_tensor.transpose(2, 0, 1).dot(data).transpose(1, 2, 0) if normalize: # Compute the norm of each vector norm_gradient_tensor = np.linalg.norm(gradient_tensor, ord=1, axis=2) # If it is a zero vector (has 0 norm), set norm=1, avoid divide by zero norm_gradient_tensor[norm_gradient_tensor == 0] = 1.0 # Normalize each gradient vector gradient_tensor = gradient_tensor / np.tile( norm_gradient_tensor, (input_dim, 1, 1)).transpose(1, 2, 0) center_input_sample_set = sample.sample_set(input_dim) center_input_sample_set.set_values(samples[:num_centers, :]) if cluster_discretization._input_sample_set.get_domain() is not None: center_input_sample_set.set_domain(cluster_discretization.\ _input_sample_set.get_domain()) center_input_sample_set.set_jacobians(gradient_tensor) center_output_sample_set = sample.sample_set(output_dim) center_output_sample_set.set_values(data[:num_centers, :]) if cluster_discretization._output_sample_set.get_domain() is not None: center_output_sample_set.set_domain(cluster_discretization.\ _output_sample_set.get_domain()) #center_output_sample_set.set_jacobians(gradient_tensor.transpose()) center_discretization = sample.discretization(center_input_sample_set, center_output_sample_set) return center_discretization
def calculate_for_sample_set_region(self, s_set, region, emulated_set=None): """ Calculate the numerical error estimate for a region of the input space defined by a sample set object. :param s_set: sample set for which to calculate error :type s_set: :class:`bet.sample.sample_set_base` :param region: region of s_set for which to calculate error :type region: int :param emulated_set: sample set for volume emulation :type emulated_sample_set: :class:`bet.sample_set_base` :rtype: float :returns: ``er_est``, the numerical error estimate for the region """ # Set up marker if s_set._region is None: msg = "regions must be defined for the sample set." raise wrong_argument_type(msg) marker = np.equal(s_set._region, region) if not np.any(marker): msg = "The given region does not exist." raise wrong_argument_type(msg) # Setup discretizations if emulated_set is not None: self.disc._input_sample_set.local_to_global() self.disc.globalize_ptrs() self.disc_new.globalize_ptrs() disc = self.disc.copy() disc.set_emulated_input_sample_set(emulated_set) disc.set_emulated_ii_ptr(globalize=False) disc_new_set = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=emulated_set) disc_new_set.set_emulated_ii_ptr(globalize=False) elif self.disc._emulated_input_sample_set is not None: self.disc._input_sample_set.local_to_global() msg = "Using emulated_input_sample_set for volume emulation" logging.warning(msg) self.disc.globalize_ptrs() self.disc_new.globalize_ptrs() disc = self.disc if disc._emulated_ii_ptr_local is None: disc.set_emulated_ii_ptr(globalize=False) self.disc_new.set_emulated_ii_ptr(globalize=False) disc_new_set = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=disc._emulated_input_sample_set) disc_new_set.set_emulated_ii_ptr(globalize=False) else: logging.warning("Using MC assumption for volumes.") return self.calculate_for_sample_set_region_mc(s_set, region) # Setup pointers ptr1 = disc._emulated_ii_ptr_local ptr3 = disc_new_set._emulated_ii_ptr_local # Check if in the region in_A = marker[ptr3] # Loop over contour events and add error contribution er_est = 0.0 ops_num = self.disc._output_probability_set.check_num() for i in range(ops_num): if self.disc._output_probability_set._probabilities[i] > 0.0: # JiA, Ji, Jie, and JiAe are defined ast in # `Butler et al. 2015. <http://arxiv.org/pdf/1407.3851>`_ indices1 = np.equal(self.disc._io_ptr, i) in_Ai1 = indices1[ptr1] indices2 = np.equal(self.disc_new._io_ptr, i) in_Ai2 = indices2[ptr1] JiA_local = float(np.sum(np.logical_and(in_A, in_Ai1))) JiA = comm.allreduce(JiA_local, op=MPI.SUM) Ji_local = float(np.sum(in_Ai1)) Ji = comm.allreduce(Ji_local, op=MPI.SUM) JiAe_local = float(np.sum(np.logical_and(in_A, in_Ai2))) JiAe = comm.allreduce(JiAe_local, op=MPI.SUM) Jie_local = float(np.sum(in_Ai2)) Jie = comm.allreduce(Jie_local, op=MPI.SUM) er_est += self.disc._output_probability_set._probabilities[i]\ * ((JiA*Jie - JiAe*Ji)/(Ji*Jie)) return er_est
def sort_by_rho(sample_set): """ This sorts the samples within the sample_set by probability density. If a discretization object is given, then the QoI data is also sorted to maintain the correspondence. Any volumes present in the input space (or just the sample object) are also sorted. :param sample_set: Object containing samples and probabilities :type sample_set: :class:`~bet.sample.sample_set_base` or :class:`~bet.sample.discretization` :param indices: sorting indices :type indices: :class:`numpy.ndarray` of shape (num_samples,) :param sample_set_out: Object containing sorted samples and probabilities :type sample_set_out: :class:`~bet.sample.sample_set` or :class:`~bet.sample.discretization` :rtype: tuple :returns: (sample_set_out, indicices) """ if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None else: raise bad_object("Improper sample object") nnz = np.sum(P_samples > 0) if lam_vol is None: indices = np.argsort(P_samples)[::-1][0:nnz] else: indices = np.argsort(P_samples/lam_vol)[::-1][0:nnz] P_samples = P_samples[indices] samples = samples[indices, :] if lam_vol is not None: lam_vol = lam_vol[indices] if data is not None: data = data[indices, :] if isinstance(sample_set, sample.discretization): samples_out = sample.sample_set(sample_set._input_sample_set.get_dim()) data_out = sample.sample_set(sample_set._output_sample_set.get_dim()) sample_set_out = sample.discretization(samples_out, data_out) sample_set_out._input_sample_set.set_values(samples) sample_set_out._input_sample_set.set_probabilities(P_samples) sample_set_out._input_sample_set.set_volumes(lam_vol) sample_set_out._output_sample_set.set_values(data) else: sample_set_out = sample.sample_set(sample_set.get_dim()) sample_set_out.set_values(samples) sample_set_out.set_probabilities(P_samples) sample_set_out.set_volumes(lam_vol) return (sample_set_out, indices)
def sample_prob(percentile, sample_set, sort=True, descending=False): """ This calculates the highest/lowest probability samples whose probability sum to a given value. A new sample_set with the samples corresponding to these highest/lowest probability samples is returned along with the number of samples and the indices. This uses :meth:`~bet.postProcess.sort_by_rho`. The ``descending`` flag determines whether or not to calcuate the highest/lowest. :param percentile: ratio of highest probability samples to select :type percentile: float :param sample_set: Object containing samples and probabilities :type sample_set: :class:`~bet.sample.sample_set_base` or :class:`~bet.sample.discretization` :type indices: :class:`numpy.ndarray` of shape (num_samples,) :param indices: sorting indices :param bool sort: Flag whether or not to sort :param bool descending: Flag order of sorting :param sample_set_out: Object containing sorted samples and probabilities :type sample_set_out: :class:`~bet.sample.sample_set` or :class:`~bet.sample.discretization` :rtype: tuple :returns: ( num_samples, sample_set_out, data) """ if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None else: raise bad_object("Improper sample object") if sort: (sample_set, indices) = sort_by_rho(sample_set) if isinstance(sample_set, sample.discretization): samples = sample_set._input_sample_set.get_values() P_samples = sample_set._input_sample_set.get_probabilities() lam_vol = sample_set._input_sample_set.get_volumes() data = sample_set._output_sample_set.get_values() elif isinstance(sample_set, sample.sample_set_base): samples = sample_set.get_values() P_samples = sample_set.get_probabilities() lam_vol = sample_set.get_volumes() data = None if descending: P_samples = P_samples[::-1] samples = samples[::-1] if lam_vol is not None: lam_vol = lam_vol[::-1] if data is not None: data = data[::-1] indices = indices[::-1] P_sum = np.cumsum(P_samples) num_samples = np.sum(np.logical_and(0.0 < P_sum, P_sum <= percentile)) P_samples = P_samples[0:num_samples] samples = samples[0:num_samples, :] if lam_vol is not None: lam_vol = lam_vol[0:num_samples] if data is not None: if len(data.shape) == 1: data = np.expand_dims(data, axis=1) data = data[0:num_samples, :] if isinstance(sample_set, sample.discretization): samples_out = sample.sample_set(sample_set._input_sample_set.get_dim()) data_out = sample.sample_set(sample_set._output_sample_set.get_dim()) sample_set_out = sample.discretization(samples_out, data_out) sample_set_out._input_sample_set.set_values(samples) sample_set_out._input_sample_set.set_probabilities(P_samples) sample_set_out._input_sample_set.set_volumes(lam_vol) sample_set_out._output_sample_set.set_values(data) else: sample_set_out = sample.sample_set(sample_set.get_dim()) sample_set_out.set_values(samples) sample_set_out.set_probabilities(P_samples) sample_set_out.set_volumes(lam_vol) return (num_samples, sample_set_out, indices[0:num_samples])
indexstart = 0 indexstop = 20 qoiIndices = range(indexstart, indexstop) # Initialize the necessary sample objects input_samples = sample.sample_set(2) output_samples = sample.sample_set(1000) # Set the input sample values from the imported file input_samples.set_values(matfile['samples']) # Set the data fromthe imported file output_samples.set_values(matfile['data']) # Create the cluster discretization cluster_discretization = sample.discretization(input_samples, output_samples) # Calculate the gradient vectors at each of the 16 centers for each of the # QoI maps if fd_scheme.upper() in ['RBF']: center_discretization = grad.calculate_gradients_rbf( cluster_discretization, normalize=False) elif fd_scheme.upper() in ['FFD']: center_discretization = grad.calculate_gradients_ffd( cluster_discretization) else: center_discretization = grad.calculate_gradients_cfd( cluster_discretization) input_samples_centers = center_discretization.get_input_sample_set()
rho_left = np.all(np.greater_equal(outputs, rho_left), axis=1) rho_right = np.all(np.less_equal(outputs, rho_right), axis=1) inside = np.logical_and(rho_left, rho_right) max_values = np.repeat(maximum, outputs.shape[0], 0) return inside.astype('float64') * max_values # Read in points_ref and plot results ref_sample = mdat['points_true'] ref_sample = ref_sample[:, 14] # Create input, output, and discretization from data read from file input_sample_set = sample.sample_set(points.shape[0]) input_sample_set.set_values(points.transpose()) input_sample_set.set_domain(param_domain) output_sample_set = sample.sample_set(Q.shape[1]) output_sample_set.set_values(Q) my_disc = sample.discretization(input_sample_set, output_sample_set) # Show the samples in the parameter space pDom.scatter_rhoD(my_disc, rho_D=rho_D, ref_sample=ref_sample, io_flag='input') # Show the corresponding samples in the data space pDom.scatter_rhoD(output_sample_set, rho_D=rho_D, ref_sample=Q_ref, io_flag='output') # Show multiple data domains that correspond with the convex hull of samples in # the parameter space pDom.show_data_domain_multi(my_disc, Q_ref=Q_ref, showdim='all')
# Load data from files # First obtain info on the parameter domain parameter_domain = np.loadtxt("files/lam_domain.txt.gz") #parameter domain parameter_dim = parameter_domain.shape[0] # Create input sample set input_samples = samp.sample_set(parameter_dim) input_samples.set_domain(parameter_domain) input_samples.set_values(np.loadtxt("files/samples.txt.gz")) input_samples.estimate_volume_mc() # Use standard MC estimate of volumes # Choose which QoI to use and create output sample set QoI_indices_observe = np.array([0,1,2,3]) output_samples = samp.sample_set(QoI_indices_observe.size) output_samples.set_values(np.loadtxt("files/data.txt.gz")[:,QoI_indices_observe]) # Create discretization object my_discretization = samp.discretization(input_sample_set=input_samples, output_sample_set=output_samples) # Load the reference parameter and QoI values param_ref = np.loadtxt("files/lam_ref.txt.gz") #reference parameter set Q_ref = np.loadtxt("files/Q_ref.txt.gz")[QoI_indices_observe] #reference QoI set # Plot the data domain plotD.scatter_rhoD(my_discretization, ref_sample=Q_ref, io_flag='output', showdim=2) # Whether or not to use deterministic description of simple function approximation of # ouput probability deterministic_discretize_D = True if deterministic_discretize_D == True: simpleFunP.regular_partition_uniform_distribution_rectangle_scaled(data_set=my_discretization, Q_ref=Q_ref, rect_scale=0.25,
def setUp(self): """ Set up problem. """ # Create sample_set object for input_samples input_samples = sample.sample_set(4) input_samples.set_domain(np.array([[0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0]])) input_samples.set_values(util.meshgrid_ndim( (np.linspace(input_samples.get_domain()[0, 0], input_samples.get_domain()[0, 1], 3), np.linspace(input_samples.get_domain()[1, 0], input_samples.get_domain()[1, 1], 3), np.linspace(input_samples.get_domain()[2, 0], input_samples.get_domain()[2, 1], 3), np.linspace(input_samples.get_domain()[3, 0], input_samples.get_domain()[3, 1], 3)))) input_samples.set_probabilities( (1.0/float(input_samples.get_values().shape[0])) * np.ones((input_samples.get_values().shape[0],))) # Check that probabilities and values arrays have same number of entries input_samples.check_num() # Create sample_set object for output_samples output_samples = sample.sample_set(4) output_samples.set_values(input_samples.get_values()*3.0) output_samples.set_domain(3.0*input_samples.get_domain()) self.disc = sample.discretization(input_samples, output_samples) self.filename = "testfigure" output_ref_datum = np.mean(output_samples.get_domain(), axis=1) bin_size = 0.15*(np.max(output_samples.get_domain(), axis=1) - np.min(output_samples.get_domain(), axis=1)) maximum = 1/np.product(bin_size) def ifun(outputs): """ Indicator function. :param outputs: outputs :type outputs: :class:`numpy.ndarray` of shape (N, ndim) :rtype: :class:`numpy.ndarray` of shape (N,) :returns: 0 if outside of set or positive number if inside set """ left = np.repeat([output_ref_datum-.5*bin_size], outputs.shape[0], 0) right = np.repeat([output_ref_datum+.5*bin_size], outputs.shape[0], 0) left = np.all(np.greater_equal(outputs, left), axis=1) right = np.all(np.less_equal(outputs, right), axis=1) inside = np.logical_and(left, right) max_values = np.repeat(maximum, outputs.shape[0], 0) return inside.astype('float64')*max_values self.rho_D = ifun self.lnums = [1, 2, 3] self.markers = [] for m in Line2D.markers: try: if len(m) == 1 and m != ' ': self.markers.append(m) except TypeError: pass self.colors = ('b', 'g', 'r', 'c', 'm', 'y', 'k')
def generate_for_input_set(self, input_sample_set, order=0): """ Generates a surrogate discretization based on the input discretization, for a user-defined input sample set. The output sample set values and error estimates are piecewise polynomially defined over input sample set cells from the input discretization. For order 0, both are piecewise constant. For order 1, values are piecewise linear (assuming Jacobians exist), and error estimates are piecewise constant. :param input_sample_set: input sample set for surrogate discretization :type set_old: :class:`~bet.sample.sample_set_base` :param order: Polynomial order :type order: int :rtype: :class:`~bet.sample.discretization` :returns: discretization defining the surrogate model """ # Check inputs if order not in [0, 1]: msg = "Order must be 0 or 1." raise calculateError.wrong_argument_type(msg) input_sample_set.check_num() if input_sample_set._dim != self.input_disc._input_sample_set._dim: msg = "Dimensions of input sets are not equal." raise sample.dim_not_matching(msg) # Give properties from input discretization. if input_sample_set._domain is None: if self.input_disc._input_sample_set._domain is not None: input_sample_set.set_domain(self.input_disc.\ _input_sample_set._domain) if input_sample_set._p_norm is None: if self.input_disc._input_sample_set._p_norm is not None: input_sample_set.set_p_norm(self.input_disc.\ _input_sample_set._p_norm) # Setup dummy discretizion to get pointers # Assumes Voronoi sample set for now output_sample_set = sample.sample_set(self.input_disc.\ _output_sample_set._dim) self.dummy_disc = self.input_disc.copy() self.dummy_disc.set_emulated_input_sample_set(input_sample_set) self.dummy_disc.set_emulated_ii_ptr(globalize=False) if order == 0: # define new values based on piecewise constants new_values_local = self.input_disc._output_sample_set.\ _values[self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_values_local(new_values_local) elif order == 1: # define new values based on piecewise linears using Jacobians if self.input_disc._input_sample_set._jacobians is None: if self.input_disc._input_sample_set._jacobians_local is None: msg = "The input discretization must" msg += " have jacobians defined." raise calculateError.wrong_argument_type(msg) else: self.input_disc._input_sample_set.local_to_global() jac_local = self.input_disc._input_sample_set._jacobians[\ self.dummy_disc._emulated_ii_ptr_local] diff_local = self.input_disc._input_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] - \ input_sample_set._values_local new_values_local = self.input_disc._output_sample_set._values[\ self.dummy_disc._emulated_ii_ptr_local] new_values_local += np.einsum('ijk,ik->ij', jac_local, diff_local) output_sample_set.set_values_local(new_values_local) # if they exist, define error estimates with piecewise constants if self.input_disc._output_sample_set._error_estimates is not None: new_ee = self.input_disc._output_sample_set._error_estimates[\ self.dummy_disc._emulated_ii_ptr_local] output_sample_set.set_error_estimates_local(new_ee) # create discretization object for the surrogate self.surrogate_discretization = sample.discretization(input_sample_set\ =input_sample_set, output_sample_set=output_sample_set, output_probability_set=self.input_disc._output_probability_set) return self.surrogate_discretization
# First obtain info on the parameter domain parameter_domain = np.loadtxt("files/lam_domain.txt.gz") # parameter domain parameter_dim = parameter_domain.shape[0] # Create input sample set input_samples = samp.sample_set(parameter_dim) input_samples.set_domain(parameter_domain) input_samples.set_values(np.loadtxt("files/samples.txt.gz")) input_samples.estimate_volume_mc() # Use standard MC estimate of volumes # Choose which QoI to use and create output sample set QoI_indices_observe = np.array([0, 1, 2, 3]) output_samples = samp.sample_set(QoI_indices_observe.size) output_samples.set_values( np.loadtxt("files/data.txt.gz")[:, QoI_indices_observe]) # Create discretization object my_discretization = samp.discretization(input_sample_set=input_samples, output_sample_set=output_samples) # Load the reference parameter and QoI values param_ref = np.loadtxt("files/lam_ref.txt.gz") # reference parameter set # reference QoI set Q_ref = np.loadtxt("files/Q_ref.txt.gz")[QoI_indices_observe] # Plot the data domain plotD.scatter_rhoD(my_discretization, ref_sample=Q_ref, io_flag='output', showdim=2) # Whether or not to use deterministic description of simple function approximation of # ouput probability deterministic_discretize_D = True
def show_data_domain_multi(sample_disc, Q_ref=None, Q_nums=None, img_folder='figs/', ref_markers=None, ref_colors=None, showdim=None, file_extension=".png", markersize=75): r""" Plots 2-D projections of the data domain D using a triangulation based on the first two coordinates (parameters) of the generating samples where :math:`Q={q_1, q_i}` for ``i=Q_nums``, with a marker for various :math:`Q_{ref}`. :param sample_disc: Object containing the samples to plot :type sample_disc: :class:`~bet.sample.discretization` :param Q_ref: reference data value :type Q_ref: :class:`numpy.ndarray` of shape (M, mdim) :param list Q_nums: dimensions of the QoI to plot :param string img_folder: folder to save the plots to :param list ref_markers: list of marker types for :math:`Q_{ref}` :param list ref_colors: list of colors for :math:`Q_{ref}` :param showdim: default 1. If int then flag to show all combinations with a given dimension (:math:`q_i`) or if ``all`` show all combinations. :type showdim: int or string :param string file_extension: file extension """ if not isinstance(sample_disc, sample.discretization): raise bad_object("Improper sample object") # Set the default marker and colors if ref_markers is None: ref_markers = markers if ref_colors is None: ref_colors = colors data_obj = sample_disc._output_sample_set sample_obj = sample_disc._input_sample_set if Q_ref is None: Q_ref = data_obj._reference_value # If no specific coordinate numbers are given for the data coordinates # (e.g. i, where \q_i is a coordinate in the data space), then # set them to be the the counting numbers. if Q_nums is None: Q_nums = list(range(data_obj.get_dim())) # If no specific coordinate number of choice is given set to be the first # coordinate direction. if showdim is None: showdim = 0 # Create a folder for these figures if it doesn't already exist if not os.path.isdir(img_folder): os.mkdir(img_folder) # Make sure the shape of Q_ref is correct if Q_ref is not None: Q_ref = util.fix_dimensions_data(Q_ref, data_obj.get_dim()) # Create the triangulization to use to define the topology of the samples # in the data space from the first two parameters in the parameter space triangulation = tri.Triangulation(sample_obj.get_values()[:, 0], sample_obj.get_values()[:, 1]) triangles = triangulation.triangles # Create plots of the showdim^th QoI (q_{showdim}) with all other QoI (q_i) if isinstance(showdim, int): for i in Q_nums: if i != showdim: xlabel = r'$q_{' + str(showdim + 1) + r'}$' ylabel = r'$q_{' + str(i + 1) + r'}$' filenames = [ img_folder + 'domain_q' + str(showdim + 1) + '_q' + str(i + 1), img_folder + 'q' + str(showdim + 1) + '_q' + str(i + 1) + '_domain_Q_cs' ] data_obj_temp = sample.sample_set(2) data_obj_temp.set_values(data_obj.get_values()[:, [showdim, i]]) sample_disc_temp = sample.discretization( sample_obj, data_obj_temp) if Q_ref is not None: show_data_domain_2D(sample_disc_temp, Q_ref[:, [showdim, i]], ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) else: show_data_domain_2D(sample_disc_temp, None, ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) # Create plots of all combinations of QoI in 2D elif showdim == 'all' or showdim == 'ALL': for x, y in combinations(Q_nums, 2): xlabel = r'$q_{' + str(x + 1) + r'}$' ylabel = r'$q_{' + str(y + 1) + r'}$' filenames = [ img_folder + 'domain_q' + str(x + 1) + '_q' + str(y + 1), img_folder + 'q' + str(x + 1) + '_q' + str(y + 1) + '_domain_Q_cs' ] data_obj_temp = sample.sample_set(2) data_obj_temp.set_values(data_obj.get_values()[:, [x, y]]) sample_disc_temp = sample.discretization(sample_obj, data_obj_temp) if Q_ref is not None: show_data_domain_2D(sample_disc_temp, Q_ref[:, [x, y]], ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize) else: show_data_domain_2D(sample_disc_temp, None, ref_markers, ref_colors, xlabel=xlabel, ylabel=ylabel, triangles=triangles, save=True, interactive=False, filenames=filenames, file_extension=file_extension, markersize=markersize)
# Choose random samples in parameter space to solve the model input_samples.set_values( np.random.uniform(0, 1, [np.int(num_samples), input_dim])) # Make the MC assumption and compute the volumes of each voronoi cell input_samples.estimate_volume_mc() # Compute the output values with the map Q output_samples.set_values( Q.dot(input_samples.get_values().transpose()).transpose()) # Calculate the gradient vectors at some subset of the samples. Here the # *normalize* argument is set to *True* because we are using bin_ratio to # determine the uncertainty in our data. cluster_discretization = sample.discretization(input_samples, output_samples) # We will approximate the jacobian at each of the centers center_discretization = grad.calculate_gradients_rbf(cluster_discretization, num_centers, normalize=True) # With these gradient vectors, we are now ready to choose an optimal set of # QoIs to use in the inverse problem, based on optimal skewness properites of # QoI vectors. The most robust method for this is # :meth:~bet.sensitivity.chooseQoIs.chooseOptQoIs_large which returns the # best set of 2, 3, 4 ... until input_dim. This method returns a list of # matrices. Each matrix has 10 rows, the first column representing the # average skewness of the Jacobian of Q, and the rest of the columns # the corresponding QoI indices. input_samples_center = center_discretization.get_input_sample_set() best_sets = cqoi.chooseOptQoIs_large(input_samples_center, measure=False)
rho_left = np.repeat([Q_ref-.5*bin_size], outputs.shape[0], 0) rho_right = np.repeat([Q_ref+.5*bin_size], outputs.shape[0], 0) rho_left = np.all(np.greater_equal(outputs, rho_left), axis=1) rho_right = np.all(np.less_equal(outputs, rho_right), axis=1) inside = np.logical_and(rho_left, rho_right) max_values = np.repeat(maximum, outputs.shape[0], 0) return inside.astype('float64')*max_values # Read in points_ref and plot results ref_sample = mdat['points_true'] ref_sample = ref_sample[:, 14] # Create input, output, and discretization from data read from file input_sample_set = sample.sample_set(points.shape[0]) input_sample_set.set_values(points.transpose()) input_sample_set.set_domain(param_domain) output_sample_set = sample.sample_set(Q.shape[1]) output_sample_set.set_values(Q) my_disc = sample.discretization(input_sample_set, output_sample_set) # Show the samples in the parameter space pDom.scatter_rhoD(my_disc, rho_D=rho_D, ref_sample=ref_sample, io_flag='input') # Show the corresponding samples in the data space pDom.scatter_rhoD(output_sample_set, rho_D=rho_D, ref_sample=Q_ref, io_flag='output') # Show multiple data domains that correspond with the convex hull of samples in # the parameter space pDom.show_data_domain_multi(my_disc, Q_ref=Q_ref, showdim='all')
def calculate_for_sample_set_region_mc(self, s_set, region): """ Calculate the numerical error estimate for a region of the input space defined by a sample set object, using the MC assumption. :param s_set: sample set for which to calculate error :type s_set: :class:`bet.sample.sample_set_base` :param region: region of s_set for which to calculate error :type region: int :rtype float :returns: ``er_est``, the numerical error estimate for the region """ # Set up marker if s_set._region is None: msg = "regions must be defined for the sample set." raise wrong_argument_type(msg) marker = np.equal(s_set._region, region) if not np.any(marker): msg = "The given region does not exist." raise wrong_argument_type(msg) disc_new_set = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=self.disc._input_sample_set) disc_new_set.set_emulated_ii_ptr(globalize=False) # Check if in the region in_A = marker[disc_new_set._emulated_ii_ptr_local] # Loop over contour events and add error contribution er_est = 0.0 ops_num = self.disc._output_probability_set.check_num() num_local = self.disc._input_sample_set.check_num_local() self.disc._input_sample_set._error_id_local = np.zeros((num_local,)) for i in range(ops_num): if self.disc._output_probability_set._probabilities[i] > 0.0: # JiA, Ji, Jie, and JiAe are defined ast in # `Butler et al. 2015. <http://arxiv.org/pdf/1407.3851>` in_Ai1 = np.equal(self.disc._io_ptr_local, i) in_Ai2 = np.equal(self.disc_new._io_ptr_local, i) JiA_local = float(np.sum(np.logical_and(in_A, in_Ai1))) JiA = comm.allreduce(JiA_local, op=MPI.SUM) Ji_local = float(np.sum(in_Ai1)) Ji = comm.allreduce(Ji_local, op=MPI.SUM) JiAe_local = float(np.sum(np.logical_and(in_A, in_Ai2))) JiAe = comm.allreduce(JiAe_local, op=MPI.SUM) Jie_local = float(np.sum(in_Ai2)) Jie = comm.allreduce(Jie_local, op=MPI.SUM) if Ji*Jie == 0: er_cont = np.inf else: er_cont = self.disc._output_probability_set._probabilities[i]\ * ((JiA*Jie - JiAe*Ji)/(Ji*Jie)) er_est += er_cont error_cells1 = np.logical_and(np.logical_and(in_Ai1, np.logical_not(in_A)), np.logical_and(in_Ai2, in_A)) error_cells2 = np.logical_and(np.logical_and(in_Ai2, np.logical_not(in_A)), np.logical_and(in_Ai1, in_A)) error_cells3 = np.not_equal(in_Ai1, in_Ai2) error_cells = np.logical_or(error_cells1, error_cells2) error_cells = np.logical_or(error_cells, error_cells3) error_cells_num_local = float(np.sum(error_cells)) error_cells_num = comm.allreduce(error_cells_num_local, op=MPI.SUM) if error_cells_num != 0: self.disc._input_sample_set._error_id_local[error_cells] \ += er_cont/error_cells_num return er_est
# Choose random samples in parameter space to solve the model input_samples.set_values(np.random.uniform(0, 1, [np.int(num_samples), input_dim])) # Make the MC assumption and compute the volumes of each voronoi cell input_samples.estimate_volume_mc() # Compute the output values with the map Q output_samples.set_values(Q.dot(input_samples.get_values().transpose()).\ transpose()) # Calculate the gradient vectors at some subset of the samples. Here the # *normalize* argument is set to *False* because we are using bin_size to # determine the uncertainty in our data. cluster_discretization = sample.discretization(input_samples, output_samples) # We will approximate the jacobian at each of the centers center_discretization = grad.calculate_gradients_rbf(cluster_discretization, num_centers, normalize=False) # With these gradient vectors, we are now ready to choose an optimal set of # QoIs to use in the inverse problem, based on minimizing the support of the # inverse solution (volume). The most robust method for this is # :meth:~bet.sensitivity.chooseQoIs.chooseOptQoIs_large which returns the # best set of 2, 3, 4 ... until input_dim. This method returns a list of # matrices. Each matrix has 10 rows, the first column representing the # expected inverse volume ratio, and the rest of the columns the corresponding # QoI indices. input_samples_center = center_discretization.get_input_sample_set() best_sets = cqoi.chooseOptQoIs_large(input_samples_center, max_qois_return=5, num_optsets_return=2, inner_prod_tol=0.9, measskew_tol=1E2, measure=True)
def compute_QoI_and_create_discretization(self, input_sample_set, savefile=None, globalize=True): """ Samples the model at ``input_sample_set`` and saves the results. Note: There are many ways to generate samples on a regular grid in Numpy and other Python packages. Instead of reimplementing them here we provide sampler that utilizes user specified samples. :param input_sample_set: samples to evaluate the model at :type input_sample_set: :class:`~bet.sample.sample_set` with num_smaples :param string savefile: filename to save samples and data :param bool globalize: Makes local variables global. :rtype: :class:`~bet.sample.discretization` :returns: :class:`~bet.sample.discretization` object which contains input and output of ``num_samples`` """ # Update the number of samples self.num_samples = input_sample_set.check_num() # Solve the model at the samples if input_sample_set._values_local is None: input_sample_set.global_to_local() local_output = self.lb_model(input_sample_set.get_values_local()) if isinstance(local_output, np.ndarray): local_output_values = local_output elif isinstance(local_output, tuple): if len(local_output) == 1: local_output_values = local_output[0] elif len(local_output) == 2 and self.error_estimates: (local_output_values, local_output_ee) = local_output elif len(local_output) == 2 and self.jacobians: (local_output_values, local_output_jac) = local_output elif len(local_output) == 3: (local_output_values, local_output_ee, local_output_jac) = \ local_output else: raise bad_object("lb_model is not returning the proper type") # figure out the dimension of the output if len(local_output_values.shape) <= 1: output_dim = 1 else: output_dim = local_output_values.shape[1] output_sample_set = sample.sample_set(output_dim) output_sample_set.set_values_local(local_output_values) lam_ref = input_sample_set._reference_value if lam_ref is not None: try: if not isinstance(lam_ref, collections.Iterable): lam_ref = np.array([lam_ref]) Q_ref = self.lb_model(lam_ref) output_sample_set.set_reference_value(Q_ref) except ValueError: try: msg = "Model not mapping reference value as expected." msg += "Attempting reshape..." logging.log(20, msg) Q_ref = self.lb_model(lam_ref.reshape(1, -1)) output_sample_set.set_reference_value(Q_ref) except ValueError: logging.log(20, 'Unable to map reference value.') if self.error_estimates: output_sample_set.set_error_estimates_local(local_output_ee) if self.jacobians: input_sample_set.set_jacobians_local(local_output_jac) if globalize: input_sample_set.local_to_global() output_sample_set.local_to_global() else: input_sample_set._values = None comm.barrier() discretization = sample.discretization(input_sample_set, output_sample_set) comm.barrier() mdat = dict() self.update_mdict(mdat) if savefile is not None: self.save(mdat, savefile, discretization, globalize=globalize) comm.barrier() return discretization
indexstart = 0 indexstop = 20 qoiIndices = range(indexstart, indexstop) # Initialize the necessary sample objects input_samples = sample.sample_set(2) output_samples = sample.sample_set(1000) # Set the input sample values from the imported file input_samples.set_values(matfile['samples']) # Set the data fromthe imported file output_samples.set_values(matfile['data']) # Create the cluster discretization cluster_discretization = sample.discretization(input_samples, output_samples) # Calculate the gradient vectors at each of the 16 centers for each of the # QoI maps if fd_scheme.upper() in ['RBF']: center_discretization = grad.calculate_gradients_rbf(cluster_discretization, normalize=False) elif fd_scheme.upper() in ['FFD']: center_discretization = grad.calculate_gradients_ffd(cluster_discretization) else: center_discretization = grad.calculate_gradients_cfd(cluster_discretization) input_samples_centers = center_discretization.get_input_sample_set() # Choose a specific set of QoIs to check the average skewness of index1 = 0
def calculate_for_sample_set_region(self, s_set, region, emulated_set=None): r""" Calculate the sampling error bounds for a region of the input space defined by a sample set object which defines an event :math:`A`. :param s_set: sample set for which to calculate error :type s_set: :class:`bet.sample.sample_set_base` :param int region: region of s_set for which to calculate error :param emulated_set: sample set for volume emulation :type emulated_set: :class:`bet.sample_set_base` :rtype: tuple :returns: (``upper_bound``, ``lower_bound``) the upper and lower bounds for the error. """ # Set up marker self.disc._input_sample_set.local_to_global() if s_set._region is None: msg = "regions must be defined for the sample set." raise wrong_argument_type(msg) marker = np.equal(s_set._region, region) if not np.any(marker): msg = "The given region does not exist." raise wrong_argument_type(msg) # Set up discretizations if emulated_set is not None: disc = self.disc.copy() disc.set_emulated_input_sample_set(emulated_set) disc.set_emulated_ii_ptr(globalize=False) disc_new = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=emulated_set) disc_new.set_emulated_ii_ptr(globalize=False) elif self.disc._emulated_input_sample_set is not None: msg = "Using emulated_input_sample_set for volume emulation" logging.warning(msg) disc = self.disc if disc._emulated_ii_ptr is None: disc.set_emulated_ii_ptr(globalize=False) disc_new = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=self. disc. _emulated_input_sample_set) disc_new.set_emulated_ii_ptr(globalize=False) else: logging.warning("Using MC assumption for calculating volumes.") disc = self.disc.copy() disc.set_emulated_input_sample_set(disc._input_sample_set) disc.set_emulated_ii_ptr(globalize=False) disc_new = samp.discretization(input_sample_set=s_set, output_sample_set=s_set, emulated_input_sample_set=self. disc._input_sample_set) disc_new.set_emulated_ii_ptr(globalize=False) # Emulated points in the the region in_A = marker[disc_new._emulated_ii_ptr_local] upper_bound = 0.0 lower_bound = 0.0 # Loop over contour intervals and add error contributions ops_num = self.disc._output_probability_set.check_num() for i in range(ops_num): # Contribution from contour event :math:`A_{i,N}` if self.disc._output_probability_set._probabilities[i] > 0.0: indices = np.equal(disc._io_ptr, i) in_Ai = indices[disc._emulated_ii_ptr_local] # sum1 :math:`\mu_{\Lambda}(A \cap A_{i,N})` sum1 = np.sum(np.logical_and(in_A, in_Ai)) # sum2 :math:`\mu_{\Lambda}(A_{i,N})` sum2 = np.sum(in_Ai) sum1 = comm.allreduce(sum1, op=MPI.SUM) sum2 = comm.allreduce(sum2, op=MPI.SUM) if sum2 == 0.0: return (float('nan'), float('nan')) E = float(sum1)/float(sum2) in_B_N = np.zeros(in_A.shape, dtype=np.bool) for j in self.B_N[i]: in_B_N = np.logical_or(np.equal(disc. _emulated_ii_ptr_local, j), in_B_N) in_C_N = np.zeros(in_A.shape, dtype=np.bool) for j in self.C_N[i]: in_C_N = np.logical_or(np.equal(disc. _emulated_ii_ptr_local, j), in_C_N) # sum3 :math:`\mu_{\Lambda}(A \cap B_N)` sum3 = np.sum(np.logical_and(in_A, in_B_N)) # sum4 :math:`\mu_{\Lambda}(C_N)` sum4 = np.sum(in_C_N) sum3 = comm.allreduce(sum3, op=MPI.SUM) sum4 = comm.allreduce(sum4, op=MPI.SUM) if sum4 == 0.0: return (float('nan'), float('nan')) term1 = float(sum3)/float(sum4) - E # sum5 :math:`\mu_{\Lambda}(A \cap C_N)` sum5 = np.sum(np.logical_and(in_A, in_C_N)) # sum6 :math:`\mu_{\Lambda}(B_N)` sum6 = np.sum(in_B_N) sum5 = comm.allreduce(sum5, op=MPI.SUM) sum6 = comm.allreduce(sum6, op=MPI.SUM) if sum6 == 0.0: return (float('nan'), float('nan')) term2 = float(sum5)/float(sum6) - E upper_bound += self.disc._output_probability_set.\ _probabilities[i]*max(term1, term2) lower_bound += self.disc._output_probability_set.\ _probabilities[i]*min(term1, term2) return (upper_bound, lower_bound)
def calculate_gradients_cfd(cluster_discretization, normalize=True): """ Approximate gradient vectors at ``num_centers, centers.shape[0]`` points in the parameter space for each QoI map. THIS METHOD IS DEPENDENT ON USING :meth:~bet.sensitivity.pick_cfd_points TO CHOOSE SAMPLES FOR THE CFD STENCIL AROUND EACH CENTER. THE ORDERING MATTERS. :param cluster_discretization: Must contain input and output values for the sample clusters. :type cluster_discretization: :class:`~bet.sample.discretization` :param boolean normalize: If normalize is True, normalize each gradient vector :rtype: :class:`~bet.sample.discretization` :returns: A new :class:`~bet.sample.discretization` that contains only the centers of the clusters and their associated ``_jacobians`` which are tensor representation of the gradient vectors of each QoI map at each point in centers :class:`numpy.ndarray` of shape (num_samples, output_dim, input_dim) """ if cluster_discretization._input_sample_set.get_values() is None \ or cluster_discretization._output_sample_set.get_values() is None: raise ValueError("You must have values to use this method.") samples = cluster_discretization._input_sample_set.get_values() data = cluster_discretization._output_sample_set.get_values() input_dim = cluster_discretization._input_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() output_dim = cluster_discretization._output_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() input_dim = cluster_discretization._input_sample_set.get_dim() num_centers = num_model_samples / (2 * input_dim + 1) # Find radii_vec from the first cluster of samples radii_vec = samples[num_centers:num_centers + input_dim, :] - samples[0, :] radii_vec = util.fix_dimensions_vector_2darray(radii_vec.diagonal()) # Clean the data data = util.clean_data(data[num_centers:]) gradient_tensor = np.zeros([num_centers, output_dim, input_dim]) radii_vec = np.tile(np.repeat(radii_vec, output_dim, axis=1), [num_centers, 1]) # Construct indices for CFD gradient approxiation inds = np.repeat(range(0, 2 * input_dim * num_centers, 2 * input_dim), input_dim) + np.tile(range(0, input_dim), num_centers) inds = np.array([inds, inds + input_dim]).transpose() gradient_mat = (data[inds[:, 0]] - data[inds[:, 1]]) * (0.5 / radii_vec) # Reshape and organize gradient_tensor = np.reshape(gradient_mat.transpose(), [output_dim, input_dim, num_centers], order='F').transpose(2, 0, 1) if normalize: # Compute the norm of each vector norm_gradient_tensor = np.linalg.norm(gradient_tensor, ord=1, axis=2) # If it is a zero vector (has 0 norm), set norm=1, avoid divide by zero norm_gradient_tensor[norm_gradient_tensor == 0] = 1.0 # Normalize each gradient vector gradient_tensor = gradient_tensor / np.tile( norm_gradient_tensor, (input_dim, 1, 1)).transpose(1, 2, 0) center_input_sample_set = sample.sample_set(input_dim) center_input_sample_set.set_values(samples[:num_centers, :]) if cluster_discretization._input_sample_set.get_domain() is not None: center_input_sample_set.set_domain(cluster_discretization.\ _input_sample_set.get_domain()) center_input_sample_set.set_jacobians(gradient_tensor) center_output_sample_set = sample.sample_set(output_dim) center_output_sample_set.set_values(data[:num_centers, :]) if cluster_discretization._output_sample_set.get_domain() is not None: center_output_sample_set.set_domain(cluster_discretization.\ _output_sample_set.get_domain()) #center_output_sample_set.set_jacobians(gradient_tensor.transpose()) center_discretization = sample.discretization(center_input_sample_set, center_output_sample_set) return center_discretization
def compute_QoI_and_create_discretization(self, input_sample_set, savefile=None, globalize=True): """ Samples the model at ``input_sample_set`` and saves the results. Note: There are many ways to generate samples on a regular grid in Numpy and other Python packages. Instead of reimplementing them here we provide sampler that utilizes user specified samples. :param input_sample_set: samples to evaluate the model at :type input_sample_set: :class:`~bet.sample.sample_set` with num_smaples :param string savefile: filename to save samples and data :param bool globalize: Makes local variables global. :rtype: :class:`~bet.sample.discretization` :returns: :class:`~bet.sample.discretization` object which contains input and output of ``num_samples`` """ # Update the number of samples self.num_samples = input_sample_set.check_num() # Solve the model at the samples if input_sample_set._values_local is None: input_sample_set.global_to_local() local_output = self.lb_model( input_sample_set.get_values_local()) if isinstance(local_output, np.ndarray): local_output_values = local_output elif isinstance(local_output, tuple): if len(local_output) == 1: local_output_values = local_output[0] elif len(local_output) == 2 and self.error_estimates: (local_output_values, local_output_ee) = local_output elif len(local_output) == 2 and self.jacobians: (local_output_values, local_output_jac) = local_output elif len(local_output) == 3: (local_output_values, local_output_ee, local_output_jac) = \ local_output else: raise bad_object("lb_model is not returning the proper type") # figure out the dimension of the output if len(local_output_values.shape) <= 1: output_dim = 1 else: output_dim = local_output_values.shape[1] output_sample_set = sample.sample_set(output_dim) output_sample_set.set_values_local(local_output_values) lam_ref = input_sample_set._reference_value if lam_ref is not None: try: if not isinstance(lam_ref, collections.Iterable): lam_ref = np.array([lam_ref]) Q_ref = self.lb_model(lam_ref) output_sample_set.set_reference_value(Q_ref) except ValueError: try: msg = "Model not mapping reference value as expected." msg += "Attempting reshape..." logging.log(20, msg) Q_ref = self.lb_model(lam_ref.reshape(1, -1)) output_sample_set.set_reference_value(Q_ref) except ValueError: logging.log(20, 'Unable to map reference value.') if self.error_estimates: output_sample_set.set_error_estimates_local(local_output_ee) if self.jacobians: input_sample_set.set_jacobians_local(local_output_jac) if globalize: input_sample_set.local_to_global() output_sample_set.local_to_global() else: input_sample_set._values = None comm.barrier() discretization = sample.discretization(input_sample_set, output_sample_set) comm.barrier() mdat = dict() self.update_mdict(mdat) if savefile is not None: self.save(mdat, savefile, discretization, globalize=globalize) comm.barrier() return discretization
def calculate_gradients_rbf(cluster_discretization, num_centers=None, num_neighbors=None, RBF=None, ep=None, normalize=True): r""" Approximate gradient vectors at ``num_centers, centers.shape[0]`` points in the parameter space for each QoI map using a radial basis function interpolation method. :param cluster_discretization: Must contain input and output values for the sample clusters. :type cluster_discretization: :class:`~bet.sample.discretization` :param int num_centers: The number of cluster centers. :param int num_neighbors: Number of nearest neighbors to use in gradient approximation. Default value is ``input_dim + 2`` :param string RBF: Choice of radial basis function. Default is Gaussian :param float ep: Choice of shape parameter for radial basis function. Default value is 1.0 :param boolean normalize: If normalize is True, normalize each gradient vector :rtype: :class:`~bet.sample.discretization` :returns: A new :class:`~bet.sample.discretization` that contains only the centers of the clusters and their associated ``_jacobians`` which are tensor representation of the gradient vectors of each QoI map at each point in centers :class:`numpy.ndarray` of shape (num_samples, output_dim, input_dim) """ if cluster_discretization._input_sample_set.get_values() is None \ or cluster_discretization._output_sample_set.get_values() is None: raise ValueError("You must have values to use this method.") samples = cluster_discretization._input_sample_set.get_values() data = cluster_discretization._output_sample_set.get_values() input_dim = cluster_discretization._input_sample_set.get_dim() num_model_samples = cluster_discretization.check_nums() output_dim = cluster_discretization._output_sample_set.get_dim() if num_neighbors is None: num_neighbors = input_dim + 2 if ep is None: ep = 1.0 if RBF is None: RBF = 'Gaussian' # If centers is None we assume the user chose clusters of size # input_dim + 2 if num_centers is None: num_centers = num_model_samples / (input_dim + 2) centers = samples[:num_centers, :] rbf_tensor = np.zeros([num_centers, num_model_samples, input_dim]) gradient_tensor = np.zeros([num_centers, output_dim, input_dim]) # For each center, interpolate the data using the rbf chosen and # then evaluate the partial derivative of that interpolant at the desired # point. for c in range(num_centers): # Find the k nearest neighbors and their distances to centers[c,:] [r, nearest] = cluster_discretization._input_sample_set.query(\ centers[c, :], k=num_neighbors) r = np.tile(r, (input_dim, 1)) # Compute the linf distances to each of the nearest neighbors diffVec = (centers[c, :] - samples[nearest, :]).transpose() # Compute the l2 distances between pairs of nearest neighbors distMat = spatial.distance_matrix( samples[nearest, :], samples[nearest, :]) # Solve for the rbf weights using interpolation conditions and # evaluate the partial derivatives rbf_mat_values = \ np.linalg.solve(radial_basis_function(distMat, RBF), radial_basis_function_dxi(r, diffVec, RBF, ep) \ .transpose()).transpose() # Construct the finite difference matrices rbf_tensor[c, nearest, :] = rbf_mat_values.transpose() gradient_tensor = rbf_tensor.transpose(2, 0, 1).dot(data).transpose(1, 2, 0) if normalize: # Compute the norm of each vector norm_gradient_tensor = np.linalg.norm(gradient_tensor, ord=1, axis=2) # If it is a zero vector (has 0 norm), set norm=1, avoid divide by zero norm_gradient_tensor[norm_gradient_tensor == 0] = 1.0 # Normalize each gradient vector gradient_tensor = gradient_tensor/np.tile(norm_gradient_tensor, (input_dim, 1, 1)).transpose(1, 2, 0) center_input_sample_set = sample.sample_set(input_dim) center_input_sample_set.set_values(samples[:num_centers, :]) if cluster_discretization._input_sample_set.get_domain() is not None: center_input_sample_set.set_domain(cluster_discretization.\ _input_sample_set.get_domain()) center_input_sample_set.set_jacobians(gradient_tensor) center_output_sample_set = sample.sample_set(output_dim) center_output_sample_set.set_values(data[:num_centers, :]) if cluster_discretization._output_sample_set.get_domain() is not None: center_output_sample_set.set_domain(cluster_discretization.\ _output_sample_set.get_domain()) #center_output_sample_set.set_jacobians(gradient_tensor.transpose()) center_discretization = sample.discretization(center_input_sample_set, center_output_sample_set) return center_discretization