MATLAB: bnb20 (Branch and Bound Method) Optimization - matlab

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

Related

How to solution of linear-time varying system correctly

I tried the given below to get the solution of the linear-time varying equation using for-loop, but the solution is not correct as I want to. I don’t know where I am getting wrong while implementing this.
r0 = 0.05;
L = 0.1;
d = 0.005;
w0 = 1.5;
Ts=10;
t=[0:Ts:800];
x0=[0 0 1]';
y0=1;
x_value=[];
for k=1:(length(t)) % Number of Iterations
x_value=[x_value x0];
g(k) = (2*r0*L*sinh((d*(k))/2))./(d*cosh((d*(k))/2)+L*sinh((d*(k))/2));
A0 = [ -0.5*g(k) -w0 0 ;
w0 -g(k)*0.5 0 ;
0 0 -g(k)];
B0 =[0; 0; -g(k)];
Q=integral(#(u) expm(A0*((k+1)*Ts)-u)*B0,(k*Ts),((k+1)*Ts), 'ArrayValued', true);
x0=expm(A0*Ts)*x0+Q;
end
plot(t,x_value,'r-','linewidth',1);

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.

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

Integral within exponential within integral

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;

Don't know how to Correct : "In an assignment A(I) = B, the number of elements in B and I must be the same."

I saw other topics about this error but I couldn't figure it out. The error "In an assignment A(I) = B, the number of elements in B and I must be the same" occurs at the second for loop. How can I change my code to avoid this error?
h1 = [70 31.859 15 5.774 3.199 2.15 1.626];
h2 = [31.859 15 5.774 3.199 2.15 1.626 1.415];
b = [1253 1253 1253 1253 1253 1253 1253];
R = [455.4 425.6 377.6 374.9 371.3 273.7 268.3];
r = [0.5448714286 0.5291754292 0.6150666667 0.4459646692 0.3279149734 0.2437209302 0.1297662977];
k = [200 200 200 200 200 200 200];
s = sqrt(r/(1-r));
v2 = [20 0 0 0 0 0 0];
v1 = [0 0 0 0 0 0 0];
Ch1 = [0 0 0 0 0 0 0];
Ch2 = [0 0 0 0 0 0 0];
C = [100 100 100 100 100 100 100];
F = b .* k .* sqrt(R-(h1-h2))- R.*sin((acos((R-((h1-h2)./2))./R))) .* (pi/2) .* (1./sqrt(r./(1-r))) .* (atan(sqrt(r./(1-r))))-(pi/4) - (1./(sqrt(r./(1-r)) .* sqrt(h2./R))).* log((h2+R.*((sqrt(h1./R).*tan(1/2 .* atan(sqrt(r./(1-r)).*sqrt(h1./r).*log(1./(1-k))))).^2).*sqrt(1-r))./h2)
M = -R.*R.*(k./2).*(.2*(sqrt(h2./R)*tan(0.5*(atan(s)))-(pi/8).*sqrt(h2./R).*log(1./1-r)))-(acos((R-((h1-h2)./2))./R))
for i=1:6
v1(i) = ((v2(i)*h2)/h1);
v2(i+1) = v1(i);
end
vr = ((v1.*h1)./h2)./(((tan(0.5.*((atan(s)))-(pi/8).*sqrt(h2./R).*log(1./(1-r)))).^(2))+1)
%--------------------------------------------------------------------------
% Calculating E
w = (((2.*R.*h2).^(3/2))./(300.*(b.^2)))
if (w <= (3*10^-4));
E = ((0.0821.*((log(w))^2))+(1.25.*log(w))+4.89)
end
if ((3*10^-4)<= w <= (2.27*10^-3));
E = ((0.0172.*((log(w)).^2))+(0.175.*log(w))+0.438)
end
if (w > (2.27*10^-3))
E = 0.01
end
%--------------------------------------------------------------------------
% Calculating Ch:
y = ((((2.*R).^(0.5)).*((h2).^(1.5)))./(b.^2))
N1 = (0.5-(1/pi).*atan((log(y)+8.1938)./(1.1044)))
N = ((h2./h1).*N1)
for i=1:1;7
Ch2(i) = (h2.*((N.*((Ch1(i)./h2)-(C./h2)))+(C/h2)))
Ch1(i+1) = Ch2(i)
end
DeltaStrain = (E.*((Ch2./h2)-(Ch1./h1)))
if DeltaStrain > 0;
Stepp = ((2/pi).*(sqrt(DeltaStrain))))
Control = 2;
else
Stepp = ((2/pi).*(sqrt(-DeltaStrain))
Control = 0;
end
In the line
Ch2(i) = (h2.*((N.*((Ch1(i)./h2)-(C./h2)))+(C/h2)))
h2 is a vector, and Ch2(i) is a scalar. You cannot assign the value of a vector to a scalar. I suspect you want to replace the entire for loop. Right now you have
for i=1:1;7
Ch2(i) = (h2.*((N.*((Ch1(i)./h2)-(C./h2)))+(C/h2)))
Ch1(i+1) = Ch2(i)
end
(?? what is the meaning of 1:1;7? Is that a typo? I am thinking you want 1:7...
Since you seem to be using the result of one loop to change the value of Ch1 which you are using again in the next loop, it may be tricky to vectorize; but I wonder what you are expecting the output to be, since you really do have a vector as the result of the RHS of the equation. I can't be sure if you want to compute the result for one element at a time, or whether you want to compute vectors (and end up appending results to Ch1 and Ch2). The following line would run without throwing an error - but it may not be the calculation you want. Please clarify what you are hoping to achieve if this is an incorrect guess.
for i = 1:7
Ch2(i) = h2.*(N.*((Ch1(i) - C(i))./h2(i))) + C(i)./h2(i);
Ch1(i+1) = Ch2(i);
end