Ejemplo n.º 1
0
    def test_dist_log_exp_norm_vector(self):
        n_samples = 5
        point = self.space_vector.random_point(n_samples)
        base_point = self.space_vector.random_point(n_samples)

        logs = self.space_vector.metric.log(point, base_point)
        normalized_logs = gs.einsum(
            '..., ...j->...j',
            1. / self.space_vector.metric.norm(logs, base_point), logs)
        point = self.space_vector.metric.exp(normalized_logs, base_point)
        result = self.space_vector.metric.dist(point, base_point)

        expected = gs.ones(n_samples)
        self.assertAllClose(result, expected)
Ejemplo n.º 2
0
    def _exp_translation_transform(self, rot_vec):
        base_1 = gs.eye(2)
        base_2 = self.rotations.skew_matrix_from_vector(gs.ones(1))
        cos_coef = rot_vec * utils.taylor_exp_even_func(
            rot_vec**2, utils.cosc_close_0, order=3)
        sin_coef = utils.taylor_exp_even_func(rot_vec**2,
                                              utils.sinc_close_0,
                                              order=3)

        sin_term = gs.einsum('...i,...jk->...jk', sin_coef, base_1)
        cos_term = gs.einsum('...i,...jk->...jk', cos_coef, base_2)
        transform = sin_term + cos_term

        return transform
        def coefficients(ind_k):
            param_k = base_point[..., ind_k]
            param_sum = gs.sum(base_point, -1)
            c1 = 1 / gs.polygamma(1, param_k) / (
                1 / gs.polygamma(1, param_sum)
                - gs.sum(1 / gs.polygamma(1, base_point), -1))
            c2 = - c1 * gs.polygamma(2, param_sum) / gs.polygamma(1, param_sum)

            mat_ones = gs.ones((n_points, self.dim, self.dim))
            mat_diag = from_vector_to_diagonal_matrix(
                - gs.polygamma(2, base_point) / gs.polygamma(1, base_point))
            arrays = [gs.zeros((1, ind_k)),
                      gs.ones((1, 1)),
                      gs.zeros((1, self.dim - ind_k - 1))]
            vec_k = gs.tile(gs.hstack(arrays), (n_points, 1))
            val_k = gs.polygamma(2, param_k) / gs.polygamma(1, param_k)
            vec_k = gs.einsum('i,ij->ij', val_k, vec_k)
            mat_k = from_vector_to_diagonal_matrix(vec_k)

            mat = gs.einsum('i,ijk->ijk', c2, mat_ones)\
                - gs.einsum('i,ijk->ijk', c1, mat_diag) + mat_k

            return 1 / 2 * mat
 def test_dist_log_exp_norm_matrix(self):
     n_samples = 10
     point = self.space_matrix.random_point(n_samples)
     base_point = self.space_matrix.random_point(n_samples)
     logs = self.space_matrix.metric.log(point, base_point)
     normalized_logs = gs.einsum(
         "..., ...jl->...jl",
         1.0 / self.space_matrix.metric.norm(logs, base_point),
         logs,
     )
     point = self.space_matrix.metric.exp(normalized_logs, base_point)
     result = self.space_matrix.metric.dist(point, base_point)
     expected = gs.ones((n_samples, ))
     self.assertAllClose(result, expected)
Ejemplo n.º 5
0
 def test_random_gaussian_rotation_orbit_noisy(self):
     """Test random_gaussian_rotation_orbit"""
     n = 2
     self.setUp_alt(n)
     mean_spd = self.space.random_uniform()
     var_rotations = 1.
     var_eigenvalues = gs.ones(n)
     points = self.space.random_gaussian_rotation_orbit_noisy(
         mean_spd=mean_spd,
         var_rotations=var_rotations,
         var_eigenvalues=var_eigenvalues,
         n_samples=4)
     result = self.space.belongs(points)
     expected = gs.array([True] * 4)
     self.assertAllClose(result, expected)
