示例#1
0
    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]
示例#2
0
    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]
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
文件: Q_3D.py 项目: yangleicq/BET
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")
示例#7
0
    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)
示例#8
0
        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
示例#9
0
    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
示例#10
0
    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])))
示例#11
0
文件: Q_3D.py 项目: leiyangcq/BET
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")
示例#12
0
 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)
示例#13
0
 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])
示例#14
0
 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])
示例#15
0
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")
示例#16
0
    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)
示例#17
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)
示例#18
0
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])
示例#19
0
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
示例#20
0
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)
示例#21
0
文件: plotDomains.py 项目: UT-CHG/BET
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)
示例#22
0
    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
示例#23
0
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
示例#24
0
    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
示例#25
0
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)
示例#26
0
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])
示例#27
0
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()
示例#28
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')
示例#29
0
# 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,
示例#30
0
    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')
示例#31
0
    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
示例#32
0
# 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
示例#33
0
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)
示例#34
0
# 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)
示例#35
0
    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')
示例#36
0
    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)
示例#38
0
    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
示例#39
0
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
示例#40
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)
示例#41
0
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
示例#42
0
    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
示例#43
0
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