Home > manopt > manifolds > complexcircle > complexcirclefactory.m

complexcirclefactory

PURPOSE ^

Returns a manifold struct to optimize over unit-modulus complex numbers.

SYNOPSIS ^

function M = complexcirclefactory(n)

DESCRIPTION ^

 Returns a manifold struct to optimize over unit-modulus complex numbers.

 function M = complexcirclefactory()
 function M = complexcirclefactory(n)

 Description of vectors z in C^n (complex) such that each component z(i)
 has unit modulus. The manifold structure is the Riemannian submanifold
 structure from the embedding space R^2 x ... x R^2, i.e., the complex
 circle is identified with the unit circle in the real plane.

 By default, n = 1.

 See also spherecomplexfactory

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function M = complexcirclefactory(n)
0002 % Returns a manifold struct to optimize over unit-modulus complex numbers.
0003 %
0004 % function M = complexcirclefactory()
0005 % function M = complexcirclefactory(n)
0006 %
0007 % Description of vectors z in C^n (complex) such that each component z(i)
0008 % has unit modulus. The manifold structure is the Riemannian submanifold
0009 % structure from the embedding space R^2 x ... x R^2, i.e., the complex
0010 % circle is identified with the unit circle in the real plane.
0011 %
0012 % By default, n = 1.
0013 %
0014 % See also spherecomplexfactory
0015 
0016 % This file is part of Manopt: www.manopt.org.
0017 % Original author: Nicolas Boumal, Dec. 30, 2012.
0018 % Contributors:
0019 % Change log:
0020 %
0021 %   July 7, 2014 (NB): Added ehess2rhess function.
0022 %
0023 %   Sep. 3, 2014 (NB): Correction to the dist function (extract real part).
0024 %
0025 %   April 13, 2015 (NB): Fixed logarithm.
0026 %
0027 %   Oct. 8, 2016 (NB)
0028 %       Code for exponential was simplified to only treat the zero vector
0029 %       as a particular case.
0030     
0031     if ~exist('n', 'var')
0032         n = 1;
0033     end
0034 
0035     M.name = @() sprintf('Complex circle (S^1)^%d', n);
0036     
0037     M.dim = @() n;
0038     
0039     M.inner = @(z, v, w) real(v'*w);
0040     
0041     M.norm = @(x, v) norm(v);
0042     
0043     M.dist = @(x, y) norm(acos(real(conj(x) .* y)));
0044     
0045     M.typicaldist = @() pi*sqrt(n);
0046     
0047     M.proj = @(z, u) u - real( conj(u) .* z ) .* z;    
0048     
0049     M.tangent = M.proj;
0050     
0051     % For Riemannian submanifolds, converting a Euclidean gradient into a
0052     % Riemannian gradient amounts to an orthogonal projection.
0053     M.egrad2rgrad = M.proj;
0054     
0055     M.ehess2rhess = @ehess2rhess;
0056     function rhess = ehess2rhess(z, egrad, ehess, zdot)
0057         rhess = M.proj(z, ehess - real(z.*conj(egrad)).*zdot);
0058     end
0059     
0060     M.exp = @exponential;
0061     function y = exponential(z, v, t)
0062         
0063         if nargin == 2
0064             % t = 1;
0065             tv = v;
0066         else
0067             tv = t*v;
0068         end
0069 
0070         y = zeros(n, 1);
0071 
0072         nrm_tv = abs(tv);
0073         
0074         % We need to be careful for zero steps.
0075         mask = (nrm_tv > 0);
0076         y(mask) = z(mask).*cos(nrm_tv(mask)) + ...
0077                   tv(mask).*(sin(nrm_tv(mask))./nrm_tv(mask));
0078         y(~mask) = z(~mask);
0079         
0080     end
0081     
0082     M.retr = @retraction;
0083     function y = retraction(z, v, t)
0084         if nargin == 2
0085             % t = 1;
0086             tv = v;
0087         else
0088             tv = t*v;
0089         end
0090         y = z+tv;
0091         y = y ./ abs(y);
0092     end
0093 
0094     M.log = @logarithm;
0095     function v = logarithm(x1, x2)
0096         v = M.proj(x1, x2 - x1);
0097         di = real(acos(real(conj(x1) .* x2)));
0098         nv = abs(v);
0099         factors = di ./ nv;
0100         factors(di <= 1e-6) = 1;
0101         v = v .* factors;
0102     end
0103     
0104     M.hash = @(z) ['z' hashmd5( [real(z(:)) ; imag(z(:))] ) ];
0105     
0106     M.rand = @random;
0107     function z = random()
0108         z = randn(n, 1) + 1i*randn(n, 1);
0109         z = z ./ abs(z);
0110     end
0111     
0112     M.randvec = @randomvec;
0113     function v = randomvec(z)
0114         % i*z(k) is a basis vector of the tangent vector to the k-th circle
0115         v = randn(n, 1) .* (1i*z);
0116         v = v / norm(v);
0117     end
0118     
0119     M.lincomb = @matrixlincomb;
0120     
0121     M.zerovec = @(x) zeros(n, 1);
0122     
0123     M.transp = @(x1, x2, d) M.proj(x2, d);
0124     
0125     M.pairmean = @pairmean;
0126     function z = pairmean(z1, z2)
0127         z = z1+z2;
0128         z = z ./ abs(z);
0129     end
0130 
0131     M.vec = @(x, u_mat) [real(u_mat) ; imag(u_mat)];
0132     M.mat = @(x, u_vec) u_vec(1:n) + 1i*u_vec((n+1):end);
0133     M.vecmatareisometries = @() true;
0134 
0135 end

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