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
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]
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.
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);
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;
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);