Simulate LDPC and QAM in MATLAB - matlab

I want to study LDPC and I want to simulate a program. This program will use LDPC on a randomly generated 1x32000 size binary array, then it will modulate with 16-QAM, add noise for SNR=20dB, do demodulation for 16-QAM and finally decode it using LDPC. When I run the program and check it for BER, I get error around %90 which is definitely not correct. Can you help me?
clear all
clc
M = 16;
SNR = 20;
ldpcEncoder = comm.LDPCEncoder(dvbs2ldpc(1/2));
ldpcDecoder = comm.LDPCDecoder(dvbs2ldpc(1/2));
data = randi([0 1],32400,1);
newData = ldpcEncoder(data);
a = qammod(newData,M,'InputType','bit');
b = awgn(a,SNR,'measured');
c = qamdemod(b,M,'OutputType','bit');
result = ldpcDecoder(c);
error = biterr(data,result)/length(data)

The LDPC decoder object expects an input with "soft" bits (log-likelihood ratio), whereas you are feeding it with "hard", unipolar bits. So, replace the line
c = qamdemod(b,M,'OutputType','bit');
by
c = qamdemod(b,M,'OutputType','llr');

Related

probabilistic neural network Error In Matlab

Hello I have biometric data such as record.mat. In record variable P denotes training features and T denotes target data. I am using new newpnn command for classification and I am taking this error:
Error using network/subsasgn>network_subsasgn (line 551)
net.IW{1,1} must be a 212-by-212 matrix.
Here is my dataset and here are codes.
clear all
load record.mat ;
P = record.P;
Tc = record.T;
T = ind2vec(Tc)
net = newpnn(P,T);
Y = sim(net,P);
Yc = vec2ind(Y);
How can I overcome this problem? Thanks
This error related to input matrix dimensions and data type.
clear
load record.mat;
P = double(record.P)'; %add ' and convert single to double will solve the issue
Tc = record.T;
T = ind2vec(Tc);
net = newpnn(P,T);
Y = sim(net,P);
Yc = vec2ind(Y);
I hope this help

First non demo example for Gaussian process using GPML (Matlab)?

