function combis = param_combinations(params, pos)
% given a param struct with multiple options for diverse
% parameters, param_combinations(params) returns all 
% valid combinations of the param sets

if nargin < 2
    pos = 1;
end

% get available fields
fields = fieldnames(params);

nparams = params;
    if pos <= numel(fields)
        
        for j = 1:numel(params.(fields{pos}))

            % ---
            % successively ralter the params struct,
            % choosing one of the options
            % ---
            if ~iscell(params.(fields{pos}))
                
                nparams.(fields{pos}) = params.(fields{pos})(j);
            else
                
                nparams.(fields{pos}) = params.(fields{pos}){j};
            end
            
            if j == 1
                combis = param_combinations(nparams, pos + 1);
                
            else
                
                % gather the resulting configurations, in reverse order 
                % regarding the recursion
                combis = cat(1, param_combinations(nparams, pos + 1), combis);
            end
        end
    else
        % we have reached the leaves, containing single combinations
        combis = nparams;
    end    
end
