Integral within exponential within integral - matlab

I am trying to numerically integrate a few different expressions, but they all have an integral within an exponential, surrounded by another integral, i.e.
I can't seem to get this to solve using the code below:
syms s p t
W = 3.18*10^(-22);
b = 10^(-23);
X = 300;
L = 0.374;
intlim = 0.589;
myfuncirc = #(s,p,t) (-W).*sqrt((L.^2)-(s.^2)).*(((-p.*cos(t))+sqrt(1-((p.^2).*((sin(t)).^2)))-sqrt(L.^2-s.^2)).^(-2));
s_min = 0;
s_max = L;
t_min = 0;
t_max = pi;
integral(#(p)(p.*exp(-(integral2(#(s,t) myfuncirc(s,t,p),s_min,s_max,t_min,t_max))/(b.*X))),0,intlim,'Arrayvalued',true)
I get the error message shown below, but I'm expecting a number between 0 and 1:
Warning: Infinite or Not-a-Number value encountered.
In funfun\private\integralCalc>iterateArrayValued at 267
In funfun\private\integralCalc>vadapt at 130
In funfun\private\integralCalc at 75
In integral at 88
I'm also attempting a similar integration in the following form, but also not getting expected answers:
pmax = y;
pmin = 0;
ymax = 1;
ymin = #(x) x;
xmax = 1;
xmin = 0;
integral3(#(x,y,p) (exp(-(integral(#(s)myfun(s,p),0,lam,'ArrayValued',true)./(k.*T)))),xmin,xmax,ymin,ymax,pmin,pmax,'Method','iterated')
Warning: Infinite or Not-a-Number value encountered. > In funfun\private\integralCalc>iterateScalarValued at 349 In funfun\private\integralCalc>vadapt at 132 In funfun\private\integralCalc at 75 In funfun\private\integral2Calc>#(xi,y1i,y2i)integralCalc(#(y)fun(xiones(size(y)),y),y1i,y2i,opstruct.integralOptions) at 17 In funfun\private\integral2Calc>#(x)arrayfun(#(xi,y1i,y2i)integralCalc(#(y)fun(xiones(size(y)),y),y1i,y2i,opstruct.integralOptions),x,ymin(x),ymax(x)) at 17 In funfun\private\integralCalc>iterateScalarValued at 314 In funfun\private\integralCalc>vadapt at 132 In funfun\private\integralCalc at 75 In funfun\private\integral2Calc>integral2i at 20 In funfun\private\integral2Calc at 7 In integral3>innerintegral at 137 In funfun\private\integralCalc>iterateScalarValued at 314 In funfun\private\integralCalc>vadapt at 132 In funfun\private\integralCalc at 75 In integral3 at 121 Warning: The integration was unsuccessful. > In integral3 at 125

Problem 1 is you define
myfuncirc = #(s,p,t) ...
But when it is called it is called as
myfuncirc(s,t,p)
The arguments are not in the same order. You should change the definition of myfuncirc to
myfuncirc = #(s, t, p) ...
It's harder to tell for the second one because what you posted doesn't give the results you printed, it errors - several values are undefined such as myfun and k. However, I think the problem is that pmax is not defined as a function handle, but as a value - whatever is in y at the time pmax is assigned to. I suspect you want
pmax = #(x,y) y;

Related

What is the meaning of the following matlab notation?

I want to write this matlab code in python but I do not know what LEV(1:n+1:n^2) = 0; or LEV(i,:) means. Can anyone explain me what are this notation? Thank you!
function A = ILU_p(A,p)
n = length(A);
LEV = inf(n);
LEV(find(A)) = 0;
LEV(1:n+1:n^2) = 0;
for i = 2:n
for k = 1:i-1
if LEV(i,k) > p
continue
end
A(i,k) = A(i,k) / A(k,k);
A(i,k+1:n) = A(i,k+1:n) - A(i,k) * A(k,k+1:n);
LEV(i,k+1:n) = min([LEV(i,k+1:n); LEV(i,k) + LEV(k,k+1:n) + 1]);
end
A(i,find(LEV(i,:)>p)) = 0;
end
The below sets up a vector of values to be used in an index. If n=10 then the below would yield a row vector of [1 12 23 34 45 56 67 78 89 100]
1:n+1:n^2
Since LEV is set up as an nxn matrix and the above row vector picks up the diagonal elements, i.e., LEV(1) = LEV(1,1), LEV(12) = LEV(2,2), etc.
LEV(i,:) is MATLAB's shorthand for referencing all columns in row i.

Errors when trying to adding points to a plot3

I'm trying to dynamically add information to a 3D plot:
A = [ -8/3 0 0; 0 -10 10; 0 28 -1 ];
y = [35 -10 -7]';
h = 0.01;
p = plot3(y(1),y(2),y(3),'.','EraseMode','none','MarkerSize',2);
axis([0 50 -25 25 -25 25])
hold on
while 1
A(1,3) = y(2);
A(3,1) = -y(2);
ydot = A*y;
y = y + h*ydot;
set(p,'XData',y(1),'YData',y(2),'ZData',y(3))
drawnow
end
I get the following errors:
Warning: The EraseMode property is no longer supported and will error
in a future release.
In strange_attractor (line 4) Warning: The EraseMode property is no longer supported and will error in a future release.
In strange_attractor (line 4) Error using matlab.graphics.chart.primitive.Line/set Invalid or deleted object.
Error in strange_attractor (line 12)
set(p,'XData',y(1),'YData',y(2),'ZData',y(3))
I understand that I'm using the outdated syntax for dynamically updating the plot that is no longer supported. How do I make it work?
Note that I don't want to call plot3 inside the loop, because it makes the graphing slow and consumes a lot of memory. I hope to call plot3 once and just add new points to the existing plot inside the loop. Can it be done in the new version?
Matlab version: R2018a
In your comment above, when you say "This does not work", what do you mean? A direct modification of your code according to the given link to the documentation works as expected:
A = [ -8/3 0 0; 0 -10 10; 0 28 -1 ];
y = [35 -10 -7]';
h = 0.01;
p = animatedline(y(1),y(2),y(3),'Marker','.','MarkerSize',2);
axis([0 50 -25 25 -25 25])
hold on
while 1
A(1,3) = y(2);
A(3,1) = -y(2);
ydot = A*y;
y = y + h*ydot;
addpoints(p,y(1),y(2),y(3))
drawnow
end

DVB-S2: LDPC Short Format

Scope
Matlab does include a function, named dvbs2ldpc, to construct a parity check matrix to be used at LDPC encoding stage in DVB-S2 standard.
This standard counts with two different transmission modes (SHORT and NORMAL), depending on the size of the resulting codeword. However dvbs2ldpc function only applies for NORMAL one. Thus I am trying to build up a function to be used in SHORT transmission mode.
Code description
You may find below all the related code in functions dvbs2ldpcShort.m, where I am to construct a parity check matrix for SHORT transmission mode, and LDPC.m, where I perform some BER simulations to check out the results.
You may see that dvbs2ldpcShort resembles quite a lot to dvbs2ldpc, which appears in Matlab Communication Toolbox. The two only differences that I included were changing the length of the codeword and the accumulator bits of the parity check matrix that it may correspond (please see annexes B and C from this link for further information).
Code
dvbs2ldpcShort.m
function H = dvbs2ldpcShort(R)
if R = 1/2
Rreal = 4/9; % Actual rate (as k = 7200 and N = 16200)
end
lenCodeWord = 16200; % Length of codeword for DVB-S.2
NB = 360; % Node indices parameter for DVB-S.2.
numInfoBits = lenCodeWord * Rreal;
numParityBits = lenCodeWord - numInfoBits;
[ct1, ct2] = getchecknodetable(R);
ck1 = nodeindices(ct1, numParityBits, NB);
ck2 = nodeindices(ct2, numParityBits, NB);
d = [size(ck1,2) size(ck1,1) size(ck2,2) size(ck2,1) numParityBits-1 2 1 1];
r = [ck1(:); ck2(:); 0; reshape(ones(2,1)*(1:numParityBits-1),[],1)];
S = zeros(length(r),1);
numGroup = length(d)/2;
n = 0;
ncol = 1;
for i = 1:numGroup
p = d(2*i-1)*d(2*i);
S(n+1:n+p) = reshape(ones(d(2*i),1)*(ncol:ncol+d(2*i-1)-1),p,1);
ncol = ncol + d(2*i-1);
n = n + p;
end
% Parity-check matrix (sparse) for DVB-S.2
outputFormat = 'sparse'; % Sparse matrix by default
if nargin == 2
if ~strcmp(varargin{1}, 'sparse') && ~strcmp(varargin{1}, 'indices')
error(message('comm:dvbs2ldpc:InvalidOutputFormat'));
end
outputFormat = varargin{1};
end
if strcmp(outputFormat, 'sparse')
H = logical(sparse(double(r+1), S, 1));
else
H = [double(r+1), double(S)];
end
%--------------------------------------------------------------------------
function ck = nodeindices(ct, M, NB)
% ct: check node table (single group)
% M: number of parity bits
% NB: block size
[N, D] = size(ct);
q = (M/NB);
b = (1:NB);
bq = (b-1).'*q;
ck = zeros(D, NB*N);
for r=1:N
ck(:, NB*(r-1)+1:NB*r) = mod(addcr(bq, ct(r,:)), M)';
end
%--------------------------------------------------------------------------
function A = addcr(c, r)
M = length(c);
N = length(r);
A = zeros(M, N);
for m = 1:M
A(m, :) = r + c(m);
end
%--------------------------------------------------------------------------
function [ct1, ct2] = getchecknodetable(R)
switch R
case 1/2 % There are all cases, but here I only include the R=1/2 one
ct1 = [20 712 2386 6354 4061 1062 5045 5158
21 2543 5748 4822 2348 3089 6328 5876
22 926 5701 269 3693 2438 3190 3507
23 2802 4520 3577 5324 1091 4667 4449
24 5140 2003 1263 4742 6497 1185 6202];
ct2 = [0 4046 6934
1 2855 66
2 6694 212
3 3439 1158
4 3850 4422
5 5924 290
6 1467 4049
7 7820 2242
8 4606 3080
9 4633 7877
10 3884 6868
11 8935 4996
12 3028 764
13 5988 1057
14 7411 3450];
end
LDPC.m
r = 1/2;
k = 7200;
ldpcEnc = comm.LDPCEncoder(dvbs2ldpcShort(r));
psk4Mod = comm.PSKModulator(4, 'BitInput',true);
EsNo = 0.2 : 0.1 : 1.2;
BER = zeros(size(EsNo));
for k = 1 : 1 : length(EsNo)
awgnChan = comm.AWGNChannel(...
'NoiseMethod','Signal to noise ratio (Es/No)','EsNo',EsNo(k));
psk4Demod = comm.PSKDemodulator(4, 'BitOutput',true,...
'DecisionMethod','Approximate log-likelihood ratio', ...
'Variance', 1/(2*10^(awgnChan.EsNo/10)));
ldpcDec = comm.LDPCDecoder(dvbs2ldpcShort(r));
ber = comm.ErrorRate;
for counter = 1:100
data = logical(randi([0 1], k, 1));
encodedData = ldpcEnc(data);
modSignal = psk4Mod(encodedData);
receivedSignal = awgnChan(modSignal);
demodSignal = psk4Demod(receivedSignal);
receivedBits = ldpcDec(demodSignal);
errorStats = ber(data, receivedBits);
end
BER(k) = errorStats(1);
end
Question
The corresponding BER curve does not resemble at all to how it is for NORMAL transmission mode (these represent the BER as function of SNR. and mine are function of EbNo, but the difference shouldn't be really big at all). Instead, results seem to be unexpectedly good. Can you see anything wrong with my code?
What could be wrong in my code?
Many thanks in advance, and may you have a nice weekend!
Thanks for the note on LDPC code identifier and Effective LDPC rate.
Your example-performance should be better, because you use more redundancy: 5/9 (0.56) of code word whereas in the MATLAB example they use (1 - 2/3) = 1/3 (0.33) of code word as redundancy.
I would like to add a note also: In the ETSI standard they also use a parameter q, that is equal to q = (M/NB); (M -- num of parity bits, NB = 360) when the n_ldpc = 64800, but if n_ldpc = 16200 the q should be used according a table in the ETSI standard.
Let's look at my solution: dvbs2ldpc_custom

Solving a system of 5 nonlinear equations in Matlab

I'm having difficulty using the fsolve function to solve a set of 5 equations in Matlab.
Here are the 5 equations:
y = a + d + e
y + x = c + d + 2e
2x = 4a + 2b + 2c
k1 = (d * b^3 / (a * c) ) * ((P/Pref)/(a+b+c+d+e))^2
k2 = be/(dc)
y,x,k1,k2,P,Pref are all parameters that I set, but would like to leave them in the function so that I can change them quickly in my code to find new answers. a,b,c,d,e are the variables that I'd like to solve for (they are compositions of a reaction equilibrium equation)
I tried to hard code the parameters in the function, but that didn't work. I'm just not sure what to do. Every thing I change creates a new error. The most common is that the data type has to be "double".
Edit: adding code
first the function:
function F = myfun(Q,I)
a = Q(1);
b = Q(2);
c = Q(3);
d = Q(4);
e = Q(5);
x = I(1);
y = I(2);
k1 = I(3);
k2 = I(4);
P = I(5);
Pref = I(6);
F(1) = a + d + e - y;
F(2) = c + d + 2*e - y - x;
F(3) = 4*a + 2*b + 2*c - 2*x;
F(4) = ((d * b^3)/(a*c))*((P/Pref)/(a+b+c+d+e))^2 - k1;
F(5) = (b*e)/(c*d);
next is the program:
%Q = [a,b,c,d,e]
%I = [x,y,k1,k2,P,Pref]
%The values for the inputs will be changed to vary the output
%Inputs:
x=5;
y=1;
k1=5;
Pref=1;
P=1;
k2=-0.01;
syms K
k1 = solve(log10(k1) - k1);
syms L
k2 = solve(log10(k2) - k2);
x = double(x);
y = double(y);
Pref = double(Pref);
P = double(P);
k1 = double(k1);
k2 = double(k2);
%Solving:
I = [x,y,k1,k2,P,Pref];
q = [0,0,0,0,0]; %initial guess
Q = fsolve(#myfun,[q,I])
when I run this, these errors comes up:
Error using myfun (line 7)
Not enough input arguments.
Error in fsolve (line 218)
fuser = feval(funfcn{3},x,varargin{:});
Error in Coal (line 27)
Q = fsolve(#myfun,[q,I])
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot continue.
Edit 2: changed the fsolve line, but still got errors:
Error using trustnleqn (line 28)
Objective function is returning undefined values at initial point. FSOLVE cannot continue.
Error in fsolve (line 376)
[x,FVAL,JACOB,EXITFLAG,OUTPUT,msgData]=...
Error in Coal (line 27)
fsolve(#(q) myfun(q,I),q)
Edit3: changed a couple parameters and the initial guess, I am now getting an answer, but it also comes up with this:
Solver stopped prematurely.
fsolve stopped because it exceeded the function evaluation limit,
options.MaxFunEvals = 500 (the default value).
ans =
0.0000 2.2174 3.7473 1.4401 3.8845
how can I get it to not stop prematurely?
Re: how can I get it to not stop prematurely?
Pass non-default options in your call to fsolve.
Refer to the signature, fsolve(myfun,q,options) here,
http://www.mathworks.com/help/optim/ug/fsolve.html
And read about creating the options using optimoptions here,
http://www.mathworks.com/help/optim/ug/optimoptions.html
You should be able to get it to "not stop prematurely" by increasing the values of convergence criteria such as TolFun and TolX.
However, it's advisable to read up on the underlying algorithms you're relying upon to perform this numerical solution here,
(EDIT: I tried to fix non-linky links, but I'm not allowed to provide more than two ... Boo) www.mathworks.com/help/optim/ug/fsolve.html#moreabout
The error you received simply indicates that after 500 function evaluations the algorithm has not yet converged on an acceptable solution conforming to the default solver options. Just increasing MaxFunEvals may allow the algorithm extra iterations needed to converge within default tolerances. For example,
options = optimoptions('MaxFunEvals',1000); % try something bigger than 500
fsolve(#(q) myfun(q,I),q,options);

MATLAB: bnb20 (Branch and Bound Method) Optimization

I've got an error when running the following code in matlab. I'm trying to use bnb20.
function [errmsg,Z,X,t,c,fail] = optimize_bnb_test
P = [34336 701 227 2860 32841 463 616 39769 331 1224 1515 472583
1021 969 9260 39380 4986 6567 3386 16926 4841 100635];
C = 31300;
A = [-C 0 0; 0 -C 0; 0 0 -C;];
B =[-P(1); -P(2); -P(3);];
function y = linear_objective(n)
y = [1, 1, 1] * n;
end
lb = [1; 1; 1;];
ub = [16; 16; 16; ];
[errmsg,Z,X,t,c,fail] = BNB20('linear_objective',lb,[],lb,ub,A,B,
[],[],[],[],[],[]);
end
I got an error message like 'fun cause error.'
I don't know why.
I'm just learning matlab.
Update:
function [errmsg,Z,X,t,c,fail] = optimize_bnb_test
P = [34336 701 227 2860 32841 463 616 39769 331 1224 1515 472583 1021 969 9260 39380 4986 6567 3386 16926 4841 100635];
C = 31300;
A = [-C 0 0; 0 -C 0; 0 0 -C;];
B =[-P(1); -P(2); -P(3);];
lb = [1; 1; 1;];
ub = [16; 16; 16;];
fun = #(x)x(1)+x(2)+x(3);
[errmsg,Z,X,t,c,fail] = BNB20('fun',lb,[],lb,ub,A,B,[],[],[],[],[]);
end
Error message is changed:
I don't know what to do now..
The error happens the following call:
eval(['z=',fun,'(x0,varargin{:});'],'errmsg=''fun caused error.''; evalreturn=1;');
My guess is that varargin{:} is giving an error to your function. It looks like you don't use it, it is empty. I would try either of:
1.- delete the last ,[] from the call to bnb20 as the 13th input argument is optional, instead of giving an empty array ([]), just don't give anything.
2.- When you define your function to evaluate, define it with extra input arguments but dump then (or just do not use them).
function y = linear_objective(n,varargin)
y = [1, 1, 1] * n;
end