Continue to Site

# Help with QPSK run time in MATLAB

Status
Not open for further replies.

#### joserse46

##### Newbie level 4
Hello I just completed a assignment for QPSK in MATLAB, it works fine, but wanted to see if I could get some help on run time as it takes a while to execute the m file. Any pointers would be appreciated. I am only simulating the baseband part. Thanks in advance for any suggestions!

In the block diagram i forgot to label x (inphase) and y(quadrature) before the AWGN channel
Oh and the output of the decoder should be d_hat1 and d_hat2

https://obrazki.elektroda.pl/3087588200_1361063670.jpg

Matlab code[%qpsk.m models baseband qpsk with N input bits

clear
clc

N = 10^4; %number of input bits
Eb_No = 1:.2:7; % In decibels
for k=1:length(Eb_No);
EB_NO = 10.^(k/10); % linear scale
%source
for i = 1:N;
d1(i) = randint;
d2(i) = randint;
end
for j = 1:N
%qpsk encoding

if [d1(j) d2(j)] == [0 0];
I(j) = sqrt(EB_NO*2) ;
Q(j) = 0 ;

elseif [d1(j) d2(j)] == [0 1];
I(j) = 0 ;
Q(j) = -sqrt(EB_NO*2);

elseif [d1(j) d2(j)] == [1 0];
I(j) = -sqrt(EB_NO*2) ;
Q(j) = 0 ;

else
I(j) = 0;
Q(j) = sqrt(EB_NO*2);
end

%pulse shaping
for i = 1:4;
s = [.5 .5 .5 .5];
x(4*(j-1)+i) = I(j)*s(i);
y(4*(j-1)+i) = Q(j)*s(i);
end

%channel
for i = 1:4;
w_i(4*(j-1)+i) = randn *(1/sqrt(2));
w_q(4*(j-1)+i) = randn *(1/sqrt(2));
x_hat(4*(j-1)+i) = x(4*(j-1)+i)+w_i(4*(j-1)+i);
y_hat(4*(j-1)+i) = y(4*(j-1)+i)+w_q(4*(j-1)+i);
end
%correlator
for i = 1:4
z_i(i) = x_hat(4*(j-1)+i)*s(i);
z_q(i) = y_hat(4*(j-1)+i)*s(i);
end
i_hat(j) = z_i(1)+z_i(2)+z_i(3)+z_i(4);
q_hat(j) = z_q(1)+z_q(2)+z_q(3)+z_q(4);

%qpsk decoder
theta(j) = atan2(q_hat(j),i_hat(j));

if -(pi/4) <= theta(j) && theta(j) < (pi/4);
d_hat1(j) = 0;
d_hat2(j) = 0;
elseif (pi/4) <= theta(j) && theta(j) < (3*pi/4);
d_hat1(j) = 1;
d_hat2(j) = 1;
elseif -(3*pi/4) <= theta(j) && theta(j) < (pi/4);
d_hat1(j) = 0;
d_hat2(j) = 1;
else
d_hat1(j) = 1;
d_hat2(j) = 0;

end
end

%probability of error
C1 = xor(d1,d_hat1);% this creates a vector where a 1 is given
C2 = xor(d2,d_hat2);% when they differ or an error has occured
Pb_simulated(k) = (sum(C1)+sum(C2))*(1/N);%overall error for each EB/NO
Pb_theoretical(k) = qfunc(sqrt(2*EB_NO));
%symbol error
Symbol_error(k) = sum(or(C1,C2));%Symbol error occurs if error in
%C1 or C2
%plots
xlim([0 7])
ylim([10^(-5) 1])
semilogy(Pb_simulated, 'red')
hold on
semilogy(Pb_theoretical,'blue')
grid on
title('QPSK Modulation');
xlabel('EB/No(dB)', 'fontsize', 12');
ylabel('Probability of Error', 'fontsize', 12');
hleg1 = legend('Pb simulated','Pb theoretical');
set(hleg1,'fontSize',12);

end

][/CODE]

Hi Joserse,

I've not examined in detail the code (the lack of indentation make it a bit more difficult to identify loops and nesting), but these are some hints:

= Move out the loops calculations that wuold be repeated at each iteration.
For instance, sqrt(EB_NO*2) is used a lot of times inside loops, requiring the calculation of a square root each time.
Instead of that, assign that value to a variable (the good place is after the line EB_NO = 10.^(k/10); % linear scale) and use that variable inside the loop instead of sqrt(EB_NO*2).

= Matlab is more efficient when using arrays (vectors or matrices) instead of loops. That wuold require some change in the structure of the program.

= Some advantage can be achieved using complex variables instead of separate I and Q components

By the way, I saw that when you have

EB_NO = 10.^(k/10); % linear scale

you should have

EB_NO = 10.^(Eb_No(k)/10); % linear scale

Regards

Z

Hi Joserse,

I've not examined in detail the code (the lack of indentation make it a bit more difficult to identify loops and nesting), but these are some hints:

= Move out the loops calculations that wuold be repeated at each iteration.
For instance, sqrt(EB_NO*2) is used a lot of times inside loops, requiring the calculation of a square root each time.
Instead of that, assign that value to a variable (the good place is after the line EB_NO = 10.^(k/10); % linear scale) and use that variable inside the loop instead of sqrt(EB_NO*2).

= Matlab is more efficient when using arrays (vectors or matrices) instead of loops. That wuold require some change in the structure of the program.

= Some advantage can be achieved using complex variables instead of separate I and Q components

By the way, I saw that when you have

EB_NO = 10.^(k/10); % linear scale

you should have

EB_NO = 10.^(Eb_No(k)/10); % linear scale

Regards

Z

could you elaborate on using complex variables instead of I Q components?
I plan to implement more matrices soon, i figured that is what is killing the time.

could you elaborate on using complex variables instead of I Q components?
I plan to implement more matrices soon, i figured that is what is killing the time.

Start with the first hint of my previous post. It is the easiest change, and maybe fairly effective.
Measure times using "tic" and "toc". (Use matlab help.)

Use complex variables representing complex symbols and signals, equivalent to I+j*Q and x+j*y , as usual.
Avoid use of "i" and "j" for variable names. In Matlab they are used for imaginary unit.

Regards

Z

joserse46

### joserse46

Points: 2
So I have improved most of this code except I am stuck on the correlation block
I want the rows an N by 4 matrix to be the product(element by element) of another N by 4 matrix and a matrix s = [ .5 .5 .5. .5]

for example A = [ 2 4 6 8; 8 6 4 2; 10 12 14 16; 20 10 8 2]
s = [.5 .5 .5 .5]
in this case N= 4
so i want each row of A to be the element by element product of s
Matrix I want = [1 2 3 4; 4 3 2 1; 5 6 7 8; 10 5 4 1]

Here is the code i have ( note that i want the option to change the size of N)

z_i(1:N, = x_hat(1:N,.*s;
z_q(1:N, = y_hat(1:N,.*s;

thanks in advance for any suggestions

Hi joserse46,

I want the rows an N by 4 matrix to be the product(element by element) of another N by 4 matrix and a matrix s = [ .5 .5 .5. .5]

for example A = [ 2 4 6 8; 8 6 4 2; 10 12 14 16; 20 10 8 2]
s = [.5 .5 .5 .5]
in this case N= 4
so i want each row of A to be the element by element product of s
Matrix I want = [1 2 3 4; 4 3 2 1; 5 6 7 8; 10 5 4 1]

What you need is this:

B = repmat(s,N,1) .* A;

Regards

Z

joserse46

Points: 2