Пример #1
0
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.man = Sphere(m, n)

        # For automatic testing of ehess2rhess
        self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x
Пример #2
0
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.manifold = Sphere(m, n)

        # For automatic testing of euclidean_to_riemannian_hessian
        self.projection = lambda x, u: u - np.tensordot(x, u, np.ndim(u)) * x

        super().setUp()
Пример #3
0
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.euclidean = Euclidean(m, n)
        self.sphere = Sphere(n)
        self.manifold = Product([self.euclidean, self.sphere])

        point = self.manifold.random_point()

        @pymanopt.function.autograd(self.manifold)
        def cost(*x):
            return np.sum([np.linalg.norm(a - b)**2 for a, b in zip(x, point)])

        self.cost = cost
Пример #4
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    n = 128
    matrix = rnd.randn(n, n)
    matrix = 0.5 * (matrix + matrix.T)

    cost, egrad = create_cost_egrad(backend, matrix)
    manifold = Sphere(n)
    problem = pymanopt.Problem(manifold, cost=cost, egrad=egrad)
    if quiet:
        problem.verbosity = 0

    solver = SteepestDescent()
    estimated_dominant_eigenvector = solver.solve(problem)

    if quiet:
        return

    # Calculate the actual solution by a conventional eigenvalue decomposition.
    eigenvalues, eigenvectors = la.eig(matrix)
    dominant_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]

    # Make sure both vectors have the same direction. Both are valid
    # eigenvectors, but for comparison we need to get rid of the sign
    # ambiguity.
    if (np.sign(dominant_eigenvector[0]) != np.sign(
            estimated_dominant_eigenvector[0])):
        estimated_dominant_eigenvector = -estimated_dominant_eigenvector

    # Print information about the solution.
    print("l2-norm of x: %f" % la.norm(dominant_eigenvector))
    print("l2-norm of xopt: %f" % la.norm(estimated_dominant_eigenvector))
    print("Solution found: %s" % np.allclose(
        dominant_eigenvector, estimated_dominant_eigenvector, rtol=1e-3))
    error_norm = la.norm(dominant_eigenvector - estimated_dominant_eigenvector)
    print("l2-error: %f" % error_norm)
Пример #5
0
def max_GtRq_brute(A, B, feedback=0, optimizer='ParticleSwarm', **kwargs):
    """
    Brute force maximization of the Generalized Tensor Rayleigh quotient
    on the sphere. Optimization is performed with Pymanopt.

    :param A: the input tensor
    :param B: the second input tensor
    :param feedback: the feedback level for pymanopt
    :param optimizer: the name of the pymanopt minimizer
    :param kwargs: keyword arguments to pass to the pymanopt solver
    """
    # get dimension:
    d = A.shape[0]
    # initialize:
    manifold = Sphere(d)
    problem = Problem(manifold=manifold,
                      cost=lambda x: -_GtRq_brute_autograd(x, A, B),
                      verbosity=feedback)
    # optimization:
    if optimizer == 'ParticleSwarm':
        solver = pymanopt.solvers.ParticleSwarm(logverbosity=0, **kwargs)
        Xopt = solver.solve(problem)
    elif optimizer == 'TrustRegions':
        solver = pymanopt.solvers.TrustRegions(logverbosity=0, **kwargs)
        Xopt = solver.solve(problem)
    # finalize:
    return _GtRq_brute_autograd(Xopt, A, B), Xopt
Пример #6
0
    def setUp(self):
        self.X = X = T.vector()
        self.cost = T.exp(T.sum(X**2))

        n = self.n = 15

        self.man = Sphere(n)
Пример #7
0
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.man = Sphere(m, n)

        # For automatic testing of ehess2rhess
        self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x
Пример #8
0
    def setUp(self):
        self.n = 15
        self.manifold = Sphere(self.n)

        @pymanopt.function.tensorflow(self.manifold)
        def cost(X):
            return tf.exp(tf.reduce_sum(X**2))

        self.cost = cost
Пример #9
0
    def setUp(self):
        n = 32
        matrix = np.random.normal(size=(n, n))
        self.manifold = manifold = Sphere(n)
        self.max_iterations = 50

        @pymanopt.function.autograd(manifold)
        def cost(point):
            return -point.T @ matrix @ point

        self.problem = pymanopt.Problem(manifold, cost)
Пример #10
0
    def setUp(self):
        X = T.vector()

        @pymanopt.function.Theano(X)
        def cost(X):
            return T.exp(T.sum(X ** 2))

        self.cost = cost

        n = self.n = 15

        self.man = Sphere(n)
