how to pass variables into the cost function and gradient function while using store

31 views
Skip to first unread message

Poo Uoo

unread,
Mar 27, 2024, 6:48:59 AMMar 27
to Manopt
hello, 

I am trying to run the first example using the store. 
But how to pass the constant matrix A into the cost function and gradient function?

I don't want to make the variable A's scope span across multiple functions


% Generate random problem data.
n = 1000;
A = randn(n);
A = .5*(A+A.');
% Create the problem structure.
manifold = spherefactory(n);
problem.M = manifold;
% Define the problem cost function and its Euclidean gradient.
problem.cost = @mycost;
problem.egrad = @myegrad; % notice the 'e' in 'egrad' for Euclidean
% Numerically check gradient consistency (optional).
checkgradient(problem);
% Solve.
[x, xcost, info, options] = trustregions(problem);
% Display some statistics.
figure;
semilogy([info.iter], [info.gradnorm], '.-');
xlabel('Iteration number');
ylabel('Norm of the gradient of f');
function [f, store] = mycost(x, store)
if ~isfield(store, 'Ax')
store.Ax = A*x; % The store memory is associated to a specific x
end
Ax = store.Ax;
f = -x'*Ax; % No need to cache f: cost values are cached 'under the hood'
end
function [g, store] = myegrad(x, store)
% This could be placed in a separate function
% to avoid code duplication.
if ~isfield(store, 'Ax')
store.Ax = A*x;
end
Ax = store.Ax;
% Euclidean gradient; this is also cached 'under the hood'.
g = -2*Ax;
end

Nicolas Boumal

unread,
Mar 28, 2024, 5:52:38 AMMar 28
to Manopt
Hello,

A typical approach is as follows:

Define your cost function as:  function [f, store] = mycost(x, store, A)

And add it to your problem structure like this:  problem.cost  = @(x, store) mycost(x, store, A);

Then proceed similarly for all the other functions.

I hope this helps, let us know if it's unclear.

Best,
Nicolas

Poo Uoo

unread,
Mar 30, 2024, 4:47:12 AMMar 30
to Manopt
thanks very much for your help.
Reply all
Reply to author
Forward
0 new messages