function sid = initSID2D(Qv, Qh, Pv, Ph, y)
% initSID2D       Initialize Shift Invariant FSD (SID) for 2D case
%
% If no example signal is given as input, atoms are random.
% If an example signal is given random patches from signal is used.
% If example signal has exactly Q elements these values are copied to freeVar.
%
% use:   sid = initSID2D(Qv, Qh);
%        sid = initSID2D(Qv, Qh, y);
%        sid = initSID2D(Qv, Qh, Pv, Ph);
%        sid = initSID2D(Qv, Qh, Pv, Ph, y);
% -------------------------------------------------------------------------
%   Qv,Qh  The vertical and horizontal size for each atom, size Mx1
%   Pv,Ph  The shift to use for each atom, for rows and columns, size Mx1
%   y      An example signal, or the dictionary variables
%   sid   The 2D Shift Invariant Dictionary, a struct with fields
%         Type     : always  'SID2D'
%         Text     : always  'Shift Invariant Dictionary 2D'
%         M        : number of atoms in dictionary
%         Q        : total number of free variables, sum(Qv.*Qh)
%         Qv,Qh    : size of each atom, size Mx1
%         Pv,Ph    : shift for each atom, size Mx1
%         freeVar  : the free variables, a vector of size Qx1
%         i1,i2    : perhaps also these, atom m is 
%                    sid.freeVar(sid.i1(m):sid.i2(m))
%         Other fields may be included when needed, ex:
%         AtA      : representation of A'*A, for learning, QxQ
%         Atb      : representation of A'*b for dictionary learning, Qx1
%         Info     : text telling how dictionary was learned/used
% -------------------------------------------------------------------------
% ex:   Qv = [4,4,4]; Qh = [4,4,4]; sid = initSID2D(Qv,Qh);

%----------------------------------------------------------------------
% Made by Karl Skretting, University of Stavanger (UiS), 
% Department of Electrical Engineering and Computer Science (IDE)
% Mail:  karl.skretting@uis.no   Homepage:  http://www.ux.uis.no/~karlsk/
% 
% HISTORY:  dd.mm.yyyy
% Ver. 1.0  24.06.2016  KS: made file 
% Ver. 1.1  15.09.2017  KS: simplified initialization of Qh, Pv and Ph
%----------------------------------------------------------------------

sid = [];
if (nargin < 2); return; end;
M = numel(Qv); 
Qv = reshape(Qv,M,1);    % Qv a Mx1 vector
Qh = reshape(Qh,M,1);    % Qh a Mx1 vector
if (nargin < 3); y = []; end;
if (nargin == 3); y = Pv; end;
if (nargin < 4) 
    Pv = ones(M,1); 
    Ph = ones(M,1); 
else
    % Pv or Ph may have length 1
    if (length(Pv) == M)
        Pv = reshape(Pv,M,1);    % a Mx1 vector
    else
        Pv = Pv(1)*ones(M,1);    % or use only first element
    end
    if (length(Ph) == M)
        Ph = reshape(Ph,M,1);    % a Mx1 vector
    else
        Ph = Ph(1)*ones(M,1);    % or use only first element
    end
end

Qm = Qv.*Qh;   % Mx1
Q = sum(Qm);
i2 = cumsum(Qm);
i1 = [1; i2(1:(M-1))+1];

sid = struct( 'Type', 'SID2D', ...
    'Text', 'Shift Invariant Dictionary 2D', ...
    'Info', ['Initialized by ',mfilename,' ',datestr(now),'.'], ...
    'M', M, ...      % number of atoms
    'Q', Q, ...      % total number of free variables
    'Qv',Qv,'Qh',Qh, ...     % length of each atom
    'Pv',Pv,'Ph',Ph, ...     % shift for each atom
    'freeVar',zeros(Q,1), ... % the free variables
    'i1',i1, ...
    'i2',i2  );

% initializing 
if isempty(y)
    sid.freeVar = randn(Q,1);
else
    [Nv,Nh] = size(y);
    if (Nv*Nh == Q)
        sid.freeVar = y(:);
    else
        for m=1:M
            if ((Nv >= Qv(m)) && (Nh >= Qh(m)))
                iv = floor((Nv-Qv(m)+1)*rand(1))+(1:Qv(m));
                ih = floor((Nh-Qh(m)+1)*rand(1))+(1:Qh(m));
                sid.freeVar(i1(m):i2(m)) = reshape(y(iv,ih), Qv(m), Qh(m));
            else
                sid.freeVar(i1(m):i2(m)) = randn(Qv(m)*Qh(m),1);
            end
        end
    end
end

for m = 1:M
    a = sid.freeVar(i1(m):i2(m));
    sid.freeVar(i1(m):i2(m)) = a/norm(a);  % normalize
end

end
