Home > manopt > tools > powermanifold.m

# powermanifold

## PURPOSE

Returns a structure describing a power manifold M^n = M x M x ... x M.

## SYNOPSIS

function Mn = powermanifold(M, n)

## DESCRIPTION

``` Returns a structure describing a power manifold M^n = M x M x ... x M.

function Mn = powermanifold(M, n)

Input: a manifold structure M and an integer n >= 1.

Output: a manifold structure Mn representing M x ... x M (n copies of M)
with the metric of M extended element-wise. Points and vectors are stored
as cells of size nx1.

This code is for prototyping uses. The structures returned are often
inefficient representations of power manifolds owing to their use of
for-loops, but they should allow to rapidly try out an idea.

Example (an inefficient representation of the oblique manifold (3, 10)):
Mn = powermanifold(spherefactory(3), 10)
disp(Mn.name());
x = Mn.rand()

## CROSS-REFERENCE INFORMATION

This function calls:
• hashmd5 Computes the MD5 hash of input data.
• lincomb Computes a linear combination of tangent vectors in the Manopt framework.
This function is called by:

## SOURCE CODE

```0001 function Mn = powermanifold(M, n)
0002 % Returns a structure describing a power manifold M^n = M x M x ... x M.
0003 %
0004 % function Mn = powermanifold(M, n)
0005 %
0006 % Input: a manifold structure M and an integer n >= 1.
0007 %
0008 % Output: a manifold structure Mn representing M x ... x M (n copies of M)
0009 % with the metric of M extended element-wise. Points and vectors are stored
0010 % as cells of size nx1.
0011 %
0012 % This code is for prototyping uses. The structures returned are often
0013 % inefficient representations of power manifolds owing to their use of
0014 % for-loops, but they should allow to rapidly try out an idea.
0015 %
0016 % Example (an inefficient representation of the oblique manifold (3, 10)):
0017 % Mn = powermanifold(spherefactory(3), 10)
0018 % disp(Mn.name());
0019 % x = Mn.rand()
0020 %
0022
0023 % This file is part of Manopt: www.manopt.org.
0024 % Original author: Nicolas Boumal, Dec. 30, 2012.
0025 % Contributors:
0026 % Change log:
0027 %   NB, July 4, 2013: Added support for vec, mat, tangent.
0029
0030
0031     assert(n >= 1, 'n must be an integer larger than or equal to 1.');
0032
0033     Mn.name = @() sprintf('[%s]^%d', M.name(), n);
0034
0035     Mn.dim = @() n*M.dim();
0036
0037     Mn.inner = @inner;
0038     function val = inner(x, u, v)
0039         val = 0;
0040         for i = 1 : n
0041             val = val + M.inner(x{i}, u{i}, v{i});
0042         end
0043     end
0044
0045     Mn.norm = @(x, d) sqrt(Mn.inner(x, d, d));
0046
0047     Mn.dist = @dist;
0048     function d = dist(x, y)
0049         sqd = 0;
0050         for i = 1 : n
0051             sqd = sqd + M.dist(x{i}, y{i})^2;
0052         end
0053         d = sqrt(sqd);
0054     end
0055
0056     Mn.typicaldist = @typicaldist;
0057     function d = typicaldist()
0058         sqd = 0;
0059         for i = 1 : n
0060             sqd = sqd + M.typicaldist()^2;
0061         end
0062         d = sqrt(sqd);
0063     end
0064
0065     Mn.proj = @proj;
0066     function u = proj(x, u)
0067         for i = 1 : n
0068             u{i} = M.proj(x{i}, u{i});
0069         end
0070     end
0071
0072     Mn.tangent = @tangent;
0073     function u = tangent(x, u)
0074         for i = 1 : n
0075             u{i} = M.tangent(x{i}, u{i});
0076         end
0077     end
0078
0079     if isfield(M, 'tangent2ambient')
0080         Mn.tangent2ambient = @tangent2ambient;
0081     else
0082         Mn.tangent2ambient = @(x, u) u;
0083     end
0084     function u = tangent2ambient(x, u)
0085         for i = 1 : n
0086             u{i} = M.tangent2ambient(x{i}, u{i});
0087         end
0088     end
0089
0092         for i = 1 : n
0094         end
0095     end
0096
0097     Mn.ehess2rhess = @ehess2rhess;
0098     function h = ehess2rhess(x, eg, eh, h)
0099         for i = 1 : n
0100             h{i} = M.ehess2rhess(x{i}, eg{i}, eh{i}, h{i});
0101         end
0102     end
0103
0104     Mn.exp = @expo;
0105     function x = expo(x, u, t)
0106         if nargin < 3
0107             t = 1.0;
0108         end
0109         for i = 1 : n
0110             x{i} = M.exp(x{i}, u{i}, t);
0111         end
0112     end
0113
0114     Mn.retr = @retr;
0115     function x = retr(x, u, t)
0116         if nargin < 3
0117             t = 1.0;
0118         end
0119         for i = 1 : n
0120             x{i} = M.retr(x{i}, u{i}, t);
0121         end
0122     end
0123
0124     if isfield(M, 'log')
0125         Mn.log = @loga;
0126     end
0127     function u = loga(x, y)
0128         u = cell(n, 1);
0129         for i = 1 : n
0130             u{i} = M.log(x{i}, y{i});
0131         end
0132     end
0133
0134     Mn.hash = @hash;
0135     function str = hash(x)
0136         str = '';
0137         for i = 1 : n
0138             str = [str M.hash(x{i})]; %#ok<AGROW>
0139         end
0140         str = ['z' hashmd5(str)];
0141     end
0142
0143     Mn.lincomb = @lincomb;
0144     function x = lincomb(x, a1, u1, a2, u2)
0145         if nargin == 3
0146             for i = 1 : n
0147                 x{i} = M.lincomb(x{i}, a1, u1{i});
0148             end
0149         elseif nargin == 5
0150             for i = 1 : n
0151                 x{i} = M.lincomb(x{i}, a1, u1{i}, a2, u2{i});
0152             end
0153         else
0155         end
0156     end
0157
0158     Mn.rand = @rand;
0159     function x = rand()
0160         x = cell(n, 1);
0161         for i = 1 : n
0162             x{i} = M.rand();
0163         end
0164     end
0165
0166     Mn.randvec = @randvec;
0167     function u = randvec(x)
0168         u = cell(n, 1);
0169         for i = 1 : n
0170             u{i} = M.randvec(x{i});
0171         end
0172         u = Mn.lincomb(x, 1/sqrt(n), u);
0173     end
0174
0175     Mn.zerovec = @zerovec;
0176     function u = zerovec(x)
0177         u = cell(n, 1);
0178         for i = 1 : n
0179             u{i} = M.zerovec(x{i});
0180         end
0181     end
0182
0183     if isfield(M, 'transp')
0184         Mn.transp = @transp;
0185     end
0186     function u = transp(x1, x2, u)
0187         for i = 1 : n
0188             u{i} = M.transp(x1{i}, x2{i}, u{i});
0189         end
0190     end
0191
0192     if isfield(M, 'pairmean')
0193         Mn.pairmean = @pairmean;
0194     end
0195     function y = pairmean(x1, x2)
0196         y = cell(n, 1);
0197         for i = 1 : n
0198             y{i} = M.pairmean(x1{i}, x2{i});
0199         end
0200     end
0201
0202     % Compute the length of a vectorized tangent vector of M at x, assuming
0203     % this length is independent of the point x (that should be fine).
0204     if isfield(M, 'vec')
0205         rand_x = M.rand();
0206         zero_u = M.zerovec(rand_x);
0207         len_vec = length(M.vec(rand_x, zero_u));
0208
0209         Mn.vec = @vec;
0210
0211         if isfield(M, 'mat')
0212             Mn.mat = @mat;
0213         end
0214
0215     end
0216
0217     function u_vec = vec(x, u_mat)
0218         u_vec = zeros(len_vec, n);
0219         for i = 1 : n
0220             u_vec(:, i) = M.vec(x{i}, u_mat{i});
0221         end
0222         u_vec = u_vec(:);
0223     end
0224
0225     function u_mat = mat(x, u_vec)
0226         u_mat = cell(n, 1);
0227         u_vec = reshape(u_vec, len_vec, n);
0228         for i = 1 : n
0229             u_mat{i} = M.mat(x{i}, u_vec(:, i));
0230         end
0231     end
0232
0233     if isfield(M, 'vecmatareisometries')
0234         Mn.vecmatareisometries = M.vecmatareisometries;
0235     else
0236         Mn.vecmatareisometries = @() false;
0237     end
0238
0239 end```

Generated on Fri 08-Sep-2017 12:43:19 by m2html © 2005