Пример #11
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    # Generate random problem data.
    n = 128
    A = np.random.randn(n, n)
    A = 0.5 * (A + A.T)
    cost, egrad = create_cost_egrad(backend, A)

    # Create the problem structure.
    manifold = Sphere(n)
    problem = Problem(manifold=manifold, cost=cost, egrad=egrad)
    if quiet:
        problem.verbosity = 0

    # Numerically check gradient consistency (optional).
    check_gradient(problem)
Пример #12
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    n = 128
    manifold = Sphere(n)

    # Generate random problem data.
    matrix = np.random.normal(size=(n, n))
    matrix = 0.5 * (matrix + matrix.T)
    cost, euclidean_gradient = create_cost_and_derivates(
        manifold, matrix, backend)

    # Create the problem structure.
    problem = Problem(manifold, cost, euclidean_gradient=euclidean_gradient)

    # Numerically check gradient consistency (optional).
    check_gradient(problem)
Пример #13
0
class TestSphereManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.sphere = Sphere(m, n)

    def test_proj(self):
        # Construct a random point X on the manifold.
        X = rnd.randn(self.m, self.n)
        X /= la.norm(X, "fro")

        # Construct a vector H in the ambient space.
        H = rnd.randn(self.m, self.n)

        # Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)),
                                             self.sphere.proj(X, H))
Пример #14
0
def run(backend=SUPPORTED_BACKENDS[0], quiet=True):
    n = 128
    matrix = np.random.normal(size=(n, n))
    matrix = 0.5 * (matrix + matrix.T)

    manifold = Sphere(n)
    cost, euclidean_gradient = create_cost_and_derivates(
        manifold, matrix, backend
    )
    problem = pymanopt.Problem(
        manifold, cost, euclidean_gradient=euclidean_gradient
    )

    optimizer = SteepestDescent(verbosity=2 * int(not quiet))
    estimated_dominant_eigenvector = optimizer.run(problem).point

    if quiet:
        return

    # Calculate the actual solution by a conventional eigenvalue decomposition.
    eigenvalues, eigenvectors = np.linalg.eig(matrix)
    dominant_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]

    # Make sure both vectors have the same direction. Both are valid
    # eigenvectors, but for comparison we need to get rid of the sign
    # ambiguity.
    if np.sign(dominant_eigenvector[0]) != np.sign(
        estimated_dominant_eigenvector[0]
    ):
        estimated_dominant_eigenvector = -estimated_dominant_eigenvector

    # Print information about the solution.
    print("l2-norm of x:", np.linalg.norm(dominant_eigenvector))
    print("l2-norm of xopt:", np.linalg.norm(estimated_dominant_eigenvector))
    print(
        "Solution found:",
        np.allclose(
            dominant_eigenvector, estimated_dominant_eigenvector, atol=1e-6
        ),
    )
    error_norm = np.linalg.norm(
        dominant_eigenvector - estimated_dominant_eigenvector
    )
    print("l2-error:", error_norm)
Пример #15
0
def dominant_eigenvector(A):
    """
    Returns the dominant eigenvector of the symmetric matrix A.

    Note: For the same A, this should yield the same as the dominant invariant
    subspace example with p = 1.
    """
    m, n = A.shape
    assert m == n, "matrix must be square"
    assert np.allclose(np.sum(A - A.T), 0), "matrix must be symmetric"

    manifold = Sphere(n)
    solver = ConjugateGradient(maxiter=500, minstepsize=1e-6)
    x = T.matrix()
    cost = -x.T.dot(T.dot(A, x)).trace()

    problem = Problem(man=manifold, ad_cost=cost, ad_arg=x)
    xopt = solver.solve(problem)
    return xopt.squeeze()
