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 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 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 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)
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
def setUp(self): self.X = X = T.vector() self.cost = T.exp(T.sum(X**2)) n = self.n = 15 self.man = Sphere(n)
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
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)
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)
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)
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)
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))
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)
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()
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))
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))
def setUp(self): self.m = m = 100 self.n = n = 50 self.sphere = Sphere(m, n)
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())
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))
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))
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)
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])
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))
def setUp(self): self.n1 = n1 = 100 self.n2 = n2 = 50 self.n3 = n3 = 25 self.man = Sphere(n1, n2, n3)
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
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))
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)
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))
def setUp(self): self.n = n = 50 self.man = Sphere(n)