Несколько ошибок
В Opt_query
изменить это
[t,y] = ode45(@ODE_set,[0, 130],y0,k1,k2,k3);
к этому
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
После tspan = [0,30]
вы должны использовать только начальные условия, выполните
не включает k1, k2, k3
- Просто возьмите функцию
ODE_set
, которая имеет 5 inputs t,y, k1, k2, k3
создайте новый с двумя входами t , y
, тогда k1, k2, k3
сохранится
в качестве фиксированных входов
new_ODE_set = @(t, y)ODE_set(t, y, k1, k2, k3)
[t,y] = ode45(odefun,tspan,y0)
odefun
является функцией только t, y
Поскольку new_ODE_set
является функцией t, y
, ее также можно использовать как
odefun
но на самом деле у нас все еще есть k1, k2, k3
внутри
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
Здесь вы должны инициализировать Z
до нуля перед запуском цикла, как
это
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
В ODE_set
вы используете только индекс 1
для dydt
Изменить это
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(1) = F/V*(B) - k2*B^2;
dydt(1) = F/V*(C) - k3*C^2;
к этому
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
Подводя итог
global k1 k2 k3
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
gs = GlobalSearch;
problem = createOptimProblem('fmincon','objective',...
@Opt_query,'x0',x0,'lb',lb,'ub',lu);
[x,fval,exitflag,output] = run(gs,problem);
disp(k1)
disp(k2)
disp(k3)
function dydt = ODE_set(t, y, k1, k2, k3)
F = 20.1;
A_in = 2.5;
V = 100;
k = 0.150;
A = y(1);
B = y(2);
C = y(3);
n = numel(y);
dydt = zeros(n,1);
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
end
function q = Opt_query(p)
global k1 k2 k3
k1 = p(1);
k2 = p(2);
k3 = p(3);
y0=[1 2 3];
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
t_steps=0:5:130;
y_steps=interp1(t,y,t_steps);
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
q = sqrt(Z);
end