Home > manopt > tools > checkretraction.m

checkretraction

PURPOSE ^

Check the order of agreement of a retraction with an exponential.

SYNOPSIS ^

function checkretraction(M, x, v)

DESCRIPTION ^

 Check the order of agreement of a retraction with an exponential.
 
 function checkretraction(M)
 function checkretraction(M, x)
 function checkretraction(M, x, v)

 checkretraction performs a numerical test to check the order of agreement
 between the retraction and the exponential map in a given Manopt
 manifold structure M. The test is performed at the point x if it is
 provided (otherwise, the point is picked at random) and along the tangent
 vector v at x if one is provided (otherwise, a tangent vector at x is
 picked at random.)

 See also: checkdiff checkgradient checkhessian

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function checkretraction(M, x, v)
0002 % Check the order of agreement of a retraction with an exponential.
0003 %
0004 % function checkretraction(M)
0005 % function checkretraction(M, x)
0006 % function checkretraction(M, x, v)
0007 %
0008 % checkretraction performs a numerical test to check the order of agreement
0009 % between the retraction and the exponential map in a given Manopt
0010 % manifold structure M. The test is performed at the point x if it is
0011 % provided (otherwise, the point is picked at random) and along the tangent
0012 % vector v at x if one is provided (otherwise, a tangent vector at x is
0013 % picked at random.)
0014 %
0015 % See also: checkdiff checkgradient checkhessian
0016 
0017 % This file is part of Manopt: www.manopt.org.
0018 % Original author: Nicolas Boumal, Oct. 21, 2016.
0019 % Contributors:
0020 % Change log:
0021 
0022     if ~isfield(M, 'exp')
0023         error(['This manifold has no exponential (M.exp): ' ...
0024                'no reference to compare the retraction.']);
0025     end
0026 
0027     if ~exist('x', 'var') || isempty(x)
0028         x = M.rand();
0029         v = M.randvec(x);
0030     end
0031     
0032     if ~exist('v', 'var') || isempty(v)
0033         v = M.randvec(x);
0034     end
0035     
0036     % Compare the retraction and the exponential over steps of varying
0037     % length, on a wide log-scale.
0038     tt = logspace(-12, 0, 251);
0039     ee = zeros(size(tt));
0040     for k = 1 : numel(tt)
0041         t = tt(k);
0042         ee(k) = M.dist(M.exp(x, v, t), M.retr(x, v, t));
0043     end
0044     
0045     % Plot the difference between the exponential and the retration over
0046     % that span of steps, in log-log scale.
0047     loglog(tt, ee);
0048     
0049     % We hope to see a slope of 3, to confirm a second-order retraction. If
0050     % the slope is only 2, we have a first-order retration. If the slope is
0051     % less than 2, this is not a retraction.
0052     % Slope 3
0053     line('xdata', [1e-12 1e0], 'ydata', [1e-30 1e6], ...
0054          'color', 'k', 'LineStyle', '--', ...
0055          'YLimInclude', 'off', 'XLimInclude', 'off');
0056     % Slope 2
0057     line('xdata', [1e-14 1e0], 'ydata', [1e-20 1e8], ...
0058          'color', 'k', 'LineStyle', ':', ...
0059          'YLimInclude', 'off', 'XLimInclude', 'off');
0060      
0061 
0062     % Figure out the slope of the error in log-log, by identifying a piece
0063     % of the error curve which is mostly linear.
0064     window_len = 10;
0065     [range, poly] = identify_linear_piece(log10(tt), log10(ee), window_len);
0066     hold all;
0067     loglog(tt(range), 10.^polyval(poly, log10(tt(range))), 'LineWidth', 3);
0068     hold off;
0069     
0070     xlabel('Step size multiplier t');
0071     ylabel('Distance between Exp(x, v, t) and Retr(x, v, t)');
0072     title(sprintf('Retraction check.\nA slope of 2 is required, 3 is desired.'));
0073     
0074     fprintf('Check agreement between M.exp and M.retr. Please check the\n');
0075     fprintf('factory file of M to ensure M.exp is a proper exponential.\n');
0076     fprintf('The slope must be at least 2 to have a proper retraction.\n');
0077     fprintf('For the retraction to be second order, the slope should be 3.\n');
0078     fprintf('It appears the slope is: %g.\n', poly(1));
0079 
0080 end

Generated on Mon 10-Sep-2018 11:48:06 by m2html © 2005