0
$\begingroup$

I am working on a simulation of QPSK data using the code below (Matlab):

j = sqrt(-1);
N = 10^6; % number of symbols
Es_N0_dB = 12; % ratio of signal energy to noise energy in dB
QP = (2*(rand(1,N)>0.5)-1)+j*(2*(rand(1,N)>0.5)-1); % actual QPSK data
s = (1/sqrt(2))*QP; % normalization of energy to 1
n = 1/sqrt(2)*(randn(1,N)+j*randn(1,N)); % white Gaussian noise, 0 dB variance
y = s + 10^(-Es_N0_dB/20)*n; % recovered noisy data
plot(y, 'b.')

This is my resulting constellation diagram:

enter image description here

To identify the errors (and calculating the bit-error-rate), I have divided the diagram into 4 quadrants and used the following to find out which elements have changed sign (i.e. crossed the decision boundaries):

sr=real(s); si=imag(s);
yr=real(y); yi=imag(y);

for i = 1:N
    if sr(i)*yr(i)<0
        errorI(i)=yr(i);
        if si(i)*yi(i)<0
            errorQ(i)=yi(i);
        end
    end
end

err = errorI+j*errorQ;
BER = numel(err)/numel(y);

However, this does not return any data for the in-phase and quadrature errors. What is the problem with this approach?

Any explanation would be greatly appreciated.

$\endgroup$

1 Answer 1

1
$\begingroup$

You're not doing anything conceptually wrong, you're just misunderstanding MATLAB. The code as you provided it doesn't execute properly; here's a fixed script:

% don't need this; MATLAB already knows what j is
%j = sqrt(-1);
N = 10^6; % number of symbols
Es_N0_dB = 12; % ratio of signal energy to noise energy in dB
QP = (2*(rand(1,N)>0.5)-1)+j*(2*(rand(1,N)>0.5)-1); % actual QPSK data
s = (1/sqrt(2))*QP; % normalization of energy to 1
n = 1/sqrt(2)*(randn(1,N)+j*randn(1,N)); % white Gaussian noise, 0 dB variance
y = s + 10^(-Es_N0_dB/20)*n; % recovered noisy data
plot(y, 'b.')
sr=real(s); si=imag(s);
yr=real(y); yi=imag(y);

% it seems like you want to predeclare these since you're indexing them below
errorI = zeros(size(s));
errorQ = zeros(size(s));

for i = 1:N
    if sr(i)*yr(i)<0
        errorI(i)=yr(i);
        if si(i)*yi(i)<0
            errorQ(i)=yi(i);
        end
    end
end

err = errorI+j*errorQ;
% BER is the number of nonzero entries in `err` divided by the number of chances
BER = sum(err ~= 0) / length(y);
$\endgroup$
5
  • $\begingroup$ Thank you so much. Is there any way to plot err on top of the original constellation diagram of the data to see the individual errors points? Because when I use plot(err, 'r.') I get a very strange plot. Why is that? $\endgroup$
    – Merin
    Sep 19, 2017 at 13:35
  • $\begingroup$ For speed and improved robustness in complex arithmetic, use 1i and 1j instead of i and j. $\endgroup$
    – AlexTP
    Sep 19, 2017 at 13:59
  • 1
    $\begingroup$ I don't think the nested ifs are correct, since it's possible to have an error in Q without an error in I. $\endgroup$
    – MBaz
    Sep 19, 2017 at 14:57
  • $\begingroup$ @MBaz you're right. I didn't give too much attention to the logic in the script, I just did enough to get it roughly working. $\endgroup$
    – Jason R
    Sep 19, 2017 at 14:59
  • $\begingroup$ @MBaz Thank you very much for pointing this out. $\endgroup$
    – Merin
    Sep 20, 2017 at 3:50

Your Answer

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

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