function vnorms = framevectornorms(F,L,varargin)
%-*- texinfo -*-
%@deftypefn {Function} framevectornorms
%@verbatim
%FRAMEVECTORNORMS  Norm of frame vectors 
%   Usage: vnorms = framevectornorms(F,L)
%          vnorms = framevectornorms(F,L,idx)
%
%   Input parameters:
%       F        : Frame definition
%       L        : System length
%       idx      : Index (or range) of vector(s)
%   Output parameters:
%       vnorms   : Vector norms
%
%   FRAMEVECTORNORMS(F,L) returns 2-norms of vectors of frame F for
%   system length L. The number of vectors in a frame (and the length of
%   the output vector) can be obtained as frameclength(F,L).
%
%   FRAMEVECTORNORMS(F,L,idx) returns 2-norms of vectors with indices 
%   idx. Elements in idx must be in range 1:frameclength(F,L).
%
%   Real-valued-input frames
%   ------------------------
%
%   By default, the function returns the norm of vectors used for
%   synthesis. Frames like 'dgtreal', 'filterbankreal' do not contain the 
%   ''redundant'' conjugate-symmetrix vectors and their synthesis operator
%   is not linear. Therefore the vectors used in synthesis do not have 
%   an explicit form and their norm is unspecified. The vectors used for 
%   analysis are well defined and can be obtained by passing additional
%   flag 'ana'.
%
%@end verbatim
%@strong{Url}: @url{http://ltfat.github.io/doc/frames/framevectornorms.html}
%@seealso{frsynmatrix}
%@end deftypefn

% Copyright (C) 2005-2016 Peter L. Soendergaard <peter@sonderport.dk>.
% This file is part of LTFAT version 2.3.0
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

%AUTHOR: Zdenek Prusa

thismfile = upper(mfilename);
complainif_notenoughargs(nargin,2,thismfile);
complainif_notvalidframeobj(F,thismfile);
complainif_notposint(L,'L',thismfile);

definput.keyvals.idx=[];
definput.flags.anasyn = {'syn','ana'};
[flags,kv,idx]=ltfatarghelper({'idx'},definput,varargin);

Lcheck = framelength(F,L);

if Lcheck~=L
    error('%s: Incompatible frame length. Next compatible one is %i.',...
          upper(mfilename),Lcheck);
end

if F.realinput && flags.do_syn
     error(['%s: The real-valued-input frame synthesis opearor is ' ...
            'non-linear, therefore the vector norms are undefined. ' ... 
            'To get norms of the vectors used in the analysis pass ' ...
            '''ana'''], upper(mfilename));
end

N = frameclength(F,L);

if isempty(idx)
    idx = 1:N;
end

if any(idx > N) || any(idx < 1)
    error('%s: Requested vector index is not in range 1:%d', ...
          thismfile,N);
end

F = frameaccel(F,L);
vnorms = zeros(numel(idx),1);
    
switch F.type
    case 'gen'
        [~,vnorms] = normalize(F.g(:,idx));
    case {'dgt','dgtreal','dwilt','wmdct'}
        vnorms(:) = norm(F.g);
    case {'filterbank','filterbankreal','ufilterbank'}
        [~,scal] = filterbankscale(F.g,L,'2');
        channorm = 1./scal;
        subidx = [0; cumsum(L./F.a(:,1).*F.a(:,2))];
        for ii = 1:numel(vnorms)
           vnorms(ii) = channorm(find( idx(ii) > subidx, 1,'last'));
        end
    case { 'dft','dftreal',...
           'dcti','dctii','dctiii','dctiv',...
           'dsti','dstii','dstiii','dstiv' }
         vnorms(:) = 1;
    otherwise
        % Fallback option
        if ~flags.do_syn
            error('%s: Unsupported frame.',thismfile);
        end

        ctmp = zeros(N,1);
        for ii = 1:numel(vnorms)
            ctmp(idx(ii)) = 1;
            vnorms(ii) = norm(F.frsyn(ctmp));
            ctmp(:) = 0;
        end
end