Ejemplo n.º 6
0
    def test_point_to_pdf_vectorization(self):
        """Test point_to_pdf.

        Check vectorization of the computation of the pdf.
        """
        n_points = 2
        points = self.dirichlet.random_point(n_points)
        pdfs = self.dirichlet.point_to_pdf(points)
        alpha = gs.ones(self.dim)
        samples = self.dirichlet.sample(alpha, self.n_samples)
        result = pdfs(samples)
        pdf1 = [dirichlet.pdf(x, points[0, :]) for x in samples]
        pdf2 = [dirichlet.pdf(x, points[1, :]) for x in samples]
        expected = gs.stack([gs.array(pdf1), gs.array(pdf2)], axis=0)
        self.assertAllClose(result, expected)
Ejemplo n.º 7
0
    def regularize_tangent_vec_at_identity(self,
                                           tangent_vec,
                                           metric=None,
                                           point_type=None):
        """Regularize a tangent vector at the identity.

        Parameters
        ----------
        tangent_vec: array-like, shape=[n_samples, {dim, [n + 1, n + 1]}]
        metric : RiemannianMetric, optional
        point_type : str, {'vector', 'matrix'}, optional
            default: self.default_point_type

        Returns
        -------
        regularized_vec : the regularized tangent vector
        """
        if point_type == 'vector':
            return self.regularize_tangent_vec(tangent_vec,
                                               self.identity,
                                               metric,
                                               point_type=point_type)

        if point_type == 'matrix':
            translation_mask = gs.hstack(
                [gs.ones((self.n, ) * 2), 2 * gs.ones((self.n, 1))])
            translation_mask = gs.concatenate(
                [translation_mask, gs.zeros((1, self.n + 1))], axis=0)
            tangent_vec = tangent_vec * gs.where(translation_mask != 0.,
                                                 gs.array(1.), gs.array(0.))
            tangent_vec = (tangent_vec -
                           GeneralLinear.transpose(tangent_vec)) / 2.
            return tangent_vec * translation_mask

        raise ValueError('Invalid point_type, expected \'vector\' or '
                         '\'matrix\'.')
Ejemplo n.º 8
0
 def is_centered_test_data(self):
     random_data = [
         dict(
             k_landmarks=4,
             m_ambient=3,
             point=gs.ones((4, 3)),
             expected=gs.array(False),
         ),
         dict(
             k_landmarks=4,
             m_ambient=3,
             point=gs.zeros((4, 3)),
             expected=gs.array(True),
         ),
     ]
     return self.generate_tests([], random_data)
Ejemplo n.º 9
0
    def predict(self, X):
        """Perform prediction.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features)
            The training input samples.

        Returns
        -------
        y : ndarray, shape (n_samples,)
            Returns an array of ones.
        """
        X = check_array(X, accept_sparse=True)
        check_is_fitted(self, "is_fitted_")
        return gs.ones(X.shape[0], dtype=gs.int64)
Ejemplo n.º 10
0
 def from_vector(vec, dtype=gs.float32):
     """Convert a vector into a symmetric matrix."""
     vec_dim = vec.shape[-1]
     mat_dim = (gs.sqrt(8. * vec_dim + 1) - 1) / 2
     if mat_dim != int(mat_dim):
         raise ValueError('Invalid input dimension, it must be of the form'
                          '(n_samples, n * (n + 1) / 2)')
     mat_dim = int(mat_dim)
     shape = (mat_dim, mat_dim)
     mask = 2 * gs.ones(shape) - gs.eye(mat_dim)
     indices = list(zip(*gs.triu_indices(mat_dim)))
     vec = gs.cast(vec, dtype)
     upper_triangular = gs.stack(
         [gs.array_from_sparse(indices, data, shape) for data in vec])
     mat = Matrices.to_symmetric(upper_triangular) * mask
     return mat
