Related
I am not good at Matlab at all. I am trying to find minimum of function witjh constrains.
I am trying to use eample line by line as it is in documentation (https://www.mathworks.com/help/optim/ug/optimization-toolbox-tutorial.html - part Constrained Optimization Example: User-Supplied Gradients)
I have tried following code:
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
g = #(x,y) x.*y/2+(x-2).^2+(y-2).^2/2-4;
x0 = [2 ,0];
options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');
gfun = #(x,y) deal(g(x,y),[]);
[x,fval,exitflag,output] = fmincon(f,x0,[],[],[],[],[],[],gfun,options);
And this is the console output:
>> Untitled4
Not enough input arguments.
Error in Untitled4>#(x,y)x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20 (line 1)
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
Error in fmincon (line 552)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in Untitled4 (line 7)
[x,fval,exitflag,output] = fmincon(f,x0,[],[],[],[],[],[],gfun,options);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
I don't understand - what is wrong with my function?
you missed the part in the documentation defining fun,
and you miss-defined gfun.
(it is important that both are functions of a single variable, x)
Here is working code:
f = #(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20;
g = #(x,y) x.*y/2+(x-2).^2+(y-2).^2/2-4;
x0 = [2 0];
options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');
fun = #(x) f(x(1),x(2));
gfun = #(x) deal(g(x(1),x(2)),[]);
[x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],gfun,options);
I'm trying to solve a symbolic optimization problem using PSO optimizer in MATLAB. The variables r x a c n theta z are symbolic and CD is calculated by integrating r.
The CD is the objective function with free variables a,n, theta and lb and ub are bounds. Full code is as follows:
syms r x a c n theta z
assume(n,'positive');
D=0.24;
L=2;
f=L/D;
b=.8;
a0=0.02;
db=0.05;
V=1;
Re=(V*(D/2))/0.000001;
Cf=(0.075/(((log10(Re))-2)^2))+0.00025;
% Define r(x)
c=L-a-b-a0;
r1=0.5*D*(2*x/a)^(1/n);
I1=simplify(int(2*pi*r1,x,a0,a));
r2=D/2;
I2=simplify(int(2*pi*r2,x,a,a+b));
r3=(0.5*D)-((((3*D)/(2*(c)^2))-(tan(theta)/c))*(x-a-b)^2)+(((D/c^3 ...
(tand(theta)/c^2))*(x-a-b)^3);
I3=simplify(int(2*pi*r3,x,a+b,L));
A=simplify(I1+I2+I3);
Sn=pi*(D^2/4);
Cdstar=Cf*(1+(60*f^-3 )+(0.0025*f))*(A/(L^2));
Cdb=0.029*((db/D)^3)*(Cdstar^-0.5)*(Sn/(L^2));
CD=simplify(Cdstar+Cdb);
%optimization problem
objective=matlabFunction(CD,'Vars',[a,n,theta])
nVar=3;
lb = [deg2rad(5),0.25,a0];
ub = [deg2rad(60),5,L/2];
options =
optimoptions('particleswarm','SwarmSize',100,'HybridFcn',#fmincon);
[z,fval,exitflag,output] = particleswarm(objective,nVar,lb,ub,options)
And this is the error I get:
#(a,n,theta)pi.*4.404634153141517e-4+pi.*1.0./sqrt(pi.4.404634153141517e-4-pi.(a.*5.0-6.0).*1.0./(a.5.0e+1-5.9e+1).^3.(a.*2.32335e+6+tan((theta.*pi)./1.8e+2).*4.779e+6-tan(theta).*6.2658e+6-a.^2.*tan(theta).*2.655125e+7+a.^3.*tan(theta).*1.4875e+7-a.^4.*tan(theta).*3.125e+6-a.*tan((theta.*pi)./1.8e+2).*1.59975e+7+a.*tan(theta).*2.1063e+7+a.^2.*tan((theta.*pi)./1.8e+2).*2.008125e+7-a.^3.*tan((theta.*pi)./1.8e+2).*1.1203125e+7+a.^4.*tan((theta.*pi)./1.8e+2).*2.34375e+6-a.^2.*1.98e+6+a.^3.*5.625e+5-9.08811e+5).*1.223509486983755e-5-(n.pi.((a.*2.5e+1).^(-1.0./n)-2.0.^(1.0./n+1.0).*a.*2.5e+1).*1.101158538285379e-5)./(n+1.0)).9.440104166666668e-7-pi.(a.*5.0-6.0).*1.0./(a.5.0e+1-5.9e+1).^3.(a.*2.32335e+6+tan((theta.*pi)./1.8e+2).*4.779e+6-tan(theta).*6.2658e+6-a.^2.*tan(theta).*2.655125e+7+a.^3.*tan(theta).*1.4875e+7-a.^4.*tan(theta).*3.125e+6-a.*tan((theta.*pi)./1.8e+2).*1.59975e+7+a.*tan(theta).*2.1063e+7+a.^2.*tan((theta.*pi)./1.8e+2).*2.008125e+7-a.^3.*tan((theta.*pi)./1.8e+2).*1.1203125e+7+a.^4.*tan((theta.*pi)./1.8e+2).*2.34375e+6-a.^2.*1.98e+6+a.^3.*5.625e+5-9.08811e+5).*1.223509486983755e-5-(n.pi.((a.*2.5e+1).^(-1.0./n)-2.0.^(1.0./n+1.0).*a.*2.5e+1).*1.101158538285379e-5)./(n+1.0)
Not enough input arguments.
Error in
symengine>#(a,n,theta)pi.*4.404634153141517e-4+pi.*1.0./sqrt(pi.4.404634153141517e-4-pi.(a.*5.0-6.0).*1.0./(a.5.0e+1-5.9e+1).^3.(a.*2.32335e+6+tan((theta.*pi)./1.8e+2).*4.779e+6-tan(theta).*6.2658e+6-a.^2.*tan(theta).*2.655125e+7+a.^3.*tan(theta).*1.4875e+7-a.^4.*tan(theta).*3.125e+6-a.*tan((theta.*pi)./1.8e+2).*1.59975e+7+a.*tan(theta).*2.1063e+7+a.^2.*tan((theta.*pi)./1.8e+2).*2.008125e+7-a.^3.*tan((theta.*pi)./1.8e+2).*1.1203125e+7+a.^4.*tan((theta.*pi)./1.8e+2).*2.34375e+6-a.^2.*1.98e+6+a.^3.*5.625e+5-9.08811e+5).*1.223509486983755e-5-(n.pi.((a.*2.5e+1).^(-1.0./n)-2.0.^(1.0./n+1.0).*a.*2.5e+1).*1.101158538285379e-5)./(n+1.0)).9.440104166666668e-7-pi.(a.*5.0-6.0).*1.0./(a.5.0e+1-5.9e+1).^3.(a.*2.32335e+6+tan((theta.*pi)./1.8e+2).*4.779e+6-tan(theta).*6.2658e+6-a.^2.*tan(theta).*2.655125e+7+a.^3.*tan(theta).*1.4875e+7-a.^4.*tan(theta).*3.125e+6-a.*tan((theta.*pi)./1.8e+2).*1.59975e+7+a.*tan(theta).*2.1063e+7+a.^2.*tan((theta.*pi)./1.8e+2).*2.008125e+7-a.^3.*tan((theta.*pi)./1.8e+2).*1.1203125e+7+a.^4.*tan((theta.*pi)./1.8e+2).*2.34375e+6-a.^2.*1.98e+6+a.^3.*5.625e+5-9.08811e+5).*1.223509486983755e-5-(n.pi.((a.*2.5e+1).^(-1.0./n)-2.0.^(1.0./n+1.0).*a.*2.5e+1).*1.101158538285379e-5)./(n+1.0)
Error in particleswarm>makeState (line 694)
firstFval = objFcn(state.Positions(1,:));
Error in particleswarm>pswcore (line 169) state =
makeState(nvars,lbMatrix,ubMatrix,objFcn,options);
Error in particleswarm (line 151) [x,fval,exitFlag,output] =
pswcore(objFcn,nvars,lbRow,ubRow,output,options);
Error in MYRING_SYMS_optimisation_K (line 56) [z,fval,exitflag,output]
= particleswarm(objective,nVar,lb,ub,options)
Caused by:
Failure in initial objective function evaluation. PARTICLESWARM cannot continue.
The fun takes only one argument, which is a vector with nvars elements. From particleswarm doc:
x = particleswarm(fun,nvars) attempts to find a vector x that achieves a local minimum of fun. nvars is the dimension (number of design variables) of fun.
So you need to declare a new objective function that only takes 1 argument:
[z,fval,exitflag,output] = particleswarm( ...
#(x) objective(x(1), x(2), x(3)), ...
nVar,lb,ub,options)
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 new to Matlab. I am trying to solve a non-linear equation using this inbuilt Matlab function called fzero() but it's not giving me the results.
The main file goes like
A = 5;
B = 6;
C = 10;
eq = equation (A, B, C);
fzero(#(x)eq);
The other function file is:
function eq = equation (A, B, C)
syms x;
eq = A*x.^2 + B*x + C*(asinh(x)) ;
When I run this code, I get the following error:
Error using fzero (line 118)
The input should be either a structure with valid fields or at least two arguments to
FZERO.
Error in main (line 7)
fzero(#(x)eq);
Could someone help me with this?
EDIT:
WHen I specify the check point as 0, it returns me the following error.
Undefined function 'isfinite' for input arguments of type 'sym'.
Error in fzero (line 308)
elseif ~isfinite(fx) || ~isreal(fx)
Error in main (line 7)
fzero(#(x)eq, 0);
There are several mistakes in your code. For a start, fzero is for finding numerical roots of a non-linear equation, it is not for symbolic computations (check the documentation), so get rid of syms x. The correct way to call fzero in your case is a as follows:
A = 5;
B = 6;
C = 10;
eq = #(x) A*x^2 + B*x + C*(asinh(x));
x0 = 0; % or whatever starting point you want to specify
x = fzero(eq,x0)
You need to specify a guess, x0 point
fun = #sin; % function
x0 = 3; % initial point
x = fzero(fun,x0)
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);