以下是我使用MATLAB方法以数字方式解析FreeMat的ODE / backward Euler代码。但是,结果与我的教科书结果不一致,有时甚至是荒谬的不一致。代码有什么问题?
function [x,y] = backEuler(f,xinit,yinit,xfinal,h)
%f - this is your y prime
%xinit - initial X
%yinit - initial Y
%xfinal - final X
%h - step size
n = (xfinal-xinit)/h; %Calculate steps
%Inititialize arrays...
%The first elements take xinit and yinit corespondigly, the rest fill with 0s.
x = [xinit zeros(1,n)];
y = [yinit zeros(1,n)];
%Numeric routine
for i = 1:n
x(i+1) = x(i)+h;
ynew = y(i)+h*(f(x(i),y(i)));
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
end
答案 0 :(得分:5)
您的方法是一种新方法。它既不向后也不向前欧拉。 : - )
转发欧拉:y1 = y0 + h*f(x0,y0)
Backward Euler solve in y1: y1 - h*f(x1,y1) = y0
您的方法:y1 = y0 +h*f(x0,x0+h*f(x0,y0))
你的方法不向后欧拉。
您无法在y1
中解决,只需使用前向欧拉方法估算y1
。我不想继续对你的方法进行分析,但我相信它会表现得很差,甚至与前向欧拉相比,因为你在错误的点上评估函数f
。
这是我能想到的最接近你的方法的方法,也是明确的,它可以提供更好的结果。这是Heun's Method:
y1 = y0 + h/2*(f(x0,y0) + f(x1,x0+h*f(x0,y0)))
答案 1 :(得分:2)
我能发现的唯一问题是该行:
n=(xfinal-xinit)/h
应该是:
n = abs((xfinal-xinit)/h)
避免负步数。如果您正在负x方向移动,请确保为该功能提供负步长。
您的答案可能会因您接近答案的粗略程度而有所偏差。要获得半精确的结果,deltaX必须非常小,步长必须非常小。
PS。这不是“后向欧拉方法”,它只是常规的古老欧拉方法。
如果这是作业,请将其标记。
答案 2 :(得分:2)
查看numerical recipes,特别是第16章,常微分方程的积分。众所周知,欧拉的方法存在问题:
有几个原因导致Euler的方法不推荐用于实际应用,其中,(i)与其他更高级的方法相比,该方法不是很准确,并且(ii)也不是非常稳定
因此,除非您知道您的教科书使用的是欧拉方法,否则我不希望结果匹配。即使它是,您可能必须使用相同的步长才能获得相同的结果。
答案 3 :(得分:1)
除非你真的希望通过你自己编写的欧拉方法解决ODE,否则你应该看看built-in ODE solvers。
旁注:您不需要在循环中创建x(i)
,如下所示:x(i+1) = x(i)+h;
。相反,您只需编写x = xinit:h:xfinal;
即可。此外,您可能需要编写n = round(xfinal-xinit)/h);
以避免警告。
以下是MATLAB实现的解算器。
ode45基于显式 Runge-Kutta(4,5)配方, 多曼 - 普林斯对。这是一步到位 求解器 - 在计算y(tn)时,它需要 只有立即解决方案 前一个时间点,y(tn-1)。在 一般来说,ode45是最好的功能 适用于大多数人的第一次尝试 问题。
ode23是一个实现 显式Runge-Kutta(2,3)对 Bogacki和Shampine。它可能更多 比原油的ode45高效 公差和存在 适度僵硬。像ode45,ode23 是一步求解器。
ode113是一个变量订单 Adams-Bashforth-Moulton PECE求解器。 它可能比ode45更高效 严格的公差和ODE时 文件功能特别好 价格昂贵。 ode113是一个 多步求解器 - 它通常需要 几个前面的解决方案 计算当前的时间点 解。
以上算法旨在 解决非系统问题。如果他们出现 如果过慢,请尝试使用其中一个 下面僵硬的解决者。
ode15s是一个变量排序求解器 基于数值微分 公式(NDF)。可选地,它使用 向后分化公式 (BDF,也称为Gear的方法) 通常效率较低。喜欢 ode113,ode15s是一个多步求解器。 当ode45失败时尝试ode15s,或者是 非常低效,你怀疑 问题是僵硬的,还是在解决时 差分代数问题。
ode23s基于修改过的 Rosenbrock公式的顺序2.因为 它可能是一步求解器 比原油上的ode15更有效 公差。它可以解决某些问题 ode15s没有的僵硬问题 有效。
ode23t是一个实现 使用“自由”的梯形规则 插值。如果使用此解算器 问题只是适度僵硬和 你需要一个没有数字的解决方案 阻尼。 ode23t可以解决DAE问题。
ode23tb是一个实现 TR-BDF2,隐式Runge-Kutta 第一阶段的公式是a 梯形规则步骤和第二步 这是一个落后的阶段 二阶微分公式。 通过构造,相同的迭代 矩阵用于评估两者 阶段。像ode23s一样,这个解算器可能 比原油的ode15更有效率 公差。
答案 4 :(得分:0)
我认为这段代码可行。试试这个。
for i =1:n
t(i +1)=t(i )+dt;
y(i+1)=solve('y(i+1)=y(i)+dt*f(t(i+1),y(i+1)');
end
答案 5 :(得分:0)
代码很好。只需要在for循环中添加另一个循环。检查一致性水平。
if abs((y(i+1) - ynew)/ynew) > 0.0000000001
ynew = y(i+1);
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
我检查了一个虚函数,结果很有希望。