Ejemplo n.º 11
0
    def test_is_single_matrix_pd(self):
        pd = gs.eye(3)
        not_pd_1 = -1 * gs.eye(3)
        not_pd_2 = gs.ones((3, 3))

        pd_result = gs.linalg.is_single_matrix_pd(pd)
        not_pd_1_result = gs.linalg.is_single_matrix_pd(not_pd_1)
        not_pd_2_result = gs.linalg.is_single_matrix_pd(not_pd_2)

        pd_expected = gs.array(True)
        not_pd_1_expected = gs.array(False)
        not_pd_2_expected = gs.array(False)

        self.assertAllClose(pd_expected, pd_result)
        self.assertAllClose(not_pd_1_expected, not_pd_1_result)
        self.assertAllClose(not_pd_2_expected, not_pd_2_result)
Ejemplo n.º 12
0
    def draw_triangle(self, theta, phi, scale):
        """Draw the corresponding triangle on the sphere at theta, phi."""
        u_theta = gs.cos(theta) * self.ua + gs.sin(theta) * self.na
        triangle = gs.cos(phi / 2.0) * self.pole + gs.sin(phi / 2.0) * u_theta
        triangle = scale * triangle
        triangle3d = gs.transpose(
            gs.stack((triangle[:, 0], triangle[:, 1], 0.5 * gs.ones(3)))
        )
        triangle3d = self.rotation(theta, phi) @ gs.transpose(triangle3d)

        x = list(triangle3d[0]) + [triangle3d[0, 0]]
        y = list(triangle3d[1]) + [triangle3d[1, 0]]
        z = list(triangle3d[2]) + [triangle3d[2, 0]]

        self.ax.plot3D(x, y, z, "grey", zorder=1)
        c = ["red", "green", "blue"]
        for i in range(3):
            self.ax.scatter(x[i], y[i], z[i], color=c[i], s=10, alpha=1, zorder=1)
Ejemplo n.º 13
0
    def variance(self,
                 points,
                 weights=None,
                 base_point=None,
                 point_type='vector'):
        """Compute variance of (weighted) points wrt a base point.

        Parameters
        ----------
        points: array-like, shape=[n_samples, dimension]
        weights: array-like, shape=[n_samples, 1], optional

        Returns
        -------
        variance
        """
        if point_type == 'vector':
            points = gs.to_ndarray(points, to_ndim=2)
        if point_type == 'matrix':
            points = gs.to_ndarray(points, to_ndim=3)
        n_points = gs.shape(points)[0]

        if weights is None:
            weights = gs.ones((n_points, 1))

        weights = gs.array(weights)
        weights = gs.to_ndarray(weights, to_ndim=2, axis=1)

        sum_weights = gs.sum(weights)

        if base_point is None:
            base_point = self.mean(points, weights)

        variance = 0.

        sq_dists = self.squared_dist(base_point, points)
        variance += gs.einsum('nk,nj->j', weights, sq_dists)

        variance = gs.array(variance)
        variance /= sum_weights

        variance = gs.to_ndarray(variance, to_ndim=1)
        variance = gs.to_ndarray(variance, to_ndim=2, axis=1)
        return variance
Ejemplo n.º 14
0
    def align(self, point, base_point, **kwargs):
        """Align point to base_point.

        Find the optimal rotation R in SO(m) such that the base point and
        R.point are well positioned.

        Parameters
        ----------
        point : array-like, shape=[..., k_landmarks, m_ambient]
            Point on the manifold.
        base_point : array-like, shape=[..., k_landmarks, m_ambient]
            Point on the manifold.

        Returns
        -------
        aligned : array-like, shape=[..., k_landmarks, m_ambient]
            R.point.
        """
        mat = gs.matmul(Matrices.transpose(point), base_point)
        left, singular_values, right = gs.linalg.svd(mat)
        det = gs.linalg.det(mat)
        conditioning = (
            (singular_values[..., -2]
             + gs.sign(det) * singular_values[..., -1]) /
            singular_values[..., 0])
        if gs.any(conditioning < 5e-4):
            logging.warning(f'Singularity close, ill-conditioned matrix '
                            f'encountered: {conditioning}')
        if gs.any(gs.isclose(conditioning, 0.)):
            logging.warning("Alignment matrix is not unique.")
        if gs.any(det < 0):
            ones = gs.ones(self.m_ambient)
            reflection_vec = gs.concatenate(
                [ones[:-1], gs.array([-1.])], axis=0)
            mask = gs.cast(det < 0, gs.float32)
            sign = (mask[..., None] * reflection_vec
                    + (1. - mask)[..., None] * ones)
            j_matrix = from_vector_to_diagonal_matrix(sign)
            rotation = Matrices.mul(
                Matrices.transpose(right), j_matrix, Matrices.transpose(left))
        else:
            rotation = gs.matmul(
                Matrices.transpose(right), Matrices.transpose(left))
        return gs.matmul(point, Matrices.transpose(rotation))
