Dynamically fixing some variables when using fmincon - matlab

I have a MINLP objective function and I want to fix some variables value into constant as an example described below:
A = [1 1 1];
b = 30;
x1 = zeros(1,3);
y=1;
x = fmincon(#(x)objfun(x,y),x1,A,b);
function f = objfun(x,y)
x(y) = 1;
f = x(1)^2 + x(2)^2 + x(3)^2;
end
However, the result of variable x is all zeros. It seems that x(1) cannot be forced to be 1. How to fix this problem?

You should use a different syntax of fmincon:
fmincon(fun,x0,A,b,Aeq,beq,lb,ub)
Then, if you wish to only limit one of the values, you can use these bounds:
lb = [1 -Inf -Inf];
ub = [1 Inf Inf];
Since you will also need to specify the inputs Aeq and beq, don't forget you can use [] for any inputs you don't want/need to specify, as shown in this example in the documentation:
fun = #(x)1+x(1)./(1+x(2)) - 3*x(1).*x(2) + x(2).*(1+x(1));
lb = [0,0];
ub = [1,2];
A = [];
b = [];
Aeq = [];
beq = [];
x0 = [0.5,1];
[x,fval] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub)

Related

Fseminf function with 2 dimensional x

I have a little problem, fseminf used to work just fine, but now as I reached to it, it happend to produce an error, I have no idea what happend. Here is the code with an example which does not work:
clc;
clear;
close;
% Zdefiniuj funkcje
global g f S
f = #(x) (x(1)-2).^2 + (x(2)-0.2).^2;
g = #(x,s) 5.*x(1).^2.*sin(pi.*sqrt(s))./(1+s.^2) - x(2);
lb = [-1,0];
ub = [1 ,0.2];
S = [0,1];
A = [];
b = [];
Aeq = [];
beq = [];
x0 = [0,0]';
[x,fval,exitflag,output,lambda] = fseminf(f,x0,1,#seminfcon2,A,b,Aeq,beq,lb,ub);
disp('x= ')
x
And seminfcon is defined:
function [c, ceq, K1, s] = seminfcon2(x,s)
global S g
% Dodatkowe parametry
c = [];
ceq = [];
if isnan(s(1,1))
s(1,1)=0.001;
s(1,2)=0;
end
t = S(1):s(1):S(2);
K1 = g(x,t);
The error is when calculating x, meaning in fseminf

implementation if isnan to sampling an interval

I am trying to run fseminf function
f = #(x) (x(1)-2).^2 + (x(2)-0.2).^2;
g = #(x,s) 5*x(1).^2*sin(pi*sqrt(s))/(1+s.^2) - x(2);
lb = [-1,0];
ub = [1 ,0.2];
S = [0,1];
A = [];
b = [];
Aeq = [];
beq = [];
x0 = [0,0];
x = fseminf(f,x0,1,#seminfcon1,A,b,Aeq,beq,lb,ub);
Where:
function [c, ceq, K1, s] = seminfcon1(x,s)
global S g
% No finite nonlinear inequality and equality constraints
c = [];
ceq = [];
% Sample set
if isnan(s)
% Initial sampling interval
s = [0.0001 0];
end
t = S(1):s(1):S(2);
% Evaluate the semi-infinite constraint
K1 = g(x,t);
This is the code I use for creating a finite set from S, which is an interval. I do not understand how it works, why do we use isnan function instead of just declaring s=[0.0001] (which by the way does not work). It is used for fseminf alghoritm, I took the code from an example.

Using interpolation outside function definition in solution using Runge-Kutta 4th order

I have written MATLAB code to solve the following systems of differential equations.
with
where
and z2 = x2 + (1+a)x1
a = 2;
k = 1+a;
b = 3;
ca = 5;
cb = 2;
theta1t = 0:.1:10;
theta1 = ca*normpdf(theta1t-5);
theta2t = 0:.1:10;
theta2 = cb*ones(1,101);
h = 0.05;
t = 1:h:10;
y = zeros(2,length(t));
y(1,1) = 1; % <-- The initial value of y at time 1
y(2,1) = 0; % <-- The initial value of y' at time 1
f = #(t,y) [y(2)+interp1(theta1t,theta1,t,'spline')*y(1)*sin(y(2));
interp1(theta2t,theta2,t,'spline')*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
for i=1:(length(t)-1) % At each step in the loop below, changed y(i) to y(:,i) to accommodate multi results
k1 = f( t(i) , y(:,i) );
k2 = f( t(i)+0.5*h, y(:,i)+0.5*h*k1);
k3 = f( t(i)+0.5*h, y(:,i)+0.5*h*k2);
k4 = f( t(i)+ h, y(:,i)+ h*k3);
y(:,i+1) = y(:,i) + (1/6)*(k1 + 2*k2 + 2*k3 + k4)*h;
end
plot(t,y(:,:),'r','LineWidth',2);
legend('RK4');
xlabel('Time')
ylabel('y')
Now what is want to do is define the interpolations/extrapolations outside the function definition like
theta1_interp = interp1(theta1t,theta1,t,'spline');
theta2_interp = interp1(theta2t,theta2,t,'spline');
f = #(t,y) [y(2)+theta1_interp*y(1)*sin(y(2));
theta2_interp*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
But this gives the error
Please suggest a solution to this issue.
Note that in your original code:
f = #(t,y) [y(2)+interp1(theta1t,theta1,t,'spline')*y(1)*sin(y(2));
interp1(theta2t,theta2,t,'spline')*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
the call to interp1 uses the input variable t. t inside this anonymous function is not the same as the t outside of it, where it is defined as a vector.
This means that, when you do
theta1_interp = interp1(theta1t,theta1,t,'spline');
then theta1_interp is a vector containing interpolated values for all your ts, not just one. One way around this is to create more anonymous functions:
theta1_interp = #(t) interp1(theta1t,theta1,t,'spline');
theta2_interp = #(t) interp1(theta2t,theta2,t,'spline');
f = #(t,y) [y(2)+theta1_interp(t)*y(1)*sin(y(2));
theta2_interp(t)*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
Though this doesn't really improve your code in any way over the original.

Finding the distribution of '1' in rows/columns from a parity-check matrix

My question this time concerns the obtention of the degree distribution of a LDPC matrix through linear programming, under the following statement:
My code is the following:
function [v] = LP_Irr_LDPC(k,Ebn0)
options = optimoptions('fmincon','Display','iter','Algorithm','interior-point','MaxIter', 4000, 'MaxFunEvals', 70000);
fun = #(v) -sum(v(1:k)./(1:k));
A = [];
b = [];
Aeq = [0, ones(1,k-1)];
beq = 1;
lb = zeros(1,k);
ub = [0, ones(1,k-1)];
nonlcon = #(v)DensEv_SP(v,Ebn0);
l0 = [0 rand(1,k-1)];
l0 = l0./sum(l0);
v = fmincon(fun,l0,A,b,Aeq,beq,lb,ub,nonlcon,options)
end
Definition of nonlinear constraints:
function [c, ceq] = DensEv_SP(v,Ebn0)
% It is also needed to modify this function, as you cannot pass parameters from others to it.
h = [0 rand(1,19)];
h = h./sum(h); % This is where h comes from
syms x;
X = x.^(0:(length(h)-1));
R = h*transpose(X);
ebn0 = 10^(Ebn0/10);
Rm = 1;
LLR = (-50:50);
p03 = 0.3;
LLR03 = log((1-p03)/p03);
r03 = 1 - p03;
noise03 = (2*r03*Rm*ebn0)^-1;
pf03 = normpdf(LLR, LLR03, noise03);
sumpf03 = sum(pf03(1:length(pf03)/2));
divisions = 100;
Aj = zeros(1, divisions);
rho = zeros(1, divisions);
xj = zeros(1, divisions);
k = 10; % Length(v) -> Same value as in 'Complete.m'
for j=1:1:divisions
xj(j) = sumpf03*j/divisions;
rho(j) = subs(R,x,1-xj(j));
Aj(j) = 1 - rho(j);
end
c = zeros(1, length(xj));
lambda = zeros(1, length(Aj));
for j = 1:1:length(xj)
lambda(j) = sum(v(2:k).*(Aj(j).^(1:(k-1))));
c(j) = sumpf03*lambda(j) - xj(j);
end
save Almacen
ceq = [];
%ceq = sum(v)-1;
end
This question is linked to the one posted here. My problem is that I need that each element from vectors v and h resulting from this optimization problem is a fraction of x/N and x/(N(1-r) respectively.
How could I ensure that condition without losing convergence capability?
I came up with one possible solution, at least for vector h, within the function DensEv_SP:
function [c, ceq] = DensEv_SP(v,Ebn0)
% It is also needed to modify this function, as you cannot pass parameters from others to it.
k = 10; % Same as in Complete.m, desired sum of h
M = 19; % Number of integers
h = [0 diff([0,sort(randperm(k+M-1,M-1)),k+M])-ones(1,M)];
h = h./sum(h);
syms x;
X = x.^(0:(length(h)-1));
R = h*transpose(X);
ebn0 = 10^(Ebn0/10);
Rm = 1;
LLR = (-50:50);
p03 = 0.3;
LLR03 = log((1-p03)/p03);
r03 = 1 - p03;
noise03 = (2*r03*Rm*ebn0)^-1;
pf03 = normpdf(LLR, LLR03, noise03);
sumpf03 = sum(pf03(1:length(pf03)/2));
divisions = 100;
Aj = zeros(1, divisions);
rho = zeros(1, divisions);
xj = zeros(1, divisions);
N = 20; % Length(v) -> Same value as in 'Complete.m'
for j=1:1:divisions
xj(j) = sumpf03*j/divisions;
rho(j) = subs(R,x,1-xj(j));
Aj(j) = 1 - rho(j);
end
c = zeros(1, length(xj));
lambda = zeros(1, length(Aj));
for j = 1:1:length(xj)
lambda(j) = sum(v(2:k).*(Aj(j).^(1:(k-1))));
c(j) = sumpf03*lambda(j) - xj(j);
end
save Almacen
ceq = (N*v)-floor(N*v);
%ceq = sum(v)-1;
end
As above stated, there is no longer any problem with vector h; nevertheless the way I defined ceq value seemed to be insufficient to make the optimization work out (the problems with v have not diminished at all). Does anybody know how to find the solution?

Solving Multiple Equations For Repeated Times With Different Initial Conditions Matlab

I have the following set of values in an array.
a = [a(1) a(2) ... a(1907)]
Gamma(1)= (u*f(1))+(r*a(1))
u and r are constant and f(n) changes during each step and its initial value is f(1) = zero.
f(n) next values will be generated from solving these equations.
h(1) = x(1) + Gamma(1) for which x(1)=0 and in next steps is constant. (c)
Z(1)= constant(T) * h(1)
f(2) = constant(G) * Z(1)
These steps will repeated 1907 times. Any idea what should I do at all?
You can input your initial conditions into a very simple for loop.
% a, u, r, T, G are assumed available.
f = zeros(1908, 1);
Z = zeros(1907 ,1);
Gamma = zeros(1907, 1);
x = [0; c*ones(1906, 1)];
for ii = 1:1907
Gamma(ii) = u*f(ii) + r*a(ii);
h(ii) = x(ii) + Gamma(ii);
Z(ii) = T*h(ii);
f(ii+1) = G*Z(ii);
end