I'm new to MATLAB and I need help to solve this optimization problem. Here is the objective function m file:
function f = objfun(x,w1,w2)
w = 6:1:125;
z1 = x(4).*((x(1).*(1i.^2).*w.^2)+(x(5).*1i.*w)+x(3));
z2 = x(1).*x(2).*(1i.^4).*w.^4;
z3 = ((x(1)+x(2)).*x(5).*(1i.^3).*w.^3);
z4 = (1i.^2).*w.^2.*((x(1).*x(3))+(x(2).*x(3))+(x(1).*x(4)));
z5 = 1i.*w.*(x(5).*x(4));
z6 = x(3).*x(4);
z7 = x(4).*(-x(5).*1i.*w-x(3));
z8 = (z7./(z2+z3+z4+z5+z6));
trfs = 0.1.*(w.^2).*(z7./(z2+z3+z4+z5+z6));
trfs2 = 0.1.*(z7./(z2+z3+z4+z5+z6));
trfu = 0.1.*(z1./(z2+z3+z4+z5+z6));
abstrfs = abs(trfs);
abstrfs2 = abs(trfs2);
abstrfu = abs(trfu);
y1 = rms(abstrfs);
y2 = rms(abstrfs2);
y3 = abs(rms(abstrfu)-y2);
f = w1.*(y1.^2)+w2.*(y3.^2);
end
These are the constraints:
function [c,ceq] = confun(x,z8,y1,trfu)
c(1) = y1 - 0.315;
c(2) = abs(z8-trfu) - 0.217;
c(3) = abs(trfu) - 0.07;
c(4) = sqrt(x(3)./x(1)) - 9.425;
ceq = [];
end
Main file
x0 = [510 85 81000 650000 3000];
UB = [764 124 120720 839170 3840];
LB = [509 83 80480 559440 2560];
j = 1;
for i = 0:0.05:1
w1 = i;
w2 = 1-i;
[x,fval] = fmincon(#objfun,x0,[],[],[],[],LB,UB,#confun,[],w1,w2);
w = 6:1:125;
z1 = x(4).*((x(1).*(1i.^2).*w.^2)+(x(5).*1i.*w)+x(3));
z2 = x(1).*x(2).*(1i.^4).*w.^4;
z3 = ((x(1)+x(2)).*x(5).*(1i.^3).*w.^3);
z4 = (1i.^2).*w.^2.*((x(1).*x(3))+(x(2).*x(3))+(x(1).*x(4)));
z5 = 1i.*w.*(x(5).*x(4));
z6 = x(3).*x(4);
z7 = x(4).*(-x(5).*1i.*w-x(3));
z8 = (z7./(z2+z3+z4+z5+z6));
trfs =(w.^2).*(z7./(z2+z3+z4+z5+z6));
trfs2 = (z7./(z2+z3+z4+z5+z6));
trfu = (z1./(z2+z3+z4+z5+z6));
abstrfs = abs(trfs);
abstrfs2 = abs(trfs2);
abstrfu = abs(trfu);
y1(j) = rms(abstrfs);
y2(j) = rms(abstrfs2);
y3(j) = abs(rms(abstrfu)-y2(j));
j = j+1;
end
plot (y1,y3,'r.','MarkerSize',10)
I'm getting the error message;
Not enough input arguments.
Error in confun (line 5)
c(2) = abs(z8-trfu) - 0.217;
Error in fmincon (line 633)
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
Error in main (line 13)
[x,fval] = fmincon(#objfun,x0,[],[],[],[],LB,UB,#confun,[],w1,w2);
Caused by:
Failure in initial nonlinear constraint function evaluation. FMINCON cannot continue.
I know fmincon accepts constraint function with input in form of one vector with number of elements corresponding to number of constrained variables. But what I don't know is how to set all the input arguments as one vector.
Because the objective function is a bit bulky I separated it into different variables in objfun. Do I have to expand the function when setting constraints or is there another way? I have done a lot of research and still not sure how this works.
Both functions that their handles are passed as fun and nonlcon arguments should take only one argument, which is the design vector (not the constant values of the problem). So you should construct new anonymous functions and pass them to fmincon like this:
[x,fval] = fmincon(#(x)objfun(x, w1, w2),...
x0,[],[],[],[],LB,UB,#(x)confun(x,z8,y1,trfu));
But to do so, z8, y1, and trfu should be assigned before the call to fmincon. Since these values are actually calculated for each x, I'm afraid you need to calculate them again in confun. If this is not a very time consuming optimization, only move them to a third function and call it from both objfun and confun. Otherwise follow the method described here, to use values calculated in objective function, in constraint functions.
Related
Basically I would like to use the fsolve command in order to find the roots of an equation.
I think I should create a function handle that evaluates this equation in the form "right hand side - left hand side =0", but I've been struggling to make this work. Does anyone know how to do this?
The equation itself is 1/sqrt(f) = -1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708)). So I would like to find the point of intersection of the left and right side by solving for 1/sqrt(f)+(1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708))) = 0 using fsolve.
Thanks a lot!
The code so far (not working at all)
f = #(x) friction(x,rho,mu,e,D,Q, tol, maxIter) ;
xguess = [0, 1];
sol = fsolve(x, xguess ) ;
function y = friction(x,rho,mu,e,D,Q, tol, maxIter)
D = 0.1;
L = 100
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)))
end
Error message:
Error using lsqfcnchk (line 80)
FUN must be a function, a valid character vector expression, or an inline function object.
Error in fsolve (line 238)
funfcn = lsqfcnchk(FUN,'fsolve',length(varargin),funValCheck,gradflag);
Error in Untitled (line 6)
sol = fsolve(x, xguess ) ;
opt = optimset('Display', 'Iter');
sol = fsolve(#(x) friction(x), 1, opt);
function y = friction(x)
D = 0.1;
L = 100; % note -- unused
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)));
end
sol = 0.0054
the first argument of fsolve should be the function not variable. Replace:
sol = fsolve(x, xguess );
with
sol = fsolve(f, xguess );
And define Rho, mu, e etc before you define f (not inside the friction function).
I'm having some issues getting my RK2 algorithm to work for a certain second-order linear differential equation. I have posted my current code (with the provided parameters) below. For some reason, the value of y1 deviates from the true value by a wider margin each iteration. Any input would be greatly appreciated. Thanks!
Code:
f = #(x,y1,y2) [y2; (1+y2)/x];
a = 1;
b = 2;
alpha = 0;
beta = 1;
n = 21;
h = (b-a)/(n-1);
yexact = #(x) 2*log(x)/log(2) - x +1;
ye = yexact((a:h:b)');
s = (beta - alpha)/(b - a);
y0 = [alpha;s];
[y1, y2] = RungeKuttaTwo2D(f, a, b, h, y0);
error = abs(ye - y1);
function [y1, y2] = RungeKuttaTwo2D(f, a, b, h, y0)
n = floor((b-a)/h);
y1 = zeros(n+1,1); y2 = y1;
y1(1) = y0(1); y2(1) = y0(2);
for i=1:n-1
ti = a+(i-1)*h;
fvalue1 = f(ti,y1(i),y2(i));
k1 = h*fvalue1;
fvalue2 = f(ti+h/2,y1(i)+k1(1)/2,y2(i)+k1(2)/2);
k2 = h*fvalue2;
y1(i+1) = y1(i) + k2(1);
y2(i+1) = y2(i) + k2(2);
end
end
Your exact solution is wrong. It is possible that your differential equation is missing a minus sign.
y2'=(1+y2)/x has as its solution y2(x)=C*x-1 and as y1'=y2 then y1(x)=0.5*C*x^2-x+D.
If the sign in the y2 equation were flipped, y2'=-(1+y2)/x, one would get y2(x)=C/x-1 with integral y1(x)=C*log(x)-x+D, which contains the given exact solution.
0=y1(1) = -1+D ==> D=1
1=y1(2) = C*log(2)-1 == C=1/log(2)
Additionally, the arrays in the integration loop have length n+1, so that the loop has to be from i=1 to n. Else the last element remains zero, which gives wrong residuals for the second boundary condition.
Correcting that and enlarging the computation to one secant step finds the correct solution for the discretization, as the ODE is linear. The error to the exact solution is bounded by 0.000285, which is reasonable for a second order method with step size 0.05.
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.
power = 2;
sigma=0.1;
a = 1 /(sigma*sqrt(2*pi));
c= (sigma^2)*2;
syms x y
f = exp(-(x.^power)./c);
dfdx = diff(f,x);
c1 = diff(dfdx,x);
f = exp(-(y.^power)./c);
dfdy = diff(f,y);
c2 = diff(dfdy,y);
meancurvature = (c1 + c2)./ 2;
gaussiancuravture =(c1 .* c2);
mean_curv = integral2(meancurvature, -Inf,+Inf, -Inf, +Inf)
gauss_curv = integral2(gaussiancurvature, -Inf,+Inf, -Inf, +Inf)
I've tried everything in my limited matlab knowledge and google searching to find an answer to the error that comes up:
Error using integral2
First input argument must be a function handle.
You need pass in anonymous functions for the first argument. Create them using the # sign. For more details, check out these links
http://www.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html
Using integral2 in Matlab with vectors
I run this code in matlab to minimize the parameters of my function real_egarchpartial with fminsearch:
data = xlsread('return_cc_in.xlsx');
SPY = data(:,25);
dailyrange = xlsread('DR_in.xlsx');
drSPY= dailyrange(:,28);
startingVals = [mean(SPY); 0.041246; 0.70121; 0.05; 0.04; 0.45068; -0.1799; 1.0375; 0.06781; 0.070518];
T = size(SPY,1);
options = optimset('fminsearch');
options.Display = 'iter';
estimates = fminsearch(#real_egarchpartial, startingVals, options, SPY, drSPY);
[ll, lls, u]=real_egarchpartial(estimates, SPY, drSPY);
And I get this message:
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
I put the original starting values. So I assumed they are corrects. I used fminsearch and not fmincon because my function hasn't constraints and with fminunc my function gets a lot of red messages.
the real_egarchpartial function is the following:
function [ll,lls,lh] = real_egarchpartial(parameters, data, x_rk)
mu = parameters(1);
omega = parameters(2);
beta = parameters(3);
tau1 = parameters(4);
tau2 = parameters(5);
gamma = parameters(6);
csi = parameters(7);
phi = parameters(8);
delta1 = parameters(9);
delta2 = parameters(10);
%Data and h are T by 1 vectors
T = size(data,1);
eps = data-mu;
lh = zeros(T,1);
h = zeros(T,1);
u = zeros(T,1);
%Must use a back Cast to start the algorithm
h(1)=var(data);
lh(1) = log(h(1));
z= eps/sqrt(h(1));
u(1) = rand(1);
lxRK = log(x_rk);
for t = 2:T;
lh(t) = omega + beta*lh(t-1) + tau1*z(t-1) + tau2*((z(t-1).^2)-1)+ gamma*u(t-1);
h(t)=exp(lh(t));
z = eps/sqrt(h(t));
end
for t = 2:T
u(t)= lxRK(t) - csi - phi*h(t) - delta1*z(t) - delta2*((z(t).^2)-1);
end
lls = 0.5*(log(2*pi) + lh + eps.^2./h);
ll = sum(lls);
Could someone explain what is wrong? Is there another function more efficient for my estimation? Any help will be appreciated! Thank you.