Ejemplo n.º 15
0
    def normalize(self, vector, base_point):
        """Normalize tangent vector at a given point.

        Parameters
        ----------
        vector : array-like, shape=[..., dim]
            Tangent vector at base_point.
        base_point : array-like, shape=[..., dim]
            Point.

        Returns
        -------
        normalized_vector : array-like, shape=[..., dim]
            Unit tangent vector at base_point.
        """
        norm = self.norm(vector, base_point)
        norm = gs.where(norm == 0, gs.ones(norm.shape), norm)
        normalized_vector = gs.einsum("...i,...->...i", vector, 1 / norm)
        return normalized_vector
    def group_exponential_barycenter(self, points, weights=None):
        """
        Compute the group exponential barycenter in SO(n), which is the
        Frechet mean of the canonical bi-invariant metric on SO(n).
        """
        n_points = points.shape[0]
        assert n_points > 0

        if weights is None:
            weights = gs.ones((n_points, 1))

        n_weights = weights.shape[0]
        assert n_points == n_weights

        barycenter = self.bi_invariant_metric.mean(points, weights)

        barycenter = gs.to_ndarray(barycenter, to_ndim=2)
        assert barycenter.ndim == 2, barycenter.ndim
        return barycenter
Ejemplo n.º 17
0
 def test_point_to_pdf(self, point, n_samples):
     point = gs.to_ndarray(point, 2)
     n_points = point.shape[0]
     pdf = self.space().point_to_pdf(point)
     alpha = gs.ones(2)
     samples = self.space().sample(alpha, n_samples)
     result = pdf(samples)
     pdf = []
     for i in range(n_points):
         pdf.append(
             gs.array(
                 [
                     gamma.pdf(x, a=point[i, 0], scale=point[i, 1] / point[i, 0])
                     for x in samples
                 ]
             )
         )
     expected = gs.squeeze(gs.stack(pdf, axis=0))
     self.assertAllClose(result, expected)
Ejemplo n.º 18
0
    def mean(self, points, weights=None):
        """
        The Frechet mean of (weighted) points is the weighted average of
        the points in the Minkowski space.
        """
        if isinstance(points, list):
            points = gs.vstack(points)
        points = gs.to_ndarray(points, to_ndim=2)
        n_points = gs.shape(points)[0]

        if isinstance(weights, list):
            weights = gs.vstack(weights)
        elif weights is None:
            weights = gs.ones((n_points, ))

        weighted_points = gs.einsum('n,nj->nj', weights, points)
        mean = (gs.sum(weighted_points, axis=0) / gs.sum(weights))
        mean = gs.to_ndarray(mean, to_ndim=2)
        return mean