Пример #16
0
class TestSphereManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.man = Sphere(m, n)

        # For automatic testing of ehess2rhess
        self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x

    def test_dim(self):
        assert self.man.dim == self.m * self.n - 1

    def test_typicaldist(self):
        np_testing.assert_almost_equal(self.man.typicaldist, np.pi)

    def test_dist(self):
        s = self.man
        x = s.rand()
        y = s.rand()
        correct_dist = np.arccos(np.tensordot(x, y))
        np.testing.assert_almost_equal(correct_dist, s.dist(x, y))

    def test_inner(self):
        s = self.man
        x = s.rand()
        u = s.randvec(x)
        v = s.randvec(x)
        np.testing.assert_almost_equal(np.sum(u * v), s.inner(x, u, v))

    def test_proj(self):
        #  Construct a random point X on the manifold.
        X = rnd.randn(self.m, self.n)
        X /= la.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = rnd.randn(self.m, self.n)

        #  Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)),
                                             self.man.proj(X, H))

    def test_egrad2rgrad(self):
        # Should be the same as proj
        #  Construct a random point X on the manifold.
        X = rnd.randn(self.m, self.n)
        X /= la.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = rnd.randn(self.m, self.n)

        #  Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)),
                                             self.man.egrad2rgrad(X, H))

    def test_ehess2rhess(self):
        x = self.man.rand()
        u = self.man.randvec(x)
        egrad = rnd.randn(self.m, self.n)
        ehess = rnd.randn(self.m, self.n)

        np_testing.assert_allclose(testing.ehess2rhess(self.proj)(x, egrad,
                                                                  ehess, u),
                                   self.man.ehess2rhess(x, egrad, ehess, u))

    def test_retr(self):
        # Test that the result is on the manifold and that for small
        # tangent vectors it has little effect.
        x = self.man.rand()
        u = self.man.randvec(x)

        xretru = self.man.retr(x, u)
        np_testing.assert_almost_equal(la.norm(xretru), 1)

        u = u * 1e-6
        xretru = self.man.retr(x, u)
        np_testing.assert_allclose(xretru, x + u)

    def test_norm(self):
        x = self.man.rand()
        u = self.man.randvec(x)

        np_testing.assert_almost_equal(self.man.norm(x, u), la.norm(u))

    def test_rand(self):
        # Just make sure that things generated are on the manifold and that
        # if you generate two they are not equal.
        s = self.man
        x = s.rand()
        np_testing.assert_almost_equal(la.norm(x), 1)
        y = s.rand()
        assert np.linalg.norm(x - y) > 1e-3

    def test_randvec(self):
        # Just make sure that things generated are in the tangent space and
        # that if you generate two they are not equal.
        s = self.man
        x = s.rand()
        u = s.randvec(x)
        v = s.randvec(x)
        np_testing.assert_almost_equal(np.tensordot(x, u), 0)

        assert np.linalg.norm(u - v) > 1e-3

    def test_transp(self):
        # Should be the same as proj
        s = self.man
        x = s.rand()
        y = s.rand()
        u = s.randvec(x)

        np_testing.assert_allclose(s.transp(x, y, u), s.proj(y, u))

    def test_exp_log_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Uexplog = s.exp(X, s.log(X, U))
        np_testing.assert_array_almost_equal(U, Uexplog)

    def test_log_exp_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U, Ulogexp)

    def test_pairmean(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Z = s.pairmean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #17
0
class TestSphereManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.man = Sphere(m, n)

        # For automatic testing of ehess2rhess
        self.proj = lambda x, u: u - npa.tensordot(x, u, np.ndim(u)) * x

    def test_name(self):
        man = self.man
        m = self.m
        n = self.n
        assert "Sphere manifold of " + str(m) + "x" + str(n) in str(man)

    def test_dim(self):
        assert self.man.dim == self.m * self.n - 1

    def test_typicaldist(self):
        np_testing.assert_almost_equal(self.man.typicaldist, np.pi)

    def test_dist(self):
        s = self.man
        x = s.rand()
        y = s.rand()
        correct_dist = np.arccos(np.tensordot(x, y))
        np.testing.assert_almost_equal(correct_dist, s.dist(x, y))

    def test_inner(self):
        s = self.man
        x = s.rand()
        u = s.randvec(x)
        v = s.randvec(x)
        np.testing.assert_almost_equal(np.sum(u * v), s.inner(x, u, v))

    def test_proj(self):
        #  Construct a random point X on the manifold.
        X = rnd.randn(self.m, self.n)
        X /= la.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = rnd.randn(self.m, self.n)

        #  Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)),
                                             self.man.proj(X, H))

    def test_egrad2rgrad(self):
        # Should be the same as proj
        #  Construct a random point X on the manifold.
        X = rnd.randn(self.m, self.n)
        X /= la.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = rnd.randn(self.m, self.n)

        #  Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T.dot(H)),
                                             self.man.egrad2rgrad(X, H))

    def test_ehess2rhess(self):
        x = self.man.rand()
        u = self.man.randvec(x)
        egrad = rnd.randn(self.m, self.n)
        ehess = rnd.randn(self.m, self.n)

        np_testing.assert_allclose(testing.ehess2rhess(self.proj)(x, egrad,
                                                                  ehess, u),
                                   self.man.ehess2rhess(x, egrad, ehess, u))

    def test_retr(self):
        # Test that the result is on the manifold and that for small
        # tangent vectors it has little effect.
        x = self.man.rand()
        u = self.man.randvec(x)

        xretru = self.man.retr(x, u)
        np_testing.assert_almost_equal(la.norm(xretru), 1)

        u = u * 1e-6
        xretru = self.man.retr(x, u)
        np_testing.assert_allclose(xretru, x + u)

    def test_norm(self):
        x = self.man.rand()
        u = self.man.randvec(x)

        np_testing.assert_almost_equal(self.man.norm(x, u), la.norm(u))

    def test_rand(self):
        # Just make sure that things generated are on the manifold and that
        # if you generate two they are not equal.
        s = self.man
        x = s.rand()
        np_testing.assert_almost_equal(la.norm(x), 1)
        y = s.rand()
        assert np.linalg.norm(x - y) > 1e-3

    def test_randvec(self):
        # Just make sure that things generated are in the tangent space and
        # that if you generate two they are not equal.
        s = self.man
        x = s.rand()
        u = s.randvec(x)
        v = s.randvec(x)
        np_testing.assert_almost_equal(np.tensordot(x, u), 0)

        assert np.linalg.norm(u - v) > 1e-3

    def test_transp(self):
        # Should be the same as proj
        s = self.man
        x = s.rand()
        y = s.rand()
        u = s.randvec(x)

        np_testing.assert_allclose(s.transp(x, y, u), s.proj(y, u))

    def test_exp_log_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Uexplog = s.exp(X, s.log(X, U))
        np_testing.assert_array_almost_equal(U, Uexplog)

    def test_log_exp_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U, Ulogexp)

    def test_pairmean(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Z = s.pairmean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #18
0
 def setUp(self):
     self.m = m = 100
     self.n = n = 50
     self.sphere = Sphere(m, n)
Пример #19
0
    def evaluate(self):
        # Perform reconstruction
        if self.recon_type == 'tp':  # Estimate theta and phi
            manifold = Sphere(3)

            def cost(X, data=self.data):
                ll = self.multiframe.noise_model.loglikelihood(
                    util.xyz2tp(*X), data)
                return -ll

            problem = Problem(manifold=manifold, cost=cost, verbosity=0)
            start_pts = [
                np.array(util.tp2xyz(*x)) for x in util.sphere_profile(20)
            ]
            solver = ParticleSwarm(maxcostevals=200)
            Xopt = solver.solve(problem, x=start_pts)
            self.estimated_fluorophore = fluorophore.Fluorophore(*util.xyz2tp(
                *Xopt))
        elif self.recon_type == 'tpc':  # Estimate theta, phi, constant
            # Create manifold and cost function
            manifold = Product((Sphere(3), Euclidean(1)))

            def cost(X, data=self.data):
                estimate = np.hstack([util.xyz2tp(*X[0]), X[1]])
                ll = self.multiframe.noise_model.loglikelihood(estimate, data)
                return -ll

            problem = Problem(manifold=manifold, cost=cost, verbosity=0)

            # Generate start_pts and format
            xyz_start_pts = 3 * [
                np.array(util.tp2xyz(*x)) for x in util.sphere_profile(10)
            ]
            c_start_pts = np.expand_dims(np.hstack(
                (10 * [0.1], 10 * [2], 10 * [10])),
                                         axis=1)
            start_pts = np.hstack((xyz_start_pts, c_start_pts))
            pts = []
            for start_pt in start_pts:
                pts.append([np.array(start_pt[0:3]), np.array(start_pt[3:5])])

            # Solve
            solver = ParticleSwarm(maxcostevals=250)
            Xopt = solver.solve(problem, x=pts)

            self.estimated_fluorophore = fluorophore.Fluorophore(
                *np.hstack([util.xyz2tp(*Xopt[0]), Xopt[1]]).flatten())

        elif self.recon_type == 'tpck':  # Estimate theta, phi, constant, kappa
            # Create manifold and cost function
            manifold = Product((Sphere(3), Euclidean(2)))

            def cost(X, data=self.data):
                estimate = np.array([
                    util.xyz2tp(*X[0]), X[1]
                ]).flatten()  # Reshape data for loglikelihood function
                ll = self.multiframe.noise_model.loglikelihood(estimate, data)
                print(estimate, ll)
                return -ll

            problem = Problem(manifold=manifold, cost=cost, verbosity=0)

            # Generate start_pts and format
            xyz_start_pts = 3 * [
                np.array(util.tp2xyz(*x)) for x in util.sphere_profile(10)
            ]
            k_start_pts = np.expand_dims(np.hstack(
                (10 * [-100], 10 * [0], 10 * [100])),
                                         axis=1)
            c_start_pts = np.expand_dims(np.hstack(
                (10 * [0.1], 10 * [1], 10 * [10])),
                                         axis=1)
            start_pts = np.hstack((xyz_start_pts, c_start_pts, k_start_pts))
            pts = []
            for start_pt in start_pts:
                pts.append([np.array(start_pt[0:3]), np.array(start_pt[3:5])])

            # Solve
            solver = ParticleSwarm(maxcostevals=200)
            Xopt = solver.solve(problem, x=pts)

            self.estimated_fluorophore = fluorophore.Fluorophore(
                *np.array([util.xyz2tp(*Xopt[0]), Xopt[1]]).flatten())
Пример #20
0
class TestProductManifold(ManifoldTestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.euclidean = Euclidean(m, n)
        self.sphere = Sphere(n)
        self.manifold = Product([self.euclidean, self.sphere])

        point = self.manifold.random_point()

        @pymanopt.function.autograd(self.manifold)
        def cost(*x):
            return np.sum([np.linalg.norm(a - b)**2 for a, b in zip(x, point)])

        self.cost = cost

    def test_dim(self):
        np_testing.assert_equal(self.manifold.dim,
                                self.m * self.n + self.n - 1)

    def test_typical_dist(self):
        np_testing.assert_equal(self.manifold.typical_dist,
                                np.sqrt((self.m * self.n) + np.pi**2))

    def test_dist(self):
        X = self.manifold.random_point()
        Y = self.manifold.random_point()
        np_testing.assert_equal(
            self.manifold.dist(X, Y),
            np.sqrt(
                self.euclidean.dist(X[0], Y[0])**2 +
                self.sphere.dist(X[1], Y[1])**2),
        )

    def test_tangent_vector_multiplication(self):
        # Regression test for https://github.com/pymanopt/pymanopt/issues/49.
        manifold = Product((Euclidean(12), Grassmann(12, 3)))
        x = manifold.random_point()
        eta = manifold.random_tangent_vector(x)
        np.float64(1.0) * eta

    # def test_inner_product(self):

    # def test_projection(self):

    # def test_euclidean_to_riemannian_hessian(self):

    # def test_retraction(self):

    def test_first_order_function_approximation(self):
        self.run_gradient_approximation_test()

    def test_second_order_function_approximation(self):
        self.run_hessian_approximation_test()

    # def test_norm(self):

    # def test_random_point(self):

    # def test_random_tangent_vector(self):

    # def test_transport(self):

    def test_exp_log_inverse(self):
        s = self.manifold
        X = s.random_point()
        Y = s.random_point()
        Yexplog = s.exp(X, tangent_vector=s.log(X, Y))
        np_testing.assert_almost_equal(s.dist(point_a=Y, point_b=Yexplog), 0)

    def test_log_exp_inverse(self):
        s = self.manifold
        X = s.random_point()
        U = s.random_tangent_vector(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U[0], Ulogexp[0])
        np_testing.assert_array_almost_equal(U[1], Ulogexp[1])

    def test_pair_mean(self):
        s = self.manifold
        X = s.random_point()
        Y = s.random_point()
        Z = s.pair_mean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #21
0
class TestProductManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.euclidean = Euclidean(m, n)
        self.sphere = Sphere(n)
        self.man = Product([self.euclidean, self.sphere])

    def test_dim(self):
        np_testing.assert_equal(self.man.dim, self.m * self.n + self.n - 1)

    def test_typicaldist(self):
        np_testing.assert_equal(self.man.typicaldist,
                                np.sqrt((self.m * self.n) + np.pi**2))

    def test_dist(self):
        X = self.man.rand()
        Y = self.man.rand()
        np_testing.assert_equal(
            self.man.dist(X, Y),
            np.sqrt(
                self.euclidean.dist(X[0], Y[0])**2 +
                self.sphere.dist(X[1], Y[1])**2))

    def test_tangent_vector_multiplication(self):
        # Regression test for https://github.com/pymanopt/pymanopt/issues/49.
        man = Product((Euclidean(12), Grassmann(12, 3)))
        x = man.rand()
        eta = man.randvec(x)
        np.float64(1.0) * eta

    # def test_inner(self):

    # def test_proj(self):

    # def test_ehess2rhess(self):

    # def test_retr(self):

    # def test_egrad2rgrad(self):

    # def test_norm(self):

    # def test_rand(self):

    # def test_randvec(self):

    # def test_transp(self):

    def test_exp_log_inverse(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Yexplog = s.exp(X, s.log(X, Y))
        np_testing.assert_almost_equal(s.dist(Y, Yexplog), 0)

    def test_log_exp_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U[0], Ulogexp[0])
        np_testing.assert_array_almost_equal(U[1], Ulogexp[1])

    def test_pairmean(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Z = s.pairmean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #22
0

if __name__ == "__main__":
    experiment_name = 'rayleigh'
    n_exp = 10

    if not os.path.isdir('result'):
        os.makedirs('result')
    path = os.path.join('result', experiment_name + '.csv')

    n = 100
    
    for i in range(n_exp):
        matrix = make_spd_matrix(n)

        cost = create_cost(matrix)
        manifold = Sphere(n)
        problem = pymanopt.Problem(manifold, cost=cost, egrad=None)
        
        res_list = []

        for beta_type in BetaTypes:
            solver = ConjugateGradient(beta_type=beta_type, maxiter=10000)
            res = solver.solve(problem)
            res_list.append(res[1])
            res_list.append(res[2])

        with open(path, 'a') as f:
            writer = csv.writer(f)
            writer.writerow(res_list)
Пример #23
0
 def setUp(self):
     self.m = m = 100
     self.n = n = 50
     self.euclidean = Euclidean(m, n)
     self.sphere = Sphere(n)
     self.man = Product([self.euclidean, self.sphere])
Пример #24
0
class TestProductManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.euclidean = Euclidean(m, n)
        self.sphere = Sphere(n)
        self.man = Product([self.euclidean, self.sphere])

    def test_dim(self):
        np_testing.assert_equal(self.man.dim, self.m*self.n+self.n-1)

    def test_typicaldist(self):
        np_testing.assert_equal(self.man.typicaldist,
                                np.sqrt((self.m*self.n)+np.pi**2))

    def test_dist(self):
        X = self.man.rand()
        Y = self.man.rand()
        np_testing.assert_equal(self.man.dist(X, Y),
                                np.sqrt(
                                    self.euclidean.dist(X[0], Y[0])**2 +
                                    self.sphere.dist(X[1], Y[1])**2))

    # def test_inner(self):

    # def test_proj(self):

    # def test_ehess2rhess(self):

    # def test_retr(self):

    # def test_egrad2rgrad(self):

    # def test_norm(self):

    # def test_rand(self):

    # def test_randvec(self):

    # def test_transp(self):

    def test_exp_log_inverse(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Yexplog = s.exp(X, s.log(X, Y))
        np_testing.assert_almost_equal(s.dist(Y, Yexplog), 0)

    def test_log_exp_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U[0], Ulogexp[0])
        np_testing.assert_array_almost_equal(U[1], Ulogexp[1])

    def test_pairmean(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Z = s.pairmean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #25
0
 def setUp(self):
     self.m = m = 100
     self.n = n = 50
     self.euclidean = Euclidean(m, n)
     self.sphere = Sphere(n)
     self.man = Product([self.euclidean, self.sphere])
Пример #26
0
 def setUp(self):
     self.n1 = n1 = 100
     self.n2 = n2 = 50
     self.n3 = n3 = 25
     self.man = Sphere(n1, n2, n3)
Пример #27
0
    def run(self,
            S,
            F,
            v=None,
            C=None,
            fs=None,
            omega=None,
            maxiter=500,
            tol=1e-10,
            variant='bp'):
        '''
        Run MERLiN algorithm.
        Whether to run a scalar variant, i.e. S -> C -> w'F, or a
        timeseries variant, i.e. S -> C -> bp(w'F) is determined by the
        dimensionality of the input F.

        Input (default)
            - S
                (m x 1) np.array that contains the samples of S
            - F
                either a (d x m) np.array that contains the linear mixture
                samples or a (d x m x n) np.array that contains the linearly
                mixed timeseries of length n (d channels, m trials)
            - v
                (d x 1) np.array holding the linear combination that
                extracts middle node C from F
            - C
                (m x 1) np.array that contains the samples of the middle
                node C
            - fs
                sampling rate in Hz
            - omega
                tuple of (low, high) cut-off of desired frequency band
            - maxiter (500)
                maximum iterations to run the optimisation algorithm for
            - tol (1e-16)
                terminate optimisation if step size < tol or grad norm < tol
            - variant ('bp')
                determines which MERLiN variant to use on timeseries data
                ('bp' = MERLiNbp algorithm ([1], Algorithm 4),
                 'bpicoh' = MERLiNbpicoh algorithm ([1], Algorithm 5),
                 'nlbp' = MERLiNnlbp)

        Output
            - w
                linear combination that was found and should extract the
                effect of C from F
            - converged
                boolean that indicates whether the stopping criterion was
                met before the maximum number of iterations was performed
            - curob
                objecive functions value at w
        '''
        self._S = S
        self._Forig = F
        self._fs = fs
        self._omega = omega
        self._d = F.shape[0]
        self._m = F.shape[1]

        # scalar or timeseries mode
        if F.ndim == 3:
            self._mode = 'timeseries'
            self._n = F.shape[2]
            if not (fs and omega):
                raise ValueError('Both the optional arguments fs and omega '
                                 'need to be provided.')
            if self._verbosity:
                print('Launching MERLiN' + variant + ' for iid sampled '
                      'timeseries chunks.')
        elif F.ndim == 2:
            self._mode = 'scalar'
            if self._verbosity:
                print('Launching MERLiN for iid sampled scalars.')
        else:
            raise ValueError('F needs to be a 2-dimensional numpy array '
                             '(iid sampled scalars) or a 3-dimensional '
                             'numpy array (iid sampled timeseries chunks).')

        self._prepare(v, C)

        if self._mode is 'scalar':
            problem = self._problem_MERLiN()
        elif variant is 'bp':
            problem = self._problem_MERLiNbp()
        elif variant is 'bpicoh':
            problem = self._problem_MERLiNbpicoh()
        elif variant is 'nlbp':
            problem = self._problem_MERLiNnlbp()
        else:
            raise NotImplementedError

        if variant is not 'nlbp':
            problem.manifold = Sphere(self._d, 1)
        elif variant is 'nlbp':
            problem.manifold = Product(
                [Sphere(self._d, 1),
                 Euclidean(1, 1),
                 Euclidean(1, 1)])

        # choose best out of ten 10-step runs as initialisation
        solver = SteepestDescent(maxiter=10, logverbosity=1)
        res = [solver.solve(problem) for k in range(0, 10)]
        obs = [-r[1]['final_values']['f(x)'] for r in res]
        w0 = res[obs.index(max(obs))][0]

        solver = SteepestDescent(maxtime=float('inf'),
                                 maxiter=maxiter,
                                 mingradnorm=tol,
                                 minstepsize=tol,
                                 logverbosity=1)
        if self._verbosity:
            print('Running optimisation algorithm.')
        w, info = solver.solve(problem, x=w0)
        if variant is 'nlbp':
            w = w[0]
        converged = maxiter != info['final_values']['iterations']
        curob = -float(info['final_values']['f(x)'])
        if self._verbosity:
            print('DONE.')
        return self._P.T.dot(w), converged, curob
Пример #28
0
class TestSphereManifold(ManifoldTestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.manifold = Sphere(m, n)

        # For automatic testing of euclidean_to_riemannian_hessian
        self.projection = lambda x, u: u - np.tensordot(x, u, np.ndim(u)) * x

        super().setUp()

    def test_dim(self):
        assert self.manifold.dim == self.m * self.n - 1

    def test_typical_dist(self):
        np_testing.assert_almost_equal(self.manifold.typical_dist, np.pi)

    def test_dist(self):
        s = self.manifold
        x = s.random_point()
        y = s.random_point()
        correct_dist = np.arccos(np.tensordot(x, y))
        np_testing.assert_almost_equal(correct_dist, s.dist(x, y))

    def test_inner_product(self):
        s = self.manifold
        x = s.random_point()
        u = s.random_tangent_vector(x)
        v = s.random_tangent_vector(x)
        np_testing.assert_almost_equal(np.sum(u * v), s.inner_product(x, u, v))

    def test_projection(self):
        #  Construct a random point X on the manifold.
        X = np.random.normal(size=(self.m, self.n))
        X /= np.linalg.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = np.random.normal(size=(self.m, self.n))

        #  Compare the projections.
        np_testing.assert_array_almost_equal(H - X * np.trace(X.T @ H),
                                             self.manifold.projection(X, H))

    def test_euclidean_to_riemannian_gradient(self):
        # Should be the same as proj
        #  Construct a random point X on the manifold.
        X = np.random.normal(size=(self.m, self.n))
        X /= np.linalg.norm(X, "fro")

        #  Construct a vector H in the ambient space.
        H = np.random.normal(size=(self.m, self.n))

        #  Compare the projections.
        np_testing.assert_array_almost_equal(
            H - X * np.trace(X.T @ H),
            self.manifold.euclidean_to_riemannian_gradient(X, H),
        )

    def test_first_order_function_approximation(self):
        self.run_gradient_approximation_test()

    def test_second_order_function_approximation(self):
        self.run_hessian_approximation_test()

    def test_euclidean_to_riemannian_hessian(self):
        x = self.manifold.random_point()
        u = self.manifold.random_tangent_vector(x)
        egrad = np.random.normal(size=(self.m, self.n))
        ehess = np.random.normal(size=(self.m, self.n))

        np_testing.assert_allclose(
            testing.euclidean_to_riemannian_hessian(self.projection)(x, egrad,
                                                                     ehess, u),
            self.manifold.euclidean_to_riemannian_hessian(x, egrad, ehess, u),
        )

    def test_retraction(self):
        # Test that the result is on the manifold and that for small
        # tangent vectors it has little effect.
        x = self.manifold.random_point()
        u = self.manifold.random_tangent_vector(x)

        xretru = self.manifold.retraction(x, u)
        np_testing.assert_almost_equal(np.linalg.norm(xretru), 1)

        u = u * 1e-6
        xretru = self.manifold.retraction(x, u)
        np_testing.assert_allclose(xretru, x + u)

    def test_norm(self):
        x = self.manifold.random_point()
        u = self.manifold.random_tangent_vector(x)

        np_testing.assert_almost_equal(self.manifold.norm(x, u),
                                       np.linalg.norm(u))

    def test_random_point(self):
        # Just make sure that things generated are on the manifold and that
        # if you generate two they are not equal.
        s = self.manifold
        x = s.random_point()
        np_testing.assert_almost_equal(np.linalg.norm(x), 1)
        y = s.random_point()
        assert np.linalg.norm(x - y) > 1e-3

    def test_random_tangent_vector(self):
        # Just make sure that things generated are in the tangent space and
        # that if you generate two they are not equal.
        s = self.manifold
        x = s.random_point()
        u = s.random_tangent_vector(x)
        v = s.random_tangent_vector(x)
        np_testing.assert_almost_equal(np.tensordot(x, u), 0)

        assert np.linalg.norm(u - v) > 1e-3

    def test_transport(self):
        # Should be the same as proj
        s = self.manifold
        x = s.random_point()
        y = s.random_point()
        u = s.random_tangent_vector(x)

        np_testing.assert_allclose(s.transport(x, y, u), s.projection(y, u))

    def test_exp_log_inverse(self):
        s = self.manifold
        X = s.random_point()
        Y = s.random_point()
        Yexplog = s.exp(X, s.log(X, Y))
        np_testing.assert_array_almost_equal(Y, Yexplog)

    def test_log_exp_inverse(self):
        s = self.manifold
        X = s.random_point()
        U = s.random_tangent_vector(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U, Ulogexp)

    def test_pair_mean(self):
        s = self.manifold
        X = s.random_point()
        Y = s.random_point()
        Z = s.pair_mean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #29
0

if __name__ == "__main__":
    experiment_name = 'stability'
    n_exp = 10

    if not os.path.isdir('result'):
        os.makedirs('result')
    path = os.path.join('result', experiment_name + '.csv')

    n = 20
    p = 1 / 4

    for i in range(n_exp):
        G = nx.fast_gnp_random_graph(n, p, directed=False)
        cost = create_cost(G)
        manifold = Sphere(len(G.nodes))
        problem = pymanopt.Problem(manifold, cost=cost, egrad=None)

        res_list = []

        for beta_type in BetaTypes:
            solver = ConjugateGradient(beta_type=beta_type, maxiter=10000)
            res = solver.solve(problem)
            res_list.append(res[1])
            res_list.append(res[2])

        with open(path, 'a') as f:
            writer = csv.writer(f)
            writer.writerow(res_list)
Пример #30
0
class TestProductManifold(unittest.TestCase):
    def setUp(self):
        self.m = m = 100
        self.n = n = 50
        self.euclidean = Euclidean(m, n)
        self.sphere = Sphere(n)
        self.man = Product([self.euclidean, self.sphere])

    def test_dim(self):
        np_testing.assert_equal(self.man.dim, self.m * self.n + self.n - 1)

    def test_typicaldist(self):
        np_testing.assert_equal(self.man.typicaldist,
                                np.sqrt((self.m * self.n) + np.pi**2))

    def test_dist(self):
        X = self.man.rand()
        Y = self.man.rand()
        np_testing.assert_equal(
            self.man.dist(X, Y),
            np.sqrt(
                self.euclidean.dist(X[0], Y[0])**2 +
                self.sphere.dist(X[1], Y[1])**2))

    # def test_inner(self):

    # def test_proj(self):

    # def test_ehess2rhess(self):

    # def test_retr(self):

    # def test_egrad2rgrad(self):

    # def test_norm(self):

    # def test_rand(self):

    # def test_randvec(self):

    # def test_transp(self):

    def test_exp_log_inverse(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Yexplog = s.exp(X, s.log(X, Y))
        np_testing.assert_almost_equal(s.dist(Y, Yexplog), 0)

    def test_log_exp_inverse(self):
        s = self.man
        X = s.rand()
        U = s.randvec(X)
        Ulogexp = s.log(X, s.exp(X, U))
        np_testing.assert_array_almost_equal(U[0], Ulogexp[0])
        np_testing.assert_array_almost_equal(U[1], Ulogexp[1])

    def test_pairmean(self):
        s = self.man
        X = s.rand()
        Y = s.rand()
        Z = s.pairmean(X, Y)
        np_testing.assert_array_almost_equal(s.dist(X, Z), s.dist(Y, Z))
Пример #31
0
 def setUp(self):
     self.n = n = 50
     self.man = Sphere(n)