# Source code for pymanopt.manifolds.euclidean

```import numpy as np
from numpy import linalg as la, random as rnd

from pymanopt.manifolds.manifold import EuclideanEmbeddedSubmanifold
from pymanopt.tools.multi import multiskew, multisym

class _Euclidean(EuclideanEmbeddedSubmanifold):
"""Shared base class for subspace manifolds of Euclidean space."""

def __init__(self, name, dimension, *shape):
self._shape = shape
super().__init__(name, dimension)

@property
def typicaldist(self):
return np.sqrt(self.dim)

def inner(self, X, G, H):
return float(np.tensordot(G, H, axes=G.ndim))

def norm(self, X, G):
return la.norm(G)

def dist(self, X, Y):
return la.norm(X - Y)

def proj(self, X, U):
return U

def ehess2rhess(self, X, egrad, ehess, H):
return ehess

def exp(self, X, U):
return X + U

retr = exp

def log(self, X, Y):
return Y - X

def rand(self):
return rnd.randn(*self._shape)

def randvec(self, X):
Y = self.rand()
return Y / self.norm(X, Y)

def transp(self, X1, X2, G):
return G

def pairmean(self, X, Y):
return (X + Y) / 2

def zerovec(self, X):
return np.zeros(self._shape)

[docs]class Euclidean(_Euclidean):
"""
Euclidean manifold of shape n1 x n2 x ... x nk tensors. Useful for
unconstrained optimization problems or for unconstrained hyperparameters,
as part of a product manifold.

Examples:
Create a manifold of vectors of length n:
manifold = Euclidean(n)

Create a manifold of m x n matrices:
manifold = Euclidean(m, n)
"""

def __init__(self, *shape):
if len(shape) == 0:
raise TypeError("Need shape parameters")
if len(shape) == 1:
name = "Euclidean manifold of {}-vectors".format(*shape)
elif len(shape) == 2:
name = ("Euclidean manifold of {}x{} matrices").format(*shape)
else:
name = ("Euclidean manifold of shape " + str(shape) + " tensors")
dimension = np.prod(shape)
super().__init__(name, dimension, *shape)

[docs]class Symmetric(_Euclidean):
"""
Manifold of n x n symmetric matrices, as a Riemannian submanifold of
Euclidean space.

If k > 1 then this is an array of shape (k, n, n) (product manifold)
containing k (n x n) matrices.
"""

def __init__(self, n, k=1):
if k == 1:
shape = (n, n)
name = ("Manifold of {} x {} symmetric matrices").format(n, n)
elif k > 1:
shape = (k, n, n)
name = ("Product manifold of {} ({} x {}) symmetric "
"matrices").format(k, n, n)
else:
raise ValueError("k must be an integer no less than 1")
dimension = int(k * n * (n + 1) / 2)
super().__init__(name, dimension, *shape)

[docs]    def proj(self, X, U):
return multisym(U)

[docs]    def ehess2rhess(self, X, egrad, ehess, H):
return multisym(ehess)

[docs]    def rand(self):
return multisym(rnd.randn(*self._shape))

[docs]    def randvec(self, X):
Y = self.rand()
return multisym(Y / self.norm(X, Y))

[docs]class SkewSymmetric(_Euclidean):
"""
The Euclidean space of n-by-n skew-symmetric matrices.

If k > 1 then this is an array of shape (k, n, n) (product manifold)
containing k (n x n) matrices.
"""

def __init__(self, n, k=1):
if k == 1:
shape = (n, n)
name = ("Manifold of {} x {} skew-symmetric "
"matrices").format(n, n)
elif k > 1:
shape = (k, n, n)
name = ("Product manifold of {} ({} x {}) skew-symmetric "
"matrices").format(k, n, n)
else:
raise ValueError("k must be an integer no less than 1")
dimension = int(k * n * (n - 1) / 2)
super().__init__(name, dimension, *shape)

[docs]    def proj(self, X, U):
return multiskew(U)

[docs]    def ehess2rhess(self, X, egrad, ehess, H):
return multiskew(ehess)

[docs]    def rand(self):
return multiskew(rnd.randn(*self._shape))

[docs]    def randvec(self, X):
G = self.rand()
return multiskew(G / self.norm(X, G))
```