Ejemplo n.º 19
0
def main():
    """Plot the result of a KNN classification on the sphere."""
    sphere = Hypersphere(dim=2)
    sphere_distance = sphere.metric.dist

    n_labels = 2
    n_samples_per_dataset = 10
    n_targets = 200

    dataset_1 = sphere.random_von_mises_fisher(kappa=10,
                                               n_samples=n_samples_per_dataset)
    dataset_2 = -sphere.random_von_mises_fisher(
        kappa=10, n_samples=n_samples_per_dataset)
    training_dataset = gs.concatenate((dataset_1, dataset_2), axis=0)
    labels_dataset_1 = gs.zeros([n_samples_per_dataset], dtype=gs.int64)
    labels_dataset_2 = gs.ones([n_samples_per_dataset], dtype=gs.int64)
    labels = gs.concatenate((labels_dataset_1, labels_dataset_2))
    target = sphere.random_uniform(n_samples=n_targets)

    neigh = KNearestNeighborsClassifier(n_neighbors=2,
                                        distance=sphere_distance)
    neigh.fit(training_dataset, labels)
    target_labels = neigh.predict(target)

    plt.figure(0)
    ax = plt.subplot(111, projection="3d")
    plt.title("Training set")
    sphere_plot = visualization.Sphere()
    sphere_plot.draw(ax=ax)
    for i_label in range(n_labels):
        points_label_i = training_dataset[labels == i_label, ...]
        sphere_plot.draw_points(ax=ax, points=points_label_i)

    plt.figure(1)
    ax = plt.subplot(111, projection="3d")
    plt.title("Classification")
    sphere_plot = visualization.Sphere()
    sphere_plot.draw(ax=ax)
    for i_label in range(n_labels):
        target_points_label_i = target[target_labels == i_label, ...]
        sphere_plot.draw_points(ax=ax, points=target_points_label_i)

    plt.show()
Ejemplo n.º 20
0
    def test_intrinsic_and_extrinsic_coords(self):
        """
        Test that the composition of
        intrinsic_to_extrinsic_coords and
        extrinsic_to_intrinsic_coords
        gives the identity.
        """
        point_int = gs.ones(self.dimension)
        point_ext = self.space.intrinsic_to_extrinsic_coords(point_int)
        result = self.space.extrinsic_to_intrinsic_coords(point_ext)
        expected = point_int
        self.assertAllClose(result, expected)

        point_ext = gs.array([2.0, 1.0, 1.0, 1.0])
        point_int = self.space.to_coordinates(point_ext, "intrinsic")
        result = self.space.from_coordinates(point_int, "intrinsic")
        expected = point_ext

        self.assertAllClose(result, expected)
Ejemplo n.º 21
0
    def random_point(self, n_samples=1):
        """Generate parameters of categorical distributions.

        The Dirichlet distribution on the simplex is used
        to generate parameters.

        Parameters
        ----------
        n_samples : int
            Number of samples.
            Optional, default: 1.

        Returns
        -------
        samples : array-like, shape=[..., dim + 1]
            Sample of points representing categorical distributions.
        """
        samples = dirichlet.rvs(gs.ones(self.dim + 1), size=n_samples)
        return gs.from_numpy(samples)
Ejemplo n.º 22
0
def linear_mean(points, weights=None, point_type='vector'):
    """Compute the weighted linear mean.

    The linear mean is the Frechet mean when points:
    - lie in a Euclidean space with Euclidean metric,
    - lie in a Minkowski space with Minkowski metric.

    Parameters
    ----------
    points : array-like, shape=[n_samples, dim]
        Points to be averaged.
    weights : array-like, shape=[n_samples, 1], optional
        Weights associated to the points.

    Returns
    -------
    mean : array-like, shape=[1, dim]
        Weighted linear mean of the points.
    """
    # TODO(ninamiolane): Factorize this code to handle lists
    # in the whole codebase
    if isinstance(points, list):
        points = gs.stack(points, axis=0)
    if isinstance(weights, list):
        weights = gs.stack(weights, axis=0)

    n_points = geomstats.vectorization.get_n_points(
        points, point_type)

    if weights is None:
        weights = gs.ones((n_points,))
    sum_weights = gs.sum(weights)

    einsum_str = '...,...j->...j'
    if point_type == 'matrix':
        einsum_str = '...,...jk->...jk'

    weighted_points = gs.einsum(einsum_str, weights, points)

    mean = gs.sum(weighted_points, axis=0) / sum_weights
    return mean
 def sectional_curvature_test_data(self):
     dim_list = [1]
     n_samples_list = random.sample(range(1, 4), 2)
     random_data = []
     for dim, n_samples in zip(dim_list, n_samples_list):
         sphere = Hypersphere(dim)
         base_point = sphere.random_uniform()
         tangent_vec_a = sphere.to_tangent(
             gs.random.rand(n_samples, sphere.dim + 1), base_point)
         tangent_vec_b = sphere.to_tangent(
             gs.random.rand(n_samples, sphere.dim + 1), base_point)
         expected = gs.ones(n_samples)  # try shape here
         random_data.append(
             dict(
                 dim=dim,
                 tangent_vec_a=tangent_vec_a,
                 tangent_vec_b=tangent_vec_b,
                 base_point=base_point,
                 expected=expected,
             ), )
     return self.generate_tests(random_data)
