Home > manopt > tools > tangentspacefactory.m

# tangentspacefactory

## PURPOSE

Returns a manifold structure representing the tangent space to M at x.

## SYNOPSIS

function N = tangentspacefactory(M, x)

## DESCRIPTION

``` Returns a manifold structure representing the tangent space to M at x.

N = tangentspacefactory(M, x)

N defines a (linear) manifold that is the tangent space to M at x. Points
are represented as tangent vectors to M at x. Tangent vectors are also
represented as tangent vectors to M at x.

This is chiefly useful to solve optimization problems involving tangent
vectors to M at x, which notably comes up when solving linear systems
involving, for example, the Hessian of the cost on M at x (think of the
Newton equations.) The Riemannian (actually, Euclidean) structure on N is
that of the tangent space to M, that is, the inner product is inherited.

## CROSS-REFERENCE INFORMATION

This function calls:
• hashmd5 Computes the MD5 hash of input data.
This function is called by:
• preconhessiansolve Preconditioner based on the inverse Hessian, by solving linear systems.

## SOURCE CODE

```0001 function N = tangentspacefactory(M, x)
0002 % Returns a manifold structure representing the tangent space to M at x.
0003 %
0004 % N = tangentspacefactory(M, x)
0005 %
0006 % N defines a (linear) manifold that is the tangent space to M at x. Points
0007 % are represented as tangent vectors to M at x. Tangent vectors are also
0008 % represented as tangent vectors to M at x.
0009 %
0010 % This is chiefly useful to solve optimization problems involving tangent
0011 % vectors to M at x, which notably comes up when solving linear systems
0012 % involving, for example, the Hessian of the cost on M at x (think of the
0013 % Newton equations.) The Riemannian (actually, Euclidean) structure on N is
0014 % that of the tangent space to M, that is, the inner product is inherited.
0015 %
0017
0018 % This file is part of Manopt: www.manopt.org.
0019 % Original author: Nicolas Boumal, April 9, 2015.
0020 % Contributors:
0021 % Change log:
0022 %
0023 %   Jan. 25, 2017 (NB):
0024 %       Following a comment by Jesus Briales on the Manopt forum, the
0026 %       projection (they were formerly identities.)
0027 %
0028 %   Feb. 2, 2017 (NB):
0029 %       Following a comment by Jesus Briales on the Manopt forum, the
0030 %       function N.proj now calls M.proj(x, .) instead of M.proj(y, .).
0031 %       Furthermore, N.ehess2rhess was corrected in the same way.
0032 %
0033 %   Dec. 14, 2019 (NB):
0034 %       Fixed N.tangent so that it should now work with factories that
0035 %       have a non-identity tangent2ambient, e.g., fixedrankembeddedfactory
0036 %       and rotationsfactory.
0037
0038     % N is the manifold we build. y will be a point on N, thus also a
0039     % tangent vector to M at x. This is a typical Euclidean space, hence it
0040     % will be easy to describe in terms of the tools available for M.
0041     N = struct();
0042
0043     % u, u1 and u2 will be tangent vectors to N at y. The tangent space to
0044     % N at y is the tangent space to M at x, thus u, u1 and u2 are also
0045     % tangent vectors to M at x.
0046
0047     if isfield(M, 'name')
0048         N.name  = @() ['Tangent space to ' M.name()];
0049     end
0050     N.dim   = @() M.dim();
0051     N.inner = @(y, u1, u2) M.inner(x, u1, u2);
0052     N.norm  = @(y, u) M.norm(x, u);
0053     N.proj  = @(y, u) M.proj(x, u);
0054     N.typicaldist = @() sqrt(N.dim());
0055     if isfield(M, 'tangent2ambient')
0056         N.tangent = @(y, u) M.proj(x, M.tangent2ambient(x, u));
0057     else
0058         N.tangent = N.proj;
0059     end
0060
0062     N.ehess2rhess = @(y, eg, eh, d) M.proj(x, eh);
0063     N.exp = @exponential;
0064     N.retr = @exponential;
0065     N.log = @(y1, y2) M.lincomb(x, 1, y2, -1, y1);
0066     N.pairmean = @(y1, y2) M.lincomb(x, 0.5, y1, 0.5, y2);
0067     N.rand = @() M.randvec(x);
0068     N.randvec = @(y) M.randvec(x);
0069     N.zerovec = M.zerovec;
0070     N.lincomb = M.lincomb;
0071     N.transp = @(y1, y2, u) u;
0072     N.hash = @(y) ['z' hashmd5(M.vec(x, y))];
0073
0074     % In a Euclidean space, the exponential is merely the sum: y + tu.
0075     function yy = exponential(y, u, t)
0076         if nargin == 2
0077             t = 1;
0078         end
0079         yy = M.lincomb(x, 1, y, t, u);
0080     end
0081
0082 end```

Generated on Fri 30-Sep-2022 13:18:25 by m2html © 2005