
function [E,P,S,M,N,I] = seo(K,symtyp,pertyp,padtyp)
% SEO Symmetric Extension Operator for producing SPS for use with GDFT and DTT
%   [E,P,S,M,N,I] = seo(K,symtyp,pertyp,padtyp)
%
%   K:      number of representative samples
%   symtyp: type of symmetry:
%
%                 Periodic      |    Antiperiodic     |
%           --------------------|---------------------|-----------
%           WSWS,WAWA,HSHS,HAHA | WSWA,WAWS,HSHA,HAHS | (M = 2N)
%           --------------------|---------------------|-----------
%           WSHS,WAHA,HSWS,HAWA | WSHA,WAHS,HSWA,HAWS | (M = 2N-1)
%
%   pertyp: types of periodicity
%           0: generalized, 1: strict, 2: same for per and antiper (non strict)
%   padtyp: type of padding
%           0: left, 1: right
%
%   E:    the Symmetric Extension Operator
%   P:    periodic (P=1) antiperiodic (P=0)
%   S:    strict period
%   M:    generalized period
%   N:    (I don't know the name of this yet)
%   I:    index of first representative sample
%
%   Notes: Antiperiodic signals with generalized period M are strictly
%          periodic with period 2M. All periodic signals (whether they are
%          periodic or antiperiodic have strict period 2M). All strict
%          periodic operators have period 2M. We always create E by
%          apropriate extension to the right.

% ------- seo.m --------------------------------------------
% Marios Athineos, marios@ee.columbia.edu
% http://www.ee.columbia.edu/~marios/
% Copyright (c) 2004-2005 by Columbia University.
% All rights reserved.
% ----------------------------------------------------------

% Default values
if nargin < 3; pertyp = 1; end % strict
if nargin < 4; padtyp = 1; end % right

% Make sparse identity matrices for the representative samples ...
idx      = 1:K;
e0       = sparse(idx,idx,1);
idx(end) = [];
e1       = sparse(idx,idx,1);
idx(end) = [];
e2       = sparse(idx,idx,1);

% ... and their rotations
re0 = rot90(e0);
re1 = rot90(e1);
re2 = rot90(e2);

% Make zero columns ...
zc0 = sparse(K,1);
zc1 = sparse(K-1,1);
zc2 = sparse(K-2,1);

% ... and rows for padding
zr0 = sparse(1,K);
zr1 = sparse(1,K-1);
zr2 = sparse(1,K-2);

switch upper(symtyp)
    % ------------------------------------------------------
    % M = 2*N, P
    case {'WSWS'}
        N  = K-1;
        M  = 2*N;
        P  = 1;
        I  = 0;
        Eg = [e0;[zc2,re2,zc2]];
    case {'WAWA'}
        N  = K+1;
        M  = 2*N;
        P  = 1;
        I  = 1;
        Eg = [zr0;e0;zr0;-re0];
    case {'HSHS'}
        N  = K;
        M  = 2*N;
        P  = 1;
        I  = 0;
        Eg = [e0;re0];
    case {'HAHA'}
        N  = K;
        M  = 2*N;
        P  = 1;
        I  = 0;
        Eg = [e0;-re0];
    % ------------------------------------------------------
    % M = 2*N, A
    case {'WSWA'}
        N  = K;
        M  = 2*N;        
        P  = 0;
        I  = 0;
        Eg = [e0;zr0;[zc1,-re1]];
    case {'WAWS'}
        N  = K;
        M  = 2*N;        
        P  = 0;
        I  = 1;
        Eg = [zr0;e0;[re1,zc1]];
    case {'HSHA'}
        N  = K;
        M  = 2*N;        
        P  = 0;
        I  = 0;
        Eg = [e0;-re0];
    case {'HAHS'}
        N  = K;
        M  = 2*N;        
        P  = 0;
        I  = 0;
        Eg = [e0;re0];
    % ------------------------------------------------------
    % M = 2*N-1, P
    case {'WSHS'}
        N  = K;
        M  = 2*N-1;        
        P  = 1;
        I  = 0;
        Eg = [e0;[zc1,re1]];
    case {'WAHA'}
        N  = K+1;
        M  = 2*N-1;        
        P  = 1;
        I  = 1;
        Eg = [zr0;e0;-re0];
    case {'HSWS'}
        N  = K;
        M  = 2*N-1;        
        P  = 1;
        I  = 0;
        Eg = [e0;[re1,zc1]];
    case {'HAWA'}
        N  = K+1;
        M  = 2*N-1;        
        P  = 1;
        I  = 0;
        Eg = [e0;zr0;-re0];
    % ------------------------------------------------------
    % M = 2*N-1, A
    case {'WSHA'}
        N  = K;
        M  = 2*N-1;        
        P  = 0;
        I  = 0;
        Eg = [e0;[zc1,-re1]];
    case {'WAHS'}
        N  = K+1;
        M  = 2*N-1;        
        P  = 0;
        I  = 1;
        Eg = [zr0;e0;re0];
    case {'HSWA'}
        N  = K+1;
        M  = 2*N-1;        
        P  = 0;
        I  = 0;
        Eg = [e0;zr0;-re0];
    case {'HAWS'}
        N  = K;
        M  = 2*N-1;        
        P  = 0;
        I  = 0;
        Eg = [e0;[re1,zc1]];
    otherwise
        error('Unknown symmetry type');
end

% Default is generalized
E = Eg;
if pertyp ~=0
    if P
        if pertyp == 2
            E = [Eg;Eg];
        end
    else
        if ~padtyp % left
            E = [-Eg;Eg];
        else        % right
            E = [Eg;-Eg];
        end
    end
end

% Fix the strict period length
if P
    S = M;
else
    S = 2*M;
end