After having some basics understanding of GPML toolbox , I written my first code using these tools. I have a data matrix namely data consist of two array values of total size 1000. I want to use this matrix to estimate the GP value using GPML toolbox. I have written my code as follows :
x = data(1:200,1); %training inputs
Y = data(1:201,2); %, training targets
Ys = data(201:400,2);
Xs = data(201:400,1); %possibly test cases
covfunc = {#covSE, 3};
ell = 1/4; sf = 1;
hyp.cov = log([ell; sf]);
likfunc = #likGauss;
sn = 0.1;
hyp.lik = log(sn);
[ymu ys2 fmu fs2] = gp(hyp, #infExact, [], covfunc, likfunc,X,Y,Xs,Ys);
plot(Xs, fmu);
But when I am running this code getting error 'After having some basics understanding of GPML toolbox , I written my first code using these tools. I have a data matrix namely data consist of two array values of total size 1000. I want to use this matrix to estimate the GP value using GPML toolbox. I have written my code as follows :
x = data(1:200,1); %training inputs
Y = data(1:201,2); %, training targets
Ys = data(201:400,2);
Xs = data(201:400,1); %possibly test cases
covfunc = {#covSE, 3};
ell = 1/4; sf = 1;
hyp.cov = log([ell; sf]);
likfunc = #likGauss;
sn = 0.1;
hyp.lik = log(sn);
[ymu ys2 fmu fs2] = gp(hyp, #infExact, [], covfunc, likfunc,X,Y,Xs,Ys);
plot(Xs, fmu);
But when I am running this code getting:
Error using covMaha (line 58) Parameter mode is either 'eye', 'iso',
'ard', 'proj', 'fact', or 'vlen'
Please if possible help me to figure out where I am making mistake ?
I know this is way late, but I just ran into this myself. The way to fix it is to change
covfunc = {#covSE, 3};
to something like
covfunc = {#covSE, 'iso'};
It doesn't have to be 'iso', it can be any of the options listed in the error message. Just make sure your hyperparameters are set correctly for the specific mode you choose. This is detailed more in the covMaha.m file in GPML.

how to generate 64 or 128 qam in matlab

How to generate 64 or 128 QAM signal in MATLAB without making use of signal processing/Communication tool box. Is there any general method for creating higher order qams?
Let's say you want to generate a QAM for M=2^b. Then you need constellation points that form a lattice of M_I = 2^b_I by M_Q = 2^b_Q points where M = M_I*M_Q and therefore b_I+b_Q==b. Distributing evenly, we get b_I = floor(b/2); and b_Q = ceil(b/2);.
This established, you set up the lattice by forming 1-D grids for real and imaginary part and then connect them to a 2-D lattice. Like this:
b = 6;
M = 2^b; % b = 6: 64-QAM, b = 7: 128-QAM, etc.
b_I = floor(b/2);
M_I = 2^b_I;
b_Q = ceil(b/2);
M_Q = 2^b_Q;
x_I = -(M_I-1)/2:(M_I-1)/2;
x_Q = -(M_Q-1)/2:(M_Q-1)/2;
x_IQ = repmat(x_I,[M_Q,1]) + 1i*repmat(x_Q.',[1,M_I]);
x_IQ = x_IQ / sqrt((M_I^2+M_Q^2-2)/12);
Note that in R2016b, the second-to last line can be simplified to x_IQ = x_I + 1i*x_Q.'; Moreover, the last line ensures that your constellation to has average energy per symbol of 1 (note: for even b, the normalization can be simplified to sqrt((M-1)/6)).
Now, x_IQ is an array that contains all possible constellation points.
To draw random symbols, use s = x_IQ(randi(M,NSymbols,1));
Note that for odd b this script generates a rectangular QAM (e.g., for 128-QAM it is a 16x8 constellation). There are other ways to do so by placing constellation points more symmetrical. There is no unique way of doing that though so if you need one you have to specify which. Though in practice one usually uses QAM with even b.
I found the answer! If it is 64,256 or square of any number, then it can be easily generated as below.
% matlab code to generate 64 qam
m = 0; n = 0;
for k = -7:2:7
m = m+1;
for l = -7:2:7
n = n+1;
x(m,n) = k+j*l;
end
n = 0;
end

Fourier Transform Of male and female voice

I'm doing fourier transform using matlab R2014a, first I have read two audio files of femal and male, then I initialized the magnitude and phase for each. A Task in my report requires to Mix female speech amplitude with phase spectrum of the other signal-male phase-, or viceversa, So I wrote a code and I keep getting this error:
Error using *
Inner matrix dimensions must agree.
out1 = Mag_Male*exp(1i*Phase_Fem);
And even using.*
Error in Untitled9 (line 183)
out1 = Mag_Male.*exp(1i*Phase_Fem);
or .* in both operators
The full error
>> Untitled9
Error using .*
Matrix dimensions must agree.
Error in Untitled9 (line 183)
out1 = Mag_Male.*(exp(1i.*Phase_Fem));
Output of m and f size using size function
code:
maleAudio_row = size(m);
femaleAudio_row = size(f);
display(maleAudio_row);
display(femaleAudio_row);
Output:
maleAudio_row =
119855 2
femaleAudio_row =
119070 1
although my other colleagues worked fine with them :(
This is my Code:
Fs = 11025;
Ts = 1/Fs;
t = 0:Ts:0.1;
[m, Fs]=audioread('hamid1.wav');
[f, Fs]=audioread('myvoice.wav');
player = audioplayer(m,Fs);
player2 = audioplayer(f,Fs);
%play(player2);
%---- Frquency Domain Sampling-----%
Fem = fft(f);
Phase_Fem = angle(Fem);
Mag_Fem = abs(Fem);
%-----------------------------------%
Male = fft(m);
Mag_Male = abs(Male);
Phase_Male = angle(Male);
%-----------------------------------%
out1 = Mag_Male*exp(1i*Phase_Fem); % this step for putting female phase on male mag.
out2 = ifft(out1); % this step is convert the previus step to time domain so i can
%play the audio
Nx = length(out2);
F0 = 1/(Ts*Nx2);
result = audioplayer(out2);
play(result);
Your 'hamid1.wav' is two-channel wav file whereas 'myvoice.wav' is one-channel wav. As mentioned in Matlab manual (http://nl.mathworks.com/help/matlab/ref/audioread.html)
Audio data in the file, returned as an m-by-n matrix, where m is the number of audio samples read and n is the number of audio channels in the file.
Just convert m to one channel as m = 0.5*(m(:,1)+m(:,2)), adjust other dimension and use .* product (as people suggested in the comments).
clear all;
m = randn(1000,2); %dummy signal
f = randn(999,1); %dummy signal
N = min(size(m,1),size(f,1));
Male = fft(0.5*(m(1:N,1)+m(1:N,2)));
Fem = fft(f(1:N,1));
Mag_Male = abs(Male);
Phase_Male = angle(Male);
Phase_Fem = angle(Fem);
Mag_Fem = abs(Fem);
out1 = Mag_Male.*exp(1i*Phase_Fem);
If you use a * it will try and do matrix multiplication. What you probably want to use is an element by element operator, which is a . before the *. This will multiply the first element in the vector with the first element in the other vector, the second with the second, etc. etc.
out1 = Mag_Male.*exp(1i*Phase_Fem);
This assumes that the result from your FFT is the same length. This will be the case if the original samples are the same length.

double to int16 (generation or conversion?)

fsamp = 2;
deltaf = fsamp/nfft; % FFT resolution
Nfreqtimestwo = 128; % Used below
Nsines = Nfreqtimestwo/2 - 1; % Number of sine waves
fmult = [1:Nsines]; % multiplicative factor
freq_fund = fsamp/Nfreqtimestwo;
freq_sines = freq_fund.*fmult;
omega = 2*pi*freq_sines;
r = int16(0);
for(ii=1:Nsines)
r = r + cos((omega(ii)/fsamp)*(0:messageLen-1));
end
This is the code I am currently using to create my input signal. However, the end result of r is a 32,768 array of doubles. Now I would like to do the best approximation of that using int16. However, I would like to note that amplitude doesn't really matter. For example, my best approach so far I think has been:
fsamp = 2;
deltaf = fsamp/nfft; % FFT resolution
Nfreqtimestwo = 128; % Used below
Nsines = Nfreqtimestwo/2 - 1; % Number of sine waves
fmult = [1:Nsines]; % multiplicative factor
freq_fund = fsamp/Nfreqtimestwo;
freq_sines = freq_fund.*fmult;
omega = 2*pi*freq_sines;
r = int16(0);
for(ii=1:Nsines)
r = r + int16(8192*cos((omega(ii)/fsamp)*(0:messageLen-1)));
end
Are there any better ways to approach this?
EDIT
The reason I want to convert the doubles to ints is because this list is being used in an embedded system and eventually going to a 16-bit DAC... no doubles allowed
int16(vector) converts vector from double to int16 and this is the preferred way. The alternate way of doing it is to define all your constants as int16s in which case, MATLAB will give you the result as an int16. However, this is cumbersome, so stick with what you have (unless if you absolutely have to do it this way).
Also, unrelated to your actual question, you can ditch the loop by using cumsum. I'll leave that for you to try out :)