MATLAB ode45 спаренная матрица ODE - PullRequest
1 голос
/ 08 марта 2020

Я изучил два связанных матричных ODE для задачи линейного квадратичного c отслеживания в оптимальном управлении, которые приведены ниже: enter image description here

где

enter image description here

Я пытаюсь написать MATLAB, который решает дифференциальные уравнения одновременно. Вот что у меня есть:

function [dSdt dGdt] = mRiccati2(t, S, A, B, Q, R, G, r, h)
    k = 1+floor(t/h);
    S = reshape(S, size(A)); %Convert from "n^2"-by-1 to "n"-by-"n"
    dSdt = A'*S + S*A - S*B*inv(R)*B'*S + Q; %Determine derivative
    dGdt = -(A'- S*B*inv(R)*B')*G + Q*r(:,k);
    dSdt = dSdt(:); %Convert from "n"-by-"n" to "n^2"-by-1
end

И я пытаюсь вызвать функцию как

[T S G] = ode45(@(t, S, G)mRiccati2(t, S, A, B, Q, R, G, r, h), [0:h:Tfinal], S0, G0);

К сожалению, я получаю эту ошибку:

Not enough input arguments.

Error in HW5 (line 24)
[T S G] = ode45(@(t, S, G)mRiccati2(t, S, A, B, Q, R, G, r, h), [0:h:Tfinal], S0, G0);

Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 115)
  odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);

Error in HW5 (line 24)
[T S G] = ode45(@(t, S, G)mRiccati2(t, S, A, B, Q, R, G, r, h), [0:h:Tfinal], S0, G0);

Есть ли общий способ правильно решить ODE со связанной матрицей с ode45?

1 Ответ

0 голосов
/ 08 марта 2020

Matlab делает много мелких вещей, чтобы облегчить достижение хороших результатов, но он не интеллектуален. Вы должны адаптировать свою задачу к интерфейсам Matlab, автоматическое обнаружение c отсутствует. Поэтому функция, которую вы передаете ode45, должна потреблять плоский массив для состояния и возвращать один плоский массив для производных. Вы уже нашли ответ о том, как выполнить преобразование, вам нужно только выполнить его до конца.

function dXdt = mRiccati2(t, X, A, B, Q, R, r, h)
    k = 1+floor(t/h);
    n = size(A(1,:))
    X = reshape(X, [n+1,n]); %Convert from flat to matrix, first the rows of S, then G
    S = X(1:n,:);
    G = X(n+1,:);
    dSdt = A'*S + S*A - S*B*inv(R)*B'*S + Q; %Determine derivative
    dGdt = -(A'- S*B*inv(R)*B')*G + Q*r(:,k);
    dXdt = [ dSdt(:) dGdt(:) ]; %Convert from matrix objects to flat arrays
end

Затем, конечно, соответствующим образом вызовите интегратор, создавая исходные данные как плоский массив из исходного matrices

[T X] = ode45(@(t, X)mRiccati2(t, X, A, B, Q, R, r, h), [0:h:Tfinal], [S0(:) G0(:) ]);

Чтобы использовать результат, вам необходимо восстановить матрицы из строк X так же, как это делается в функции производных. Из него можно сделать явные вспомогательные функции.

...