function psif = array2cwtfilters(psifVec,arrayIdx)
% ARRAY2CWTFILTERS Convert deep-learning CWT filter tensor to filter bank
% matrix. 
%   PSIF = ARRAY2CWTFILTERS(PSIFVEC,FILTERIDX) reconstructs an
%   approximation to the continuous wavelet filter bank matrix, PSIF, from
%   the 1-by-1-by-Nr tensor, PSIFVEC, and the filter index matrix,
%   FILTERIDX. PSIFVEC and FILTERIDX are outputs of CWTFILTERS2ARRAY.
%
%   If PSIFVEC was constructed with IncludeLowpass=true, the final row of 
%   PSIF is the lowpass (scaling) filter. 
%
%   %Example
%   %   Construct a CWT filter tensor compatible with DLCWT. Use a threshold
%   %   of -Inf which trivially reshapes the filter bank. Show that we can
%   %   recover the filter bank exactly with ARRAY2CWTFILTERS.
%   fb = cwtfilterbank(SignalLength=2048,Boundary="periodic");
%   [psifvec,filtidx] = cwtfilters2array(fb,-Inf);
%   psifR = array2cwtfilters(psifvec,filtidx);
%   psif = freqz(fb,FrequencyRange="twosided");
%   max(abs(psif(:)-psifR(:)))
%
%   See also DLCWT, CWTLAYER, CWTFILTERS2ARRAY, CWT, CWTFILTERBANK

%   Copyright 2022-2023 The MathWorks, Inc.

arguments
    psifVec (1,1,:) {mustBeFinite,mustBeReal,mustBeNonempty}
    arrayIdx (:,4) {mustBeFinite,mustBeReal,mustBeNonempty}
end
nargoutchk(0,1);
[~,~,Nidx] = size(psifVec);
[M,~] = size(arrayIdx);
if Nidx ~= arrayIdx(M,4)
    error(message('wavelet_deep:dlcwt:psifidxMisMatch'));
end

Nf = size(arrayIdx,1)-1;
N = double(arrayIdx(1,2));
EvenLen = signalwavelet.internal.iseven(N);
psif = zeros(Nf,N,underlyingType(psifVec));
IsLP = arrayIdx(Nf+1,1) == 1;
for ii = 1:Nf
    psif(ii,arrayIdx(ii+1,1):arrayIdx(ii+1,2)) = ...
        psifVec(1,1,arrayIdx(ii+1,3):arrayIdx(ii+1,4));
end
if IsLP && EvenLen
    psif(Nf,N/2+2:N) = flip(conj(psif(Nf,2:N/2)));
elseif IsLP && ~EvenLen
    psif(Nf,floor(N/2)+2:N) = flip(conj(psif(Nf,2:floor(N/2)+1)));
end
