# Strange results with all pass compensation

I am new to DSP and, as a learning exercise, I am trying to design an all-pass filter in order to compensate the phase of an input impulse response (heqm.mat, which you can download from here). The MATLAB code is the following; for the phase compensation I am using the time-reversed technique, also called matched-filter:

load heqm.mat; % Load the heqm vector
HEQM      = fft(heqm);
% Design the all-pass filter
HEQMP     = exp(1j.*angle(HEQM));
tmp       = ifft(HEQMP,'symmetric');
% Time-reversed technique
eqpr      = tmp(end:-1:1);
% Figure on the left
figure; plot(unwrap(angle(fft(heqm))));
hold on; plot(unwrap(angle(fft(eqpr))));
% Convolution of the original impulse response with the all-pass filter
o = conv(heqm,eqpr);
% Figure on the right
figure; plot(unwrap(angle(fft(o))));


As you can see from the left picture, the phase of the all-pass filter is the opposite of the original one. But if I convolve the two vectors, why the resulting phase (right figure) isn't flat as it should be? What am I missing here?

You need to distinguish between circular and linear convolution. The DFT considers all signals to be periodic with the FFT length.

Your all pass filter is non-causal. Due to the periodic nature of the FFT the non-causal part for $$t < 0$$ shows up at the end of the buffer. Applying linear convolution with $$conv$$ makes a mess: you get two copies of your signal. One with the causal part and one with the non-causal part which is delayed by one FFT length.

The way to fix non-causalities is to apply bulk delay: Circulate the impulse response until the peak is in the middle, than convolve. Note that this will also increase the length. This method will always create some amount of error and your system will have overall linear phase behavior.

%% rotate so that the all pass becomes causal
n = length(heqm);
eqprRot = circshift(eqpr,n/2);
% linear cponvolution
result = conv(eqprRot,heqm);
% append a zero to get back to 2^n length
result = [result; 0];
% plot the phase minuse the bulk delay
fResult = fft(circshift(result,-n/2+1));
figure; clf;
plot(angle(fResult(1:n+1)));

• Thank you @Hilmar for the explanation. I don't think I have clear why the all-pass filter is non-causal. Is there a way to show in a more intuitive way the t<0 part from Matlab? The problem of non-causality is in the first all-pass tmp vector from IFFT or in his time-reversed version (eqpr)? – Spark123 Feb 20 at 14:27
• The time reversal is just needlessly complicated way of inverting the phase. HEQMP = exp(-1j.*angle(HEQM)); would work just as well. The allpass is non-causal because there is no reason for it be causal. It's a more less arbitrary phase specification and some phase delays will positive and some will be negative. It's "normal" to be non-causal, there is nothing in it's definition or derivation that would make it causal. – Hilmar Feb 20 at 15:29

UPDATE: As Hilmar pointed out, OP did convolution in the time domain (as is clear in this code). This answer is misleading so will be deleted).

You would not convolve the two responses as you are in the frequency domain. It is the time domain impulse response of the equalization filter that you would convolve with, and convolution in the time domain is the product in the frequency domain. For the product of complex signals, the phases would add, so in your simple example (which may not be realizable due to causality) the phases would add to zero.

For the product of complex signals, the phases would add:

$$K_1e^{j\phi_1}K_2e^{j\phi_2} = K_1K_2e^{j(\phi_1 + \phi_2)}$$

• But heqm (lower cases) used in the convolution is already the time domain impulse response of the equalization, right? – Spark123 Feb 20 at 6:39
• @Dan, I believe Spark123 is correct here. He does convolution in the time domain – Hilmar Feb 20 at 12:30
• @Hilmar Yes I see! I didn’t read his code so jumped at the incorrect conclusion; I’ll delete this misleading answer – Dan Boschen Feb 20 at 13:47