Implementing an Optimization problem using matlab - matlab

I am trying to implement an Optimization problem using matlab
Where N=100 , M=(N-1/k) and L=50.
N=100;
L = 50;
for K= 101:1:1000
M = (N-1)/K;
R=#(x) -((1./x(2)).*(N- (x(1).*M)-((min ( N./(L.*x(2)), K)-x(1))*(max(0,N-(L.*x(2).*x(1)))))/(x(1)+(min ( N./(L.*x(2)), K)-x(2)))) - (max(0,N-(L.*K*x(2)))));
LB = [1 1];
b=1:min((ceil(N/L)), K) ;
UB = [min((ceil(N./L)), K) ((N./(L*b))) ];
options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
[xopt, vopt] = fmincon(R,1,[],[],[],[],LB,UB,[],options);
v(K) = -vopt;
end
plot(101:1000,v,'v-','LineWidth',2);
xlabel('Number of Users (K)');
ylabel('Delivery Rate (R)');
The following error appears:
Warning: Length of lower bounds is > length(x); ignoring extra bounds.
> In checkbounds (line 27)
In fmincon (line 318)
In R1 (line 19)
Warning: Length of upper bounds is > length(x); ignoring extra bounds.
> In checkbounds (line 41)
In fmincon (line 318)
In R1 (line 19)
Index exceeds array bounds.
Error in
R1>#(x)-((1./x(2)).*(N-(x(1).*M)-((min(N./(L.*x(2)),K)-x(1))*(max(0,N-(L.*x(2).*x(1)))))/(x(1)+(min(N./(L.*x(2)),K)-x(2))))-(max(0,N-(L.*K*x(2)))))
Error in fmincon (line 546)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in R1 (line 19)
[xopt, vopt] = fmincon(R,1,[],[],[],[],LB,UB,[],options);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
The output graph should be the one shown here:
(the lower bound curve)

