Returns an orthonormal basis of tangent vectors in the Manopt framework. function orthobasis = tangentorthobasis(M, x) function orthobasis = tangentorthobasis(M, x, n) function orthobasis = tangentorthobasis(M, x, n, basis_vecs) Inputs: M is a Manopt manifold structure obtained from a factory. x is a point on the manifold M. n (optional) is the dimension of the random subspace to span; by default, n = M.dim() so that the returned basis spans the whole tangent space. basis_vecs (optional) is a cell of tangent vectors that are assumed to be linearly independent. Their independence is not checked. Output: orthobasis is a cell of n tangent vectors at x. With high probability, they form an orthonormal basis of the tangent space at x. If necessary, this can be checked by calling G = grammatrix(M, x, orthobasis) and verifying that norm(G - eye(size(G))) is close to zero. If basis_vecs is not specified then n vectors are taken at random in the tangent space, then orthonormalized using Gram-Schmidt. If basis_vecs is specified, then: If length(basis_vecs) >= n, the first n vectors in basis_vecs are passed are orthogonalized and returned. If length(basis_vecs) < n, we append n - length(basis_vecs) random vectors to basis_vecs, and we orthogonalize then return the resulting cell. Therefore if basis_vecs is provided, the span of the first min(n, length(basis_vecs)) vectors in basis_vecs is always a subspace of the span of the returned orthobasis. Note: if extra accuracy is required, it may help to re-orthogonalize the basis returned by this function once, as follows: B = tangentorthobasis(M, x, ...); B = orthogonalize(M, x, B); See also: grammatrix orthogonalize lincomb tangent2vec plotprofile
0001 function orthobasis = tangentorthobasis(M, x, n, basis_vecs) 0002 % Returns an orthonormal basis of tangent vectors in the Manopt framework. 0003 % 0004 % function orthobasis = tangentorthobasis(M, x) 0005 % function orthobasis = tangentorthobasis(M, x, n) 0006 % function orthobasis = tangentorthobasis(M, x, n, basis_vecs) 0007 % 0008 % Inputs: 0009 % M is a Manopt manifold structure obtained from a factory. 0010 % x is a point on the manifold M. 0011 % n (optional) is the dimension of the random subspace to span; by default, 0012 % n = M.dim() so that the returned basis spans the whole tangent space. 0013 % basis_vecs (optional) is a cell of tangent vectors that are assumed to be 0014 % linearly independent. Their independence is not checked. 0015 % 0016 % Output: 0017 % orthobasis is a cell of n tangent vectors at x. 0018 % With high probability, they form an orthonormal basis of the tangent 0019 % space at x. If necessary, this can be checked by calling 0020 % G = grammatrix(M, x, orthobasis) 0021 % and verifying that norm(G - eye(size(G))) is close to zero. 0022 % 0023 % If basis_vecs is not specified then n vectors are taken at random in 0024 % the tangent space, then orthonormalized using Gram-Schmidt. 0025 % 0026 % If basis_vecs is specified, then: 0027 % If length(basis_vecs) >= n, the first n vectors in basis_vecs are 0028 % passed are orthogonalized and returned. 0029 % If length(basis_vecs) < n, we append n - length(basis_vecs) random 0030 % vectors to basis_vecs, and we orthogonalize 0031 % then return the resulting cell. 0032 % 0033 % Therefore if basis_vecs is provided, the span of the first 0034 % min(n, length(basis_vecs)) vectors in basis_vecs is always a 0035 % subspace of the span of the returned orthobasis. 0036 % 0037 % Note: if extra accuracy is required, it may help to re-orthogonalize the 0038 % basis returned by this function once, as follows: 0039 % B = tangentorthobasis(M, x, ...); 0040 % B = orthogonalize(M, x, B); 0041 % 0042 % See also: grammatrix orthogonalize lincomb tangent2vec plotprofile 0043 0044 % This file is part of Manopt: www.manopt.org. 0045 % Original author: Nicolas Boumal, April 28, 2016. 0046 % Contributors: 0047 % Change log: 0048 % 0049 % VL July 17, 2022: 0050 % Added the option to input basis_vecs to specify a linearly 0051 % independent set of tangent vectors to pass to orthogonalize. 0052 0053 0054 dim = M.dim(); 0055 if ~exist('n', 'var') || isempty(n) 0056 n = dim; 0057 end 0058 assert(n >= 0 && n <= dim && n == round(n), ... 0059 'n must be an integer between 0 and M.dim().'); 0060 0061 basis = cell(n, 1); 0062 0063 % With high probability, vectors taken at random in the tangent space 0064 % are linearly independent of basis_vecs 0065 for k = 1 : n 0066 if exist('basis_vecs', 'var') && k <= length(basis_vecs) 0067 basis(k, 1) = basis_vecs(k, 1); 0068 else 0069 basis{k} = M.randvec(x); 0070 end 0071 end 0072 0073 % The Gram-Schmidt process transforms any n linearly independent 0074 % vectors into n orthonormal vectors spanning the same subspace. 0075 orthobasis = orthogonalize(M, x, basis); 0076 0077 end