我有一个(一阶)ODE系统,计算衍生工具相当昂贵。
然而,导数可以在给定的误差范围内以相当低的成本计算,或者因为导数是从收敛级数计算的,并且边界可以放在丢弃项的最大贡献上,或者通过使用存储的预计算范围信息。 kd-tree / octree查找表。
不幸的是,我无法找到任何可以从中受益的一般ODE解算器;他们似乎只是给你坐标,并希望得到一个确切的结果。 (请注意,我不是ODE的专家;我熟悉Runge-Kutta,数字解析书中的材料,LSODE和Gnu科学图书馆的求解器。)
即对于我见过的所有解算器,您提供derivs
回调函数,接受t
和x
数组,并返回dx/dt
数组背部;但理想情况下,我正在寻找一个提供回调t
,x
s,和一系列可接受错误,并接收dx/dt_min
和{{1数组返回,导数范围保证在所需的精度范围内。 (可能有许多同样有用的变体)。
任何针对此类设计的解决方案的指针,或问题的替代方法(我不能相信我是第一个想要这样的人)将不胜感激。
答案 0 :(得分:1)
粗略地说,如果你知道f'达到绝对误差eps,并从x0积分到x1,那么来自导数误差的积分误差将是&lt; = eps *(x1-x0) 。您的ODE解算器也会出现离散化错误。考虑一下eps *(x1 - x0)有多大,并为ODE求解器提供f'值,计算误差<= eps。
答案 1 :(得分:1)
我不确定这是一个很好的问题。
在许多算法中,例如,非线性方程求解,f(x)= 0,导数f'(x)的估计就是在牛顿方法中使用所需的全部因为你只需要进入答案的“大方向”。
然而,在这种情况下,导数是你正在解决的(ODE)方程的主要部分 - 得到导数错误,你只会得到错误的答案;这就像尝试用f(x)的近似值来求解f(x)= 0。
正如另一个答案所示,如果你将ODE设置为应用f(x)+ g(x),其中g(x)是一个错误术语,你应该能够将你的衍生物中的错误与你的错误联系起来。输入。
答案 2 :(得分:1)
在考虑了这个之后,我想到间隔算术可能是关键。我的derivs
函数基本上返回间隔。使用区间运算的积分器将x维持为间隔。我感兴趣的是在最终x
的{{1}} s上获得足够小的误差限制。一种显而易见的方法是迭代地重新整合,提高样本的质量,每次迭代引入最大的误差,直到我们最终获得具有可接受范围的结果(尽管听起来它可能是“治愈比疾病更糟糕”)总体效率)。我怀疑自适应步长控制可以很好地适应这种方案,选择步长以保持“隐式”离散误差与“显式误差”即间隔范围相当。
无论如何,谷歌搜索“颂歌解算器间隔算术”或只是“间隔颂歌”会出现一堆有趣的新的和相关的东西(VNODE及其特别引用)。
答案 3 :(得分:1)
如果你有一个僵硬的系统,你将使用某种形式的隐式方法,在这种情况下,导数只在牛顿迭代中使用。使用近似雅可比矩阵将使您在牛顿迭代中花费严格的二次收敛,但这通常是可以接受的。或者(大多数情况下,如果系统很大)你可以使用一个无Jacobian的Newton-Krylov方法来解决阶段,在这种情况下,你的近似Jacobian变成了一个预处理器,你在牛顿迭代中保留了二次收敛。
答案 4 :(得分:0)
您是否考虑过使用odeset?它允许您为ODE求解器设置选项,然后将选项结构作为第四个参数传递给您调用的任何求解器。错误控制属性(RelTol,AbsTol,NormControl)可能是您最感兴趣的。不确定这是否真的是你需要的那种帮助,但这是我能想到的最好的建议,几年前最后一次使用MATLAB ODE功能。
此外:对于用户定义的导数函数,您是否可以将公差编码到衍生函数的计算中,或者您是否真的需要从求解器传递误差限制?
答案 5 :(得分:0)
不确定我做出了多少贡献,但在制药模型领域,我们使用LSODE,DVERK和DGPADM。 DVERK是一个很好的快速简单订单5/6龙格 - 库塔解算器。 DGPADM是一个很好的矩阵指数求解器。如果你的ODE是线性的,那么矩阵指数是最好的。但是你的问题有点不同。
顺便说一下,T论证只是为了普遍性。我从未见过依赖T的实际系统。你可能正在进入新的理论领域。祝你好运!
补充:如果你正在进行轨道模拟,在我看来,我听说过基于圆锥曲线的特殊方法。
答案 6 :(得分:0)
检查具有线性基函数和中点正交的有限元方法。解决以下ODE只需要对每个元素的f(x),k(x)和b(x)进行一次评估:
-k(x)u''(x)+ b(x)u'(x)= f(x)
答案的逐点误差与评估中的误差成正比。
如果您需要更平滑的结果,您可以使用二次基函数,每个元素对上述每个函数进行2次评估。