Используя тета-метод, показанный на рисунке ниже

(https://i.stack.imgur.com/MJx0d.png)

Для тета в [0.1].

Я пытаюсь решить некоторые ODE, видимые в коде

`

function [tnodes,y] = theta_method(f, t_interval, N, y0, theta)

global glob_h glob_yold glob_tnew glob_f glob_theta;

y= y0;
yold= y0(:); %initial conditions
t0 = t_interval(1);
tN = t_interval(2);

tnodes = linspace(t0, tN, N+1); %the nodes of the partition

glob_h = (tN- t0)/N; %mesh-size
glob_f = f;
glob_theta=theta;
for tnew = tnodes(2:end)
  glob_tnew = tnew;
  glob_yold = yold;
  ynew = fsolve(@(x)F(x), yold);
  y =[y; ynew.'];
  yold = ynew;
end
endfunction

function rhs = F(x)

  global glob_h glob_yold glob_tnew glob_f glob_theta;

  rhs = x - glob_h*glob_theta*feval(glob_f, glob_tnew, x)-glob_h*(1.0 - glob_theta)*feval(glob_f, t0, glob_yold) - glob_yold;

Endfunction

`

И сюжет:

`

PLOT
hold off
N=20;
t_interval = [0 1];
y0 = 1;
theta = 0.5;
[t,y]=theta_method(@model_f, t_interval, N, y0, theta)
uexact = model_exact(t)
plot(t,y,'linewidth', 1, 'g*'); % plot approx vs t
hold on
plot(t,uexact,'linewidth', 1, 'r'); % plot exact solution vs t
legend('BE approx','exact solution')
title('Solution of y''=\lambda y')
xlabel('time')

MODEL EXACT
function rhs = model_exact(t)
  lambda = -1;
  rhs = exp(lambda*t);
endfunction
MODEL F

function rhs = model_f(t,y)
  lambda = -1;
  rhs = lambda*y;
endfunction

`

Программа говорит, что ошибка `

error: 't0' undefined near line 28, column 99
error: called from
    theta_method>F at line 28 column 7
    theta_method>@<anonymous> at line 18 column 21
    fsolve at line 246 column 8
    theta_method at line 18 column 8
    a at line 6 column 6

`

Но я не могу понять, почему что-то не так. Я определил t0 и думаю, что синтаксической ошибки нет.

0
lebong66 16 Ноя 2022 в 18:09
t0 по-прежнему не существует в контексте или области действия функции F, как указано в сообщении об ошибке.
 – 
Lutz Lehmann
16 Ноя 2022 в 19:01
Как мне это исправить?
 – 
lebong66
16 Ноя 2022 в 19:10
Я уже говорил вам в предыдущем воплощении вопроса, замените t0 на glob_told и включите это в глобальные переменные, установите его правильное значение во временном цикле. Было бы проще, если бы сопрограмма/лямбда-выражение/анонимная функция, которая объявляется во временном цикле, собирала сначала все константные выражения, чтобы только переменная точка запускала вычисления.
 – 
Lutz Lehmann
16 Ноя 2022 в 19:18

1 ответ

Лучший ответ

Было бы проще избежать необходимости использования глобальных переменных.

told = tnodes(1)
for tnew = tnodes(2:end)
  fold = f(told,yold);
  yhalf = yold+(1-theta)*h*fold;
  F = @(x) yhalf+theta*h*f(tnew,x)-x;
  ynew = fsolve(F, yold+h*fold);
  y =[y; ynew.'];
  told = tnew;
  yold = ynew;
end

Было бы целесообразно масштабировать допуски ошибок fsolve с помощью h или h^2.

См. модель SIR с использованием fsolve и Euler 3BDF для аналогичная конструкция для другого неявного метода. Другой метод с установкой параметров допусков ошибок, Код Matlab для $y_{n+2} - y_n = h\left[(1/3)f_{n+2} + (4/3)f_{n+1 } + (1/3)f_n\right]$

0
Lutz Lehmann 16 Ноя 2022 в 19:36