Комбинирование решения и dsolve для решения систем уравнений с дифференциальными и алгебраическими уравнениями

Я пытаюсь решить системы уравнений, которые содержат как алгебраические, так и дифференциальные уравнения. Чтобы сделать это символически, мне нужно объединить dsolve и решить (не так ли?).

Рассмотрим следующий пример: у нас есть три основных уравнения

a == b + c; % algebraic equation
diff(b,1) == 1/C1*y(t); % differential equation 1
diff(c,1) == 1/C2*y(t); % differential equation 2

Решение обоих дифференциальных уравнений, исключение int (y, 0..t) и затем решение для c = f (C1, C2, a) дает

C1*b == C2*c   or   C1*(a-c) == C2*c
c = C1/(C1+C2) * a

Как я могу убедить Matlab дать мне такой результат? Вот что я пробовал:

syms a b c y C1 C2;
Eq1 = a == b + c; % algebraic equation
dEq1 = 'Db == 1/C1*y(t)'; % differential equation 1
dEq2 = 'Dc == 1/C2*y(t)'; % differential equation 2
[sol_dEq1, sol_dEq2]=dsolve(dEq1,dEq2,'b(0)==0','c(0)==0'); % this works, but no inclusion of algebraic equation
%[sol_dEq1, sol_dEq2]=dsolve(dEq1,dEq2,Eq1,'c'); % does not work
%solve(Eq1,dEq1,dEq2,'c') % does not work
%solve(Eq1,sol_dEq_C1,sol_dEq_C2,'c') % does not work

Никакая комбинация решения и / или dsolve с уравнениями или их решениями, которые я пробовал, не дает мне полезного результата. Любые идеи?


person JLo    schedule 17.07.2013    source источник


Ответы (1)


Теперь я предположил, что вы хотите, чтобы код был достаточно общим, поэтому я сделал его так, чтобы он мог работать с любым заданным числом уравнений и любым заданным числом переменных, и я не выполнял вычислений вручную.

Обратите внимание, что способ работы символической панели инструментов кардинально меняется из года в год, но, надеюсь, это сработает для вас. Теперь можно добавить уравнение Eq1 к списку входных данных dSolve, но с этим связаны две проблемы: во-первых, dSolve, кажется, предпочитает символьные входы, а во-вторых, dSolve, похоже, не понимает, что есть 3 независимых переменных a , b и c (он видит только 2 переменные, b и c).

Чтобы решить вторую проблему, я дифференцировал исходное уравнение, чтобы получить новое дифференциальное уравнение, с этим было три проблемы: первая - Matlab оценил производную a по t как 0, поэтому мне пришлось заменить a на a(t) и например, для b и c (я назвал a(t) длинной версией a). Вторая проблема заключалась в том, что Matlab использовал непоследовательную нотацию, вместо того, чтобы представлять производную от a как Da, она представляла ее как diff(a(t), t), поэтому мне пришлось заменить последнее на первое и тому подобное для b и c; это дало мне Da = Db + Dc. Последняя проблема заключается в том, что система сейчас недостаточно определена, поэтому мне пришлось получить начальные значения, здесь я мог бы решить для a(0), но Matlab, похоже, доволен использованием a(0) = b(0) + c(0).

Теперь вернемся к исходной первой проблеме, для решения которой мне пришлось преобразовать каждый символ обратно в char.

Вот код

function SolveExample
syms a b c y C1 C2 t;
Eq1 = sym('a = b + c'); 
dEq1 = 'Db = 1/C1*y(t)';
dEq2 = 'Dc = 1/C2*y(t)'; 
[dEq3, initEq3] = ...
  TurnEqIntoDEq(Eq1, [a b c], t, 0);

% In the most general case Eq1 will be an array
% and thus DEq3 will be one too
dEq3_char = SymArray2CharCell(dEq3);
initEq3_char = SymArray2CharCell(initEq3);

% Below is the same as 
% dsolve(dEq1, dEq2, 'Da = Db + Dc', ...
%   'b(0)=0','c(0)=0', 'a(0) = b(0) + c(0)', 't');
[sol_dEq1, sol_dEq2, sol_dEq3] = dsolve(...
  dEq1, dEq2, dEq3_char{:}, ...
  'b(0)=0','c(0)=0', initEq3_char{:}, 't')

end

function [D_Eq, initEq] = ...
  TurnEqIntoDEq(eq, depVars, indepVar, initialVal)
% Note that eq and depVars 
% may all be vectors or scalars
% and they need not be the same size.
% eq = equations
% depVars = dependent variables
% indepVar = independent variable
% initialVal = initial value of indepVar

depVarsLong = sym(zeros(size(depVars)));
for k = 1:numel(depVars)
  % Make the variables functions
  % eg. a becomes a(t)
  % This is so that diff(a, t) does not become 0
  depVarsLong(k) = sym([char(depVars(k)) '(' ...
    char(indepVar) ')']);
end

% Next make the equation in terms of these functions
eqLong = subs(eq, depVars, depVarsLong);

% Now find the ODE corresponding to the equation
D_EqLong = diff(eqLong, indepVar);

% Now replace all the long terms like 'diff(a(t), t)'
% with short terms like 'Da'
% otherwise dSolve will not work.
% First make the short variables 'Da'
D_depVarsShort = sym(zeros(size(depVars)));
for k = 1:numel(depVars)
  D_depVarsShort(k) = sym(['D' char(depVars(k))]);
end
% Next make the long names like 'diff(a(t), t)'
D_depVarsLong = diff(depVarsLong, indepVar);
% Finally replace
D_Eq = subs(D_EqLong, D_depVarsLong, D_depVarsShort);

% Finally determine the equation
% governing the initial values
initEq = subs(eqLong, indepVar, initialVal);
end

function cc = SymArray2CharCell(sa)
cc = cell(size(sa));
for k = 1:numel(sa)
  cc{k} = char(sa(k));
end

end

Некоторые мелкие примечания. Я изменил == на =, поскольку это, кажется, разница между нашими версиями Matlab. Также я добавил t в качестве независимой переменной в dsolve. Я также предположил, что вы знаете о ячейках, числах, линейных индексах и т. Д.

person Strategy Thinker    schedule 02.12.2013