function b = firlp2hp(b,flag)
%FIRLP2HP  FIR lowpass to highpass transformation.

%   References: 
%     [1] T. Saramaki, Finite impulse response filter design, in 
%          Handbook for Digital Signal Processing. S.K. Mitra and
%          J.F. Kaiser Eds. Wiley-Interscience, N.Y., 1993, Chapter 4.

%   Copyright 1999-2023 The MathWorks, Inc.

%#codegen

arguments
    b (:,:) {mustBeNumeric}
    flag (1,:) char {mustBeMember(flag,{'narrow','wide'})} = 'narrow'; 
end

N = cast(length(b),like=b) - 1; % FIR order

symmetric = strcmpi(symmetrytest(b, 1),'symmetric');
coder.internal.errorIf(strcmp(flag,'wide') && (~symmetric || rem(N,2)), 'dsp:firlp2hp:FilterErr2');

switch lower(flag)
case 'narrow'
	% Compute B(-z), 
	b(2:2:end)=-b(2:2:end);
	
    %if rem(length(b),2) % =>order N is even
    if rem(N,2)==0 % =>order N is even
        % Multiply by (-1)^(N/2)
        coeffSign = cast(-1,like=b)^(N./2);
        b = coeffSign.*b;
    end	
case 'wide'
	% Implement as a parallel of two FIR filters, -B(z) and z^(-N/2)
    dly = zeros(1,N/2+1,like=b);
	dly(N/2+1) = 1; % z^(-N/2)
    
    [dly,b] = eqtflength(dly,b);
    b = dly - b;
	b = removetrailzeros(b);
otherwise
	coder.internal.error('dsp:firlp2hp:FilterErr1');
end
end

%-----------------------------------------------------------------------------
function symstr = symmetrytest(b,removezerosFlag,tol)
%SYMMETRYTEST  Test if vector corresponds to a symmetric or antisymmetric polynomial.
arguments
    b (:,:) {mustBeNumeric}
    removezerosFlag (1,1) logical = false;
    tol (1,1) = eps^(2/3);
end

% Convert b to a row
b = b(:).';

% Remove leading and trailing zeros of b
if removezerosFlag
    if all(b==0)
        b = cast(0,like=b);
    else
        % Remove leading and trailing zeros of b 
        firstnonzero = find(b,1);
        lastnonzero  = find(b,1, 'last');
        b = b(firstnonzero(1):lastnonzero(1));
    end
end

% For complex filters, use the hermitian terminology
if ~isreal(b)
    if max(abs(b - conj(b(end:-1:1)))) <= tol
        symstr = 'hermitian';
    elseif max(abs(b + conj(b(end:-1:1)))) <= tol
        symstr = 'antihermitian';
    else
        symstr = 'none';
    end
else
    if max(abs(b - b(end:-1:1))) <= tol
        symstr = 'symmetric';
    elseif max(abs(b + b(end:-1:1))) <= tol
        symstr = 'antisymmetric';
    else
        symstr = 'none';
    end    
end
end