Couples of mistakes
First, the initial guess should be an 1D array of length 2, kindly
replace 1 by [1, 1]
Better initialize the variable v first , it will speed up your
computation
The most important is the upper bound of l, as you can see it
depends on s and it's in the denominator, consider it as non linear
constraint then set UB = [] You will need to include nonlcon into
fmincon
The code is as follow
N=100;
L = 50;
t = 101:1:1000;
le = length(t);
v = zeros(1, le);
for K= 100:1:1000
M = (N-1)/K;
R = #(x) -(1./(x(1))).*(N-x(1).*((N-1)./K)-((min(ceil(N./(L.*x(2))), K)).*...
max(N -L.*x(1).*x(2), 0))./((x(1) +(min(ceil(N./(L.*x(2))), K))))...
-(max(N - K.*L.*x(2), 0)));
LB = [1 1];
options = optimoptions('fmincon','Algorithm','interior-point');
[xopt, vopt] = fmincon(R,[1, 1],[],[],[],[],LB,[],...
#(x)nonlincon(x(1), x(2),N, L, K ),options);
v(K-101+1) = -vopt;
end
plot(101:1000,v,'v-','LineWidth',2);
xlabel('Number of Users (K)');
ylabel('Delivery Rate (R)');
function [c, ceq] = nonlincon(s, l,N, L, K )
c(1) = l -N./(L.*s);
c(2) = s - min((ceil(N./L)), K) ;
ceq = [];
end

Related

Unable to meet integration tolerances in fmincon to solve ODE optimization problem

I have constrained ODE optimization problem to be solved using Matlab, I started by solving the ODE using ode15s which working will this initial values, also I had very good results without constraints using fminsearch, the problem started when I used fmincon it gave me these warnings:
Warning: Length of lower bounds is < length(x); filling in missing lower bounds with -Inf.
> In checkbounds (line 33)
In fmincon (line 318)
In Optimization (line 64)
Warning: Length of upper bounds is < length(x); filling in missing upper bounds with +Inf.
> In checkbounds (line 47)
In fmincon (line 318)
In Optimization (line 64)
Warning: Failure at t=2.340250e+01. Unable to meet integration tolerances without reducing the step size below the smallest value
allowed (5.684342e-14) at time t.
> In ode15s (line 668)
In ObjFun (line 6)
In barrier
In fmincon (line 813)
In Optimization (line 64)
I tried to remove constraints, but nothing changed...
y1_max = 5; y2_max = 2.3;
y01 = 1; y02 = 1.6;
%Control function parameter
Umin = -0.3; Umax = -0.1;
%Creation the structure of model parameters
params.T0=T0; params.Tf=Tf;
params.y1d=y1d; params.y2d=y2d;
params.y01=y01; params.y02=y02;
params.y2_max=y2_max;
n=2;
U0=-0.2*ones(1,n);
params.n=n;
params.U=U0; params.Umax=Umax; params.Umin=Umin;
params.dt=(Tf-T0)/n;
%for initial value of optimization parameters
options = odeset('RelTol',1e-7,'AbsTol',1e-7);
U=U0;
[t,y]=ode15s(#ODEsolver,[T0,Tf],[y01 y02],options,params);
%adding the ode solution as input prameters
params.t=t; params.y1= y(:,1); params.y2= y(:,2);
U0=-0.2*ones(1,n);
params.n=n; params.U=U0;
params.dt=(Tf-T0)/n;
A = [];
B = [];
Aq = []; Bq = [];
options1 = optimset('MaxIter',5000);
[x,fval,exitflag,output] = fmincon(#ObjFun,U0,A,B,Aq,Bq,Umin,Umax,IneqConst(U0,params),options1,params)
function y = ODEsolver(t,y,params)
dt = params.dt;
nu = floor(t/dt)+1;
nu = min(nu,params.n-1);
t1 = (nu-1)*dt;
Ut = params.U(nu) + ((t-t1)/dt)*(params.U(nu+1) - params.U(nu));
dy1a = ((0.63*y(1))/(1 + y(1)));
dy1b = (Ut*y(1)*y(2))/(1+0.6*y(1));
dy1 = dy1a + dy1b;
dy2a = (0.15*y(2))/(0.05-0.2*y(2));
dy2 = -0.2*y(2) + dy1b * dy2a;
y = [dy1; dy2];
end
function ObjFun1 = ObjFun(u,params)
% Calculating the value of the optimization criteria
params.U=u;
options = odeset('RelTol',1e-8,'AbsTol',1e-8);
[t,y]=ode15s(#ODEsolver,[0,100],[params.y01,
params.y02],options,params);
ObjFun1 =trapz(t,(y(:,1)-params.y1d).^2);
end
function [c,Const] = IneqConst(u, params)
params.U=u;
options = odeset('RelTol',1e-8,'AbsTol',1e-8);
[t,y]=ode15s(#ODEsolver,[0,100],[params.y01, params.y02],options,params);
c =[];
yCon = y(:,2)-params.y2_max;
Const = trapz(t,(abs(yCon)+yCon).^2);
end
The bug in this code is that the dimension of the bounds (Umin, Umax) should be an array with the same size of the control function U
so if the control function parameters n = 2 then Umin = [-0.3 -0.3] & Umax = [-0.1 -0.1]

Matlab: fmincon throws error

I am implementing the expression given in the image which is the log-likelihood for AR(p) model.
In this case, p=2. I am using fmincon as the optimization tool. I checked the documentation and other examples over internet regarding the syntax of this command. Still, I am unable to mitigate the problem. Can somebody please help in eliminating the problem?
The following is the error
Warning: Options LargeScale = 'off' and Algorithm = 'trust-region-reflective' conflict.
Ignoring Algorithm and running active-set algorithm. To run trust-region-reflective, set
LargeScale = 'on'. To run active-set without this warning, use Algorithm = 'active-set'.
> In fmincon at 456
In MLE_AR2 at 20
Error using ll_AR2 (line 6)
Not enough input arguments.
Error in fmincon (line 601)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in MLE_AR2 (line 20)
[theta_hat,likelihood] =
fmincon(#ll_AR2,theta0,[],[],[],[],low_theta,up_theta,[],opts);
Caused by:
Failure in initial user-supplied objective function evaluation. FMINCON cannot
continue.
The vector of unknown parameters,
theta_hat = [c, theta0, theta1, theta2] where c = intercept in the original model which is zero ; theta0 = phi1 = 0.195 ; theta1 = -0.95; theta2 = variance of the noise sigma2_epsilon.
The CODE:
clc
clear all
global ERS
var_eps = 1;
epsilon = sqrt(var_eps)*randn(5000,1); % Gaussian signal exciting the AR model
theta0 = ones(4,1); %Initial values of the parameters
low_theta = zeros(4,1); %Lower bound of the parameters
up_theta = 100*ones(4,1); %upper bound of the parameters
opts=optimset('DerivativeCheck','off','Display','off','TolX',1e-6,'TolFun',1e-6,...
'Diagnostics','off','MaxIter', 200, 'LargeScale','off');
ERS(1) = 0.0;
ERS(2) = 0.0;
for t= 3:5000
ERS(t)= 0.1950*ERS(t-1) -0.9500*ERS(t-2)+ epsilon(t); %AR(2) model y
end
[theta_hat,likelihood,exit1] = fmincon(#ll_AR2,theta0,[],[],[],[],low_theta,up_theta,[],opts);
exit(1,1)=exit1;
format long;disp(num2str([theta_hat],5))
function L = ll_AR2(theta,Y)
rho0 = theta(1); %c
rho1 = theta(2); %phi1
rho2 = theta(3); %phi2
sigma2_epsilon = theta(4);
T= size(Y,1);
p=2;
mu_p = rho0./(1-rho1-rho2); %mean of Y for the first p samples
%changed sign of the log likelihood expression
cov_p = xcov(Y);
L1 = (Y(3:end) - rho0 - rho1.*Y(1:end-1) - rho2.*Y(1:end-2)).^2;
L = (p/2).*(log(2*pi)) + (p/2).*log(sigma2_epsilon) - 0.5*log(det(inv(cov_p))) + 0.5*(sigma2_epsilon^-1).*(Y(p) - mu_p)'.*inv(cov_p).*(Y(p) - mu_p)+...
(T-p).*0.5*log(2*pi) + 0.5*(T-p).*log(sigma2_epsilon) + 0.5*(sigma2_epsilon^-1).*L1;
L = sum(L);
end
You are trying to pass constant parameters to the objective function (Y) in addition to the optimization variables (theta).
The right way of doing so is using anonymous function:
Y = ...; %// define your parameter here
fmincon( #(theta) ll_AR2(theta, Y), theta0, [],[],[],[],low_theta,up_theta,[],opts);
Now the objective function, as far as fmincon concerns, depends only on theta.
For more information you can read about anonymous functions and passing const parameters.

Newton's method roots on Matlab

I am not so much experiences with Matlab. I just need it for the sake of solving some lengthy non-linear equations. Instead of using fzero, I wanna use Newton-Raphson's to solve the equation.
newton.m file contains the following code.
function [ x, ex ] = newton( f, df, x0, tol, nmax )
if nargin == 3
tol = 1e-4;
nmax = 1e1;
elseif nargin == 4
nmax = 1e1;
elseif nargin ~= 5
error('newton: invalid input parameters');
end
x(1) = x0 - (f(x0)/df(x0));
ex(1) = abs(x(1)-x0);
k = 2;
while (ex(k-1) >= tol) && (k <= nmax)
x(k) = x(k-1) - (f(x(k-1))/df(x(k-1)));
ex(k) = abs(x(k)-x(k-1));
k = k+1;
end
end
And in the main file, I have called this function as follows:
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
When I run this function, it gives me the following error.
Error using sym/subsref (line 9)
Error using maplemex
Error, (in MTM:-subsref) Array index out of range
Error in newton (line 37)
x(1) = x0 - (f(x0)/df(x0));
Error in main (line 104)
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
Could anyone please help me to get through this?
You can probably use Matlab's fsolve (http://uk.mathworks.com/help/optim/ug/fsolve.html) with a couple of options
x0 = 9;
options = optimoptions('fsolve','Algorithm','levenberg-marquardt','TolFun',5*10^-6,'MaxIter',100);
x = fsolve(#(x)(exp(x) + x^3), x0,options);
or just fzero (http://uk.mathworks.com/help/optim/ug/fzero.html) which implements BD algorithm
x = fzero(#(x)(exp(x) + x^3), x0);

MATLAB strange error Gamma function numerical integration

i try to run the following in order to integrate numerically:
nu = 8;
psi=-0.2;
lambda = 1;
git = #(u) tpdf((0 - lambda * skewtdis_inverse(u, nu, psi)), nu);
g(t,i) = integral(git,1e-10,1-1e-10,'AbsTol',1e-16);
where tpdf is a matlab function and skewtdis:inverse looks like this:
function inv = skewtdis_inverse(u, nu, lambda)
% PURPOSE: returns the inverse cdf at u of Hansen's (1994) 'skewed t' distribution
c = gamma((nu+1)/2)/(sqrt(pi*(nu-2))*gamma(nu/2));
a = 4*lambda*c*((nu-2)/(nu-1));
b = sqrt(1 + 3*lambda^2 - a^2);
if (u<(1-lambda)/2);
inv = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u/(1-lambda),nu)-a/b;
elseif (u>=(1-lambda)/2);
inv = (1+lambda)/b*sqrt((nu-2)./nu).*tinv(0.5+1/(1+lambda)*(u-(1-lambda)/2),nu)-a/b;
end
What i get out is:
Error in skewtdis_inverse (line 6)
c = gamma((nu+1)/2)/(sqrt(pi*(nu-2))*gamma(nu/2));
Output argument "inv" (and maybe others) not assigned during call to "F:\Xyz\skewtdis_inverse.m>skewtdis_inverse".
Error in #(u)tpdf((0-lambda*skewtdis_inverse(u,nu,psi)),nu)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);
If i , however call the function in thr handle directly there are no Problems:
tpdf((0 - lambda * skewtdis_inverse(1e-10, nu, psi)), nu)
ans =
1.4092e-11
tpdf((0 - lambda * skewtdis_inverse(1-1e-10, nu, psi)), nu)
ans =
7.0108e-10
Your effort is highly appreciated!
By default, integral expects the function handle to take a vector input.
In your code, the if-statement creates a complication since the condition will evaluate to true only if all elements of u satisfy it.
So, if u is a vector that has elements both greater than and less than (1-lambda)/2, inv will never be assigned.
There are two options:
Put the if-statement in a for-loop and iterate over all of the elements of u.
Use logical indexes for the assignment.
The second option is faster for large element count and, in my opinion, cleaner:
inv = u; % Allocation
IsBelow = u < (1-lambda)/2; % Below the threshold
IsAbove = ~IsBelow ; % Above the threshold
inv(IsBelow) = (1-lambda)/b*sqrt((nu-2)./nu)*tinv(u(IsBelow)/(1-lambda),nu)-a/b;
inv(IsAbove) = (1+lambda)/b*sqrt((nu-2)./nu)*tinv(0.5+1/(1+lambda)*(u(IsAbove)-(1-lambda)/2),nu)-a/b;

Create flexible function handle

I am using numerical integration in MATLAB, with one varibale to integrate over but the function also contains a variable number of terms depending on the dimension of my data. Right now this looks like the following for the 2-dimensional case:
for t = 1:T
fxt = #(u) exp(-0.5*(x(t,1)-theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x(t,2) -theta*norminv(u,0,1)).^2);
f(t) = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3);
end
I would like to have this function flexible in the sense that there could be any number of data points in, each in the following term:
exp(-0.5*(x(t,i) -theta*norminv(u,0,1)).^2);
I hope this is understandable.
If x and u have a valid dimension match (vector-vector or array-scalar) for the subtraction, you can put the whole matrix x into the handle and pass it to the integral function using the name-parameter pair ('ArrayValued',true):
fxt = #(u) exp(-0.5*(x - theta*norminv(u,0,1)).^2) .* ...
exp(-0.5*(x - theta*norminv(u,0,1)).^2);
f = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
[Documentation]
You may need a loop if integral ever passes a vector u into the handle.
But in looking at how the integral function is written, the integration nodes are entered as scalars for array-valued functions, so the loop shouldn't be necessary unless some weird dimension-mismatch error is thrown.
Array-Valued Output
In response to the comments below, you could try this function handle:
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
Then your current loop would look like
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
for t = 1:T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
end
The ArrayValued flag is needed since x and u will have a dimension mismatch.
In this form, another loop would be needed to sweep through the k indexes.
However, we can improve this function by skipping the loop altogether since each iterate of the loop is independent by using the ArrayValued mode:
fx = #(u,k) prod(exp(-0.5*(x(:,1:k)-theta*norminv(u,0,1)).^2),2);
k = 2;
f = integral(#(u)fx(u,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
Vector-Valued Output
If ArrayValued is not desired, which may be the case if the integration requires a lot of subdivisions and a vector-valued u is preferable, you can also try a recursive version of the handle using cell arrays:
% x has size [T,K]
fx = cell(K,1);
fx{1} = #(u,t) exp(-0.5*(x(t,1) - theta*norminv(u,0,1)).^2);
for k = 2:K
fx{k} = #(u,t) fx{k-1}(u,t).*exp(-0.5*(x(t,k) - theta*norminv(u,0,1)).^2);
end
f(T) = 0;
k = 2;
for t = 1:T
f(t) = integral(#(u)fx{k}(u,t),1e-4,1-1e-4,'AbsTol',1e-3);
end
ThanksTroy but now I run into the follwing:
x = [0.3,0.8;1.5,-0.7];
T = size(x,1);
k = size(x,2);
theta= 1;
fx = #(u,t,k) prod(exp(-0.5*(x(t,1:k) - theta*norminv(u,0,1))^2));
for t = 1,T
f(t) = integral(#(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3);
end
Error using -
Matrix dimensions must agree.
Error in #(u,t,k)prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1))^2))
Error in #(u)fx(u,t,k)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);