function store = incrementcounter(store, countername, increment)
% Increment a manopt counter in a store or storedb.
%
% function store = incrementcounter(store, countername)
% function store = incrementcounter(store, countername, increment)
% 
% function incrementcounter(storedb, countername)
% function incrementcounter(storedb, countername, increment)
%
% Increment a counter by 1 (default) or by 'increment'. The counter itself
% is stored in a store structure (inside store.shared) or in a storedb
% object (inside storedb.shared); shared is a structure and countername is
% a string that will be used as field name to store the counter value.
%
% Since storedb objects are passed by reference, there is no need to
% collect the output of the function. For store structures on the other
% hand, it is necessary to collect the output and either store it, or
% return it further.
%
% This manopt tool is meant to be used in conjunction with statscounter.
%
% See also: statscounters statsfunhelper

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, July 27, 2018.
% Contributors: 
% Change log: 

    assert(isa(store, 'StoreDB') || ...
           isstruct(store) && isfield(store, 'shared'), ...
           ['First input must be a store structure or a StoreDB object. ' ...
            'The store structure must have the shared memory.']);

    % If the counter does not exist yet, initialize it to 0.
    if ~isfield(store.shared, countername)
        store.shared.(countername) = 0;
    end
    
    % By default, increment counter by 1.
    if ~exist('increment', 'var') || isempty(increment)
        increment = 1;
    end
    
    % The counter is stored in the shared memory of the store or storedb,
    % that is, it is not attached to a particular point on the manifold.
    store.shared.(countername) = store.shared.(countername) + increment;
    
end