Ejemplo n.º 24
0
def linear_mean(points, weights=None, point_type='vector'):
    """Compute the weighted linear mean.

    The linear mean is the Frechet mean when points:
    - lie in a Euclidean space with Euclidean metric,
    - lie in a Minkowski space with Minkowski metric.

    Parameters
    ----------
    points : array-like, shape=[..., dim]
        Points to be averaged.
    weights : array-like, shape=[...,]
        Weights associated to the points.
        Optional, default: None.

    Returns
    -------
    mean : array-like, shape=[dim,]
        Weighted linear mean of the points.
    """
    if isinstance(points, list):
        points = gs.stack(points, axis=0)
    if isinstance(weights, list):
        weights = gs.stack(weights, axis=0)

    n_points = geomstats.vectorization.get_n_points(
        points, point_type)

    if weights is None:
        weights = gs.ones((n_points,))
    sum_weights = gs.sum(weights)

    einsum_str = '...,...j->...j'
    if point_type == 'matrix':
        einsum_str = '...,...jk->...jk'

    weighted_points = gs.einsum(einsum_str, weights, points)

    mean = gs.sum(weighted_points, axis=0) / sum_weights
    return mean
Ejemplo n.º 25
0
    def permute(self, graph_to_permute, permutation):
        r"""Permutation action applied to graph observation.

        Parameters
        ----------
        graph_to_permute : array-like, shape=[..., n, n]
            Input graphs to be permuted.
        permutation: array-like, shape=[..., n]
            Node permutations where in position i we have the value j meaning
            the node i should be permuted with node j.

        Returns
        -------
        graphs_permuted : array-like, shape=[..., n, n]
            Graphs permuted.
        """
        nodes = self.nodes
        single_graph = len(graph_to_permute.shape) < 3
        if single_graph:
            graph_to_permute = [graph_to_permute]
            permutation = [permutation]
        result = []
        for i, p in enumerate(permutation):
            if gs.all(gs.array(nodes) == gs.array(p)):
                result.append(graph_to_permute[i])
            else:
                gtype = graph_to_permute[i].dtype
                permutation_matrix = gs.array_from_sparse(
                    data=gs.ones(nodes, dtype=gtype),
                    indices=list(zip(list(range(nodes)), p)),
                    target_shape=(nodes, nodes),
                )
                result.append(
                    self.adjmat.mul(
                        permutation_matrix,
                        graph_to_permute[i],
                        gs.transpose(permutation_matrix),
                    ))
        return result[0] if single_graph else gs.array(result)
Ejemplo n.º 26
0
    def test_intrinsic_and_extrinsic_coords(self):
        """
        Test that the composition of
        intrinsic_to_extrinsic_coords and
        extrinsic_to_intrinsic_coords
        gives the identity.
        """
        point_int = gs.ones(self.dimension)
        point_ext = self.space.intrinsic_to_extrinsic_coords(point_int)
        result = self.space.extrinsic_to_intrinsic_coords(point_ext)
        expected = point_int
        expected = helper.to_vector(expected)

        gs.testing.assert_allclose(result, expected)

        point_ext = self.space.random_uniform()
        point_int = self.space.extrinsic_to_intrinsic_coords(point_ext)
        result = self.space.intrinsic_to_extrinsic_coords(point_int)
        expected = point_ext
        expected = helper.to_vector(expected)

        gs.testing.assert_allclose(result, expected)
    def test_intrinsic_and_extrinsic_coords(self):
        """
        Test that the composition of
        intrinsic_to_extrinsic_coords and
        extrinsic_to_intrinsic_coords
        gives the identity.
        """
        point_int = gs.ones(self.dimension)
        point_ext = self.space.intrinsic_to_extrinsic_coords(point_int)
        result = self.space.extrinsic_to_intrinsic_coords(point_ext)
        expected = point_int
        expected = helper.to_vector(expected)
        with self.test_session():
            self.assertAllClose(gs.eval(result), gs.eval(expected))

        point_ext = tf.convert_to_tensor([2.0, 1.0, 1.0, 1.0])
        point_int = self.space.extrinsic_to_intrinsic_coords(point_ext)
        result = self.space.intrinsic_to_extrinsic_coords(point_int)
        expected = point_ext
        expected = helper.to_vector(expected)

        with self.test_session():
            self.assertAllClose(gs.eval(result), gs.eval(expected))
Ejemplo n.º 28
0
    def variance(self,
                 points,
                 weights=None,
                 base_point=None,
                 point_type='vector'):
        """
        Variance of (weighted) points wrt a base point.
        """
        if point_type == 'vector':
            points = gs.to_ndarray(points, to_ndim=2)
        if point_type == 'matrix':
            points = gs.to_ndarray(points, to_ndim=3)
        n_points = gs.shape(points)[0]

        if weights is None:
            weights = gs.ones((n_points, 1))

        weights = gs.array(weights)
        weights = gs.to_ndarray(weights, to_ndim=2, axis=1)

        sum_weights = gs.sum(weights)

        if base_point is None:
            base_point = self.mean(points, weights)

        variance = 0.

        sq_dists = self.squared_dist(base_point, points)
        variance += gs.einsum('nk,nj->j', weights, sq_dists)

        variance = gs.array(variance)
        variance /= sum_weights

        variance = gs.to_ndarray(variance, to_ndim=1)
        variance = gs.to_ndarray(variance, to_ndim=2, axis=1)
        return variance
Ejemplo n.º 29
0
def variance(points, base_point, metric, weights=None, point_type='vector'):
    """Variance of (weighted) points wrt a base point.

    Parameters
    ----------
    points : array-like, shape=[n_samples, dimension]

    weights : array-like, shape=[n_samples, 1], optional
    """
    if point_type == 'vector':
        points = gs.to_ndarray(points, to_ndim=2)
        base_point = gs.to_ndarray(base_point, to_ndim=2)
    if point_type == 'matrix':
        points = gs.to_ndarray(points, to_ndim=3)
        base_point = gs.to_ndarray(base_point, to_ndim=3)
    n_points = gs.shape(points)[0]

    if weights is None:
        weights = gs.ones((n_points, 1))

    weights = gs.array(weights)
    weights = gs.to_ndarray(weights, to_ndim=2, axis=1)

    sum_weights = gs.sum(weights)

    var = 0.

    sq_dists = metric.squared_dist(base_point, points)
    var += gs.einsum('nk,nj->j', weights, sq_dists)

    var = gs.array(var)
    var /= sum_weights

    var = gs.to_ndarray(var, to_ndim=1)
    var = gs.to_ndarray(var, to_ndim=2, axis=1)
    return var
Ejemplo n.º 30
0
    def fit(self, X, weights=None):
        r"""Compute the Geometric Median.

        Parameters
        ----------
        X : array-like, shape=[n_samples, n_features]
            Training input samples.
        weights : array-like, shape=[...]
            Weights associated to the points.
            Optional, default: None, in which case
            it is equally weighted

        Returns
        -------
        self : object
            Returns self.
        """
        n_points = X.shape[0]
        current_median = X[-1] if self.init is None else self.init
        if weights is None:
            weights = gs.ones(n_points) / n_points

        for iteration in range(1, self.max_iter + 1):
            new_median = self._iterate_once(current_median, X, weights,
                                            self.lr)
            shift = self.metric.dist(new_median, current_median)
            if shift < gs.atol:
                break

            current_median = new_median
            if self.print_every and (iteration + 1) % self.print_every == 0:
                logging.info(
                    f"iteration: {iteration} curr_median: {current_median}")
        self.estimate_ = current_median

        return self