# Output of Zero-forcing equalizer doesn't match theoretical calculations

Let's say I have a sequence $$x[n]$$ (signal) and perform convolution with another sequence $$h[n]$$ (channel), so: $$y[n] = h[n]*x[n] = \sum_{k}{h[k]x[n-k]} \leftrightarrow Y(z) = H(z)X(z)$$

I'm looking for $$C(z)$$ such that: $$C(z)= \frac{1}{H(z)}$$

So that I can compensate the channel: $$c[n]*y[n] = \sum_{k}{c[k]y[n-k]} \leftrightarrow C(z)Y(z) = \frac{1}{H(z)}Y(z) = \frac{1}{H(z)}H(z)X(z) = X(z)$$

Let's assume I know the channel $$h[n]$$ and I use that to obtain $$c[n]$$ using Zero-Forcing equalization.

My question is, if I do:

x = [1 2 3 4 5 6 7];
h = [1 0.9 0.3];
c = zeroforcing(h); % c=[-4.7619, 4.2857, -1.4286]

y = filter(h,1,x);
x_d = filter(c,1,y);


Shouldn't x_d be a delayed version of x ? But I don't seem to get that in my simulations.

(The way I obtain c is converting h to a toeplitz matrix and doing $$c[n]=H^{-1}\delta [n]$$ as explained here:

$$\begin{bmatrix} c_1 \\ c_2 \\ c_3 \end{bmatrix} = \begin{bmatrix} h_2 & h_1 & 0 \\ h_3 & h_2 & h_1 \\ 0 & h_3 & h_2 \end{bmatrix}^{-1} \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix} = \begin{bmatrix} 0.9 & 1 & 0 \\ 0.3 & 0.9 & 1 \\ 0 & 0.3 & 0.9 \end{bmatrix}^{-1} \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix}$$

It seems like there might be something weird going on with that blog, but I only quickly looked. Here is the idea for the ZF equalizer:

1. Figure out the convolution matrix.

convMatrix = convmtx(h, length(x));

This will be a $$9 \times 7$$ matrix because the input vector $$\mathbf{x}$$ is length 7 and the output convolution will be of length $$7+3-1=9$$. It is not a square matrix but we can still get an inverse by computing the Moore-Penrose inverse (https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse), which in MATLAB can be done by calling:

invConvMatrix = pinv(convMatrix);.

1. Choose your delay. invConvMatrix is a $$7 \times 9$$ matrix and we are multiplying with an all zero vector except for a single one at some delay $$\mathbf{\delta}$$. Lets choose the delay to be 5, so we have: $$\mathbf{\delta}=[0, 0, 0, 0, 1, 0, 0, 0, 0]^T$$.

2. Compute the ZF equalizer:

 zfEqualizer = invConvMatrix * d;

1. Generate the received signal, and generate signal after equalization

 y = conv(h, x); z = conv(zfEqualizer, y);

Now lets take a look at the resulting signals, and specifically notice where the equalized signal starts, right at the delay of 5 that we choose earlier. I hope this helps.

• Thanks! I haven't managed to get it working the way you explained. When doing convMatrix = convmtx(h, length(x)); I get a $7x9$ matrix. The pseudoinverse is a $9x7$ matrix though. So I picked $\delta = [0,0,0,0,1,0,0,0,0]$ ($1x9$) and did zfEqualizer = d * invConvMatrix;. A little bit different from what you said, why did this happen? Nov 6 '19 at 10:53
• Also, the way of building the $H$ matrix is a bit different from what I've seen in some books (and in that blog)? The total impulse response tends to be 1 at central point and zeros to the left and right of the 1. In this case, I get all zeros to the left, a central 1 and then non-zeros to the right. Is that how's supposed to be? Thanks again! Nov 6 '19 at 10:53
• Ah, my mistake. I fixed my typo. It should be that the result of pinv is 7x9. Your dimensions aren't matching mine because I am passing everything around as column vectors and you are as row vectors. I do that out of habit but if you read the doc on convmtx it will work with either row or column vectors. I hope that helps! Nov 6 '19 at 17:17
• Also, about the construction of the $\mathbf{H}$ matrix...like I mentioned in my answer I had some doubts about that blog. I read it before and sometimes its accurate sometimes its not. Just googling to check gives the wikipedia: en.wikipedia.org/wiki/Toeplitz_matrix. Scroll to the section on "Discrete Convolution" to convince yourself that it matches the MATLAB implementation. Nov 6 '19 at 17:21