I need help in plotting the Bit error curve or the symbol error curve for BPSK modulation scheme for varying Signal to Noise ratios or Eb/N0. The plot should show the simulated versus the theoretical curve, but I cannot figure out how to mitigate the problems when using the Constant Modulus Algorithm as an Equalizer which are

(1) I want to use the filter function instead of conv in order to model a moving average channel model, chanOut = filter(ht,1,s). But, when I use filter, I am getting an error. How can I use filter function here?

(2) Bit error rate calculation

I am still unable to use filter and unsure if BER curve is proper or not. Below is the code I wrote:

UPDATE after the answer posted, I have included all the suggestions. The error has been mitigated but now the curve for CMA is coming out to be flat instead of the one shown in the answer. Would like to know what I should do to get similar curve.

  • 2
    $\begingroup$ This site explicitly frowns on asking for code to be written to a specification, as you did: if somebody can provide the additional code for this. $\endgroup$
    – Peter K.
    Oct 10, 2015 at 21:22
  • 1
    $\begingroup$ Which error do you get when using filter? It's important to have in mind that the output from filter have the same length that the input, different from the conv. So, if you are using conv, at some point you need to "ignore" the exceeding samples, and you don't need to do that when using filter. Maybe this is the problem. $\endgroup$
    – JohnMarvin
    Oct 13, 2015 at 21:09
  • $\begingroup$ Also, plot the evolution of the filter coefficients, to see it is converging. You can also plot the error in a log scale in order to see the convergence. $\endgroup$
    – JohnMarvin
    Oct 13, 2015 at 21:10
  • $\begingroup$ I don't know if this line is correct: nErr_CMA(ii) = size(find([ip- ipHat]),2); I think it is not computing the number of errors. Check the values of nerr_CMA and see if it is true. I am not executing the code, I am just thinking over the code. $\endgroup$
    – JohnMarvin
    Oct 13, 2015 at 21:20

1 Answer 1


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:

figure semilogy(Eb_N0_dB,theoryBer,'b'),grid; hold on; semilogy(Eb_N0_dB,simBer_CMA,'r-','Linewidth',2); %axis([0 14 10^-5 0.5]) grid on legend('Theoretical BER','sim-CMA'); xlabel('Eb/No, dB'); 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.

BER for BPSK with CMA Equalization

Let me know if I need to let anything I said more clear. Good luck on your research.

  • $\begingroup$ Thank you for your answer in such clarity. The difference between filter and conv was really beneficial and that problem is solved. However, I am getting an Error in this statement sb = filter() which is Attempted to access w(:,101); index out of bounds because size(w)=[20,1]. Error in BER_CMA (line 64) sb = filter(w(:,N+1), 1, y); % estimate symbols (perform equalization) $\endgroup$
    – Ria George
    Oct 14, 2015 at 2:03
  • $\begingroup$ I wonder how you did not get any error and got the curve. I have used filter instead of conv(). The estimated weight w is of size 20 by 1, so why are we doing w(:,N+1)? Can you please let me know what to do? $\endgroup$
    – Ria George
    Oct 14, 2015 at 2:04
  • $\begingroup$ I have done instead $sb = filter(w, 1, y); $ and the error is not there anymore. But my BER curve looks different than yours- the Theoretical does not seem to start from zero. I have put up the image of the curve. Can you suggest what to do? $\endgroup$
    – Ria George
    Oct 14, 2015 at 2:10
  • $\begingroup$ This is how I have created the noise signal: n = 1/sqrt(2)*[randn(1,N)]; The curve put up by you starts from the zero and the BER for Simulated CMA decreases, but mine Theoretical does not start from zero and the Simulated remains flat!!! This is weird. $\endgroup$
    – Ria George
    Oct 14, 2015 at 2:19
  • 1
    $\begingroup$ I edited the answer including this part. Take a look! If you have more questions, call me in the chat. $\endgroup$
    – JohnMarvin
    Oct 14, 2015 at 23:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.