How to perform spectral inversion in the frequency domain to convert a low-pass filter into a high-pass filter? To convert a linear-phase FIR low-pass filter into a high-pass filter with the same cut-off frequency, we can invert the sign of the low-pass filter's impulse response $h(n)$ and then add one to the center point: $\delta(n)-h(n)$, where the $\delta(n)$ is the unit impulse function.

I am trying to verify the result in the frequency domain. If the DFT of $h(n)$ is $H(f)$, then the DFT of $\delta(n)-h(n)$ is $1-H(f)$. However, in MATLAB it seems that I cannot generate the desired high-pass filter kernel by applying the ifft() function to $1-H(f)$. The unit impulse function is added to the first point of the high-pass filter kernel instead of the center point. What is the reason for this and how can I correct my code?



MATLAB code to generate this figure:

%% Generate window-sinc filter coefficients
% CutOffFreq and TransBandWidth should be expressed as fractions of sampling rate between 0 and 0.5.
CutOffFreq = 0.1;
TransBandWidth = 0.01;

% Approxiately calculate the filter order (must be a even integer).
M = 4 / TransBandWidth;
M = round((M-2)/2)*2+2; % Round to the nearest even integer

% Generate the sinc function. Filter length = filter order + 1.
idx = 0:1:M;
Sinc = sin(2*pi*CutOffFreq*(idx-M/2)) ./ (idx-M/2);
Sinc(M/2+1) = 2 * pi * CutOffFreq;  % Solve the divided by zero problem

% Generate the Blackman window.
BlackMan = 0.42 - 0.5*cos(2*pi*idx/M) + 0.08*cos(4*pi*idx/M);

% Generate the filter coefficients (the impulse response function).
b = Sinc .* BlackMan;

% Normalized the filter coefficients to have unity gain at DC.
b = b / sum(b);

%% Spectral inversion in the frequency domain
bfft = fft(b);
b1 = ifft(1-bfft);

figure('Color','w');
plot(b,'Color','b','LineWidth',1);
hold on;
plot(b1,'Color','m','LineWidth',1);
xlim([-1,length(b)+1]);
legend({'Low-pass filter kernel','Wrong high-pass kernel'});
The flaw in your logic is assuming that the frequency response of your lowpass filter in its passband is identically $1$. You're inherently assuming this when thinking that you can form the highpass filter by simply calculating $H_{hp}(f) = 1 - H_{lp}(f)$. 

However, the lowpass filter has group delay because the peak of the sinc function doesn't occur at $n = 0$. Instead, as a symmetric FIR filter, it will have a delay of $\frac{N}{2}$ samples, where $N$ is the filter order. This means that the frequency response of the filter across the passband may have unity magnitude, but it will have linear phase! Recall the time shift property of the discrete-time Fourier transform:

$$
x[n-k] \Leftrightarrow X(f)e^{-j2\pi fk}
$$

So, instead of your prototype lowpass filter having a response of $1$ in the passband, it actually has a response of $e^{-j2\pi fk}$, which imparts a phase shift that is linearly proportional to frequency. If you would like to transform this filter to a highpass structure with equivalent group delay, you would need to take this into account when synthesizing your highpass filter in the frequency domain:

$$
H_{hp}(f)= e^{-j2\pi f\frac{N}{2}} - H_{lp}(f)
$$