Home > manopt > manifolds > sphere > spherecomplexfactory.m

spherecomplexfactory

PURPOSE ^

Returns a manifold struct to optimize over unit-norm complex matrices.

SYNOPSIS ^

function M = spherecomplexfactory(n, m)

DESCRIPTION ^

 Returns a manifold struct to optimize over unit-norm complex matrices.

 function M = spherecomplexfactory(n)
 function M = spherecomplexfactory(n, m)

 Manifold of n-by-m complex matrices of unit Frobenius norm.
 By default, m = 1, which corresponds to the unit sphere in C^n. The
 metric is such that the sphere is a Riemannian submanifold of the space
 of 2nx2m real matrices with the usual trace inner product, i.e., the
 usual metric.
 
 See also: spherefactory

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function M = spherecomplexfactory(n, m)
0002 % Returns a manifold struct to optimize over unit-norm complex matrices.
0003 %
0004 % function M = spherecomplexfactory(n)
0005 % function M = spherecomplexfactory(n, m)
0006 %
0007 % Manifold of n-by-m complex matrices of unit Frobenius norm.
0008 % By default, m = 1, which corresponds to the unit sphere in C^n. The
0009 % metric is such that the sphere is a Riemannian submanifold of the space
0010 % of 2nx2m real matrices with the usual trace inner product, i.e., the
0011 % usual metric.
0012 %
0013 % See also: spherefactory
0014 
0015 % This file is part of Manopt: www.manopt.org.
0016 % Original author: Nicolas Boumal, Dec. 30, 2012.
0017 % Contributors:
0018 % Change log:
0019 %
0020 %   Sep. 4, 2014 (NB):
0021 %       Added ehess2rhess.
0022 %
0023 %   April 7, 2015 (NB):
0024 %       Added vec/mat pair (for use with hessianspectrum, for example).
0025 %
0026 %   April 13, 2015 (NB):
0027 %       Added logarithm
0028 %
0029 %   Oct. 8, 2016 (NB)
0030 %       Code for exponential was simplified to only treat the zero vector
0031 %       as a particular case.
0032 %
0033 %   Oct. 22, 2016 (NB)
0034 %       Distance function dist now significantly more accurate for points
0035 %       within 1e-7 and less from each other.
0036 
0037     
0038     if ~exist('m', 'var')
0039         m = 1;
0040     end
0041 
0042     if m == 1
0043         M.name = @() sprintf('Complex sphere S^%d', n-1);
0044     else
0045         M.name = @() sprintf('Unit F-norm %dx%d complex matrices', n, m);
0046     end
0047     
0048     M.dim = @() 2*(n*m)-1;
0049     
0050     M.inner = @(x, d1, d2) real(d1(:)'*d2(:));
0051     
0052     M.norm = @(x, d) norm(d, 'fro');
0053     
0054     M.dist = @dist;
0055     function d = dist(x, y)
0056         d = real(acos(real(x(:)'*y(:))));
0057         % The above formula is numerically inaccurate if x and y are too
0058         % close together. In that case, norm is a much better proxy.
0059         if d < 1e-7
0060             d = norm(x-y, 'fro');
0061         end
0062     end
0063     
0064     M.typicaldist = @() pi;
0065     
0066     M.proj = @(x, d) reshape(d(:) - x(:)*(real(x(:)'*d(:))), n, m);
0067     
0068     % For Riemannian submanifolds, converting a Euclidean gradient into a
0069     % Riemannian gradient amounts to an orthogonal projection.
0070     M.egrad2rgrad = M.proj;
0071     
0072     M.ehess2rhess = @ehess2rhess;
0073     function rhess = ehess2rhess(x, egrad, ehess, u)
0074         rhess = M.proj(x, ehess) - real((x(:)'*egrad(:)))*u;
0075     end
0076     
0077     M.tangent = M.proj;
0078     
0079     M.exp = @exponential;
0080     
0081     M.retr = @retraction;
0082 
0083     M.log = @logarithm;
0084     function v = logarithm(x1, x2)
0085         v = M.proj(x1, x2 - x1);
0086         di = M.dist(x1, x2);
0087         % If the two points are "far apart", correct the norm.
0088         if di > 1e-6
0089             nv = norm(v, 'fro');
0090             v = v * (di / nv);
0091         end
0092     end
0093     
0094     M.hash = @(x) ['z' hashmd5([real(x(:)) ; imag(x(:))])];
0095     
0096     M.rand = @() random(n, m);
0097     
0098     M.randvec = @(x) randomvec(n, m, x);
0099     
0100     M.lincomb = @matrixlincomb;
0101     
0102     M.zerovec = @(x) zeros(n, m);
0103     
0104     M.transp = @(x1, x2, d) M.proj(x2, d);
0105     
0106     M.pairmean = @pairmean;
0107     function y = pairmean(x1, x2)
0108         y = x1+x2;
0109         y = y / norm(y, 'fro');
0110     end
0111 
0112     mn = m*n;
0113     M.vec = @(x, u_mat) [real(u_mat(:)) ; imag(u_mat(:))];
0114     M.mat = @(x, u_vec) reshape(u_vec(1:mn), m, n) + 1i*reshape(u_vec((mn+1):end), m, n);
0115     M.vecmatareisometries = @() true;
0116 
0117 end
0118 
0119 % Exponential on the sphere
0120 function y = exponential(x, d, t)
0121 
0122     if nargin == 2
0123         % t = 1;
0124         td = d;
0125     else
0126         td = t*d;
0127     end
0128     
0129     nrm_td = norm(td, 'fro');
0130     
0131     if nrm_td > 0
0132         y = x*cos(nrm_td) + td*(sin(nrm_td)/nrm_td);
0133     else
0134         y = x;
0135     end
0136 
0137 end
0138 
0139 % Retraction on the sphere
0140 function y = retraction(x, d, t)
0141 
0142     if nargin == 2
0143         t = 1;
0144     end
0145     
0146     y = x+t*d;
0147     y = y/norm(y, 'fro');
0148 
0149 end
0150 
0151 % Uniform random sampling on the sphere.
0152 function x = random(n, m)
0153 
0154     x = randn(n, m) + 1i*randn(n, m);
0155     x = x/norm(x, 'fro');
0156 
0157 end
0158 
0159 % Random normalized tangent vector at x.
0160 function d = randomvec(n, m, x)
0161 
0162     d = randn(n, m) + 1i*randn(n, m);
0163     d = reshape(d(:) - x(:)*(real(x(:)'*d(:))), n, m);
0164     d = d / norm(d, 'fro');
0165 
0166 end

Generated on Sat 12-Nov-2016 14:11:22 by m2html © 2005