function X = detoeplitzize(T,varargin)
%DETOEPLITZIZE Recover the generating vector(s) from an (approximate)
%Toeplitz matrix/tensor.
%   X = DETOEPLITZIZE(H) converts an (approximate) Toeplitz matrix T of
%   size I1 x I2 into a column vector X of length I1+I2-1 by averaging
%   along the diagonals (hyperplanes) of the Toeplitz matrix (tensor).
%
%   DETOEPLITZIZE(H,'key',value,...) or DETOEPLITZIZE(X,options) can be used to
%   pass the following options:
%
%   - Method:        Indicates the detoeplitzation method:
%                    - If 'fibers', the first column and row is extracted.
%                    - If 'mean' or @mean (default), the diagionals or
%                      hyperplanes are averaged.
%                    - If a function handle (such as @median), this
%                      function is applied on the diagonals or the
%                      hyperplanes.
%                    Alternatives of 'mean' can only be used when T is a
%                    full tensor.
% 
%   See also dehankelize, hankelize, deloewnerize, desegmentize, dedecimate
   
%   Authors: Otto Debals (Otto.Debals@esat.kuleuven.be)
%            Marc Van Barel (Marc.VanBarel@cs.kuleuven.be)
%            Lieven De Lathauwer (Lieven.DeLathauwer@kuleuven-kulak.be)
%
%   References:
%   [1] O. Debals, L. De Lathauwer, "Stochastic and Deterministic
%       Tensorization for Blind Signal Separation," Latent Variable
%       Analysis and Signal Separation, Springer Berlin / Heidelberg, Vol.
%       9237, 2015, pp. 3-13.
%
%   Version History:
%   - 2017/02/28   OD      Initial version, based on dehankelize.m 02/28

p = inputParser();
p.addOptional('Method',@mean);
p.KeepUnmatched = false;
p.parse(varargin{:});
options = p.Results;

switch getstructure(T)
    case 'full'
        T = T(end:-1:1,:);
        X = dehankelize(T,'Method',options.Method);
    case 'hankel'
        error('Not yet supported')
    case 'cpd'
        error('Not yet supported')
    case {'incomplete','sparse','tt','btd','lmlragen'}
        T = ful(T);
        T = T(end:-1:1,:);
        X = dehankelize(T,'Method',options.Method);
end