Well, I took a look at your code, and spent a lot of time on it, and I have discovered some mistakes, some practicals and some theoretics. Here are my answers:
(1) You can use the function filter. Just remember that it returns a vector of the same length of the input, while conv returns the $ N_x + N_h - 1 $, where $ N_x $ is the length of your input and $ N_h $ is the length of your channel. This difference needs to be take in consideration when you create your noise vector. You won't be able to add the noise vector to your signal if you don't pay attention to this. Read the documentation to get more information.
(2) As I said, there is a lot of mistakes at your code:
- First I changed the vector noise to only add a real number to the signal, and not a complex number.
- Second, I changed the equation
w = w - mu * e(i) * yy * x;
w = w - mu * x * e(i) * yy.'
that I took from here.
- There is some mistakes in your CMA algorithm. Here are some lines and the coments:
yy = w(:,i).'*x; Remeber to conjugate w in this. In BPSK we only have real numbers so this is not a problem, but if you had complex numbers, you must conjugate w.
e(i) = abs(yy)^2 - 1; In your original code, you didn't use abs(y) to calculate the error. Again, it is not a problem if you are only working with real numbers, but it will become a problem with complex numbers.
- The way that you are getting the vector x inside the CMA loop is not getting all the samples since the beginning. So I iniciated the vector x before the loop as:
x = zeros(Le, 1);
and inside the loop I used:
x = [r(i); x(1:end-1)];
It will start CMA from the beginning of the receiving symbols.
- This line doesn't make sense:
This only equalizes ONE sample. The correct way to perform the equalization once you have the filter coefficients is:
sb = filter(w(:,N+1), 1, y);
Remember what I said about the function filter and the function conv. Read the documentation.
- The next problem is in your number of errors computing. This is a very trick, but you need to remember (or learn) that every equalizer generates a delay in your signal. So you cant do
ip- ipHat directly. You need to compensate this delay. I used:
nErr_CMA(ii) = size(find([ip(1:end-Le+1) - ipHat(Le:end)]),2);
If you don't know about this delay, you need to study a litle bit more.
- In the plot part, I used the following:
%axis([0 14 10^-5 0.5])
ylabel('Bit Error Rate');
title('Bit error probability curve for BPSK in ISI with CMA equalizer');
I also increased N to N = 1e5, so as to perform a Monte Carlo simulation properly.
I changed Le to Le = 5;
I changed the w initializations for w = ones(Le, 1); to avoid that the update part of the CMA equation results in zero.
Also, change your channel. I didn't have time to verify that, but I strongly suspect that the channel [0.2 0.9 0.3] has some properties that makes it difficult for the CMA to equalize. I used ht = [1 0.5 0.2]. Try using this channel.
Ok, I gave you a lot of answers. I don't know if there is any more mistakes, but here I was able to get a BER curve that looks right. If it is right or not, it is up to you. I suggest you to look for articles about communications systems using CMA algorithm and compare your results.
Let me know if I need to let anything I said more clear. Good luck on your research.