Conmajia

Stop stealing sheep!

导航

< 20253 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

欧拉法求解微分方程

by Conmajia
2014
原文写于2014C# 完成现在改为JavaScript. 欧拉和中心差分逼近是最朴素的想法但代数精度太低而龙格库塔的稳定性又是个问题. 总之只能用来计算普通的东西高大上问题一般还是使用广义 αWilson-Θ 之类的利用系数调节人工阻尼让低频的部分少受算法影响高频阻尼增大增加微分方程的稳定性又不影响算法的精度.

当然现在大把的libapp你完全可以用pymtlb之类的搞定不需要搞懂任何原理.

Math.NET计划是用于.NET的数学运算库包括了数值计算库Iridium.NET非常经典且古老.

工程中有时候需要解微分方程比如这种

y=y2xy

y(0)=1. 两边积分得到

xnxn+1ydx=xnxn+1(y2xy)dxyn+1yn=xnxn+1(y2xy)dxy=1+2x

工程上一般不需要精确解求个数值就好通常采用差分近似代替微分最简单最朴素的办法是

(1)yn+1=yn+Δxf(xn,yn)n=0,1,2,

推导很简单xn

yn=f(xn,yn).

y(xn)

(2)ynyn+1ynΔx.

(2)的左边叫微商右边叫差商Δx=|xn+1xn|.

代回(2)

yn=f(xn,yn)yn+1ynΔxf(xn,yn)yn+1ynΔxf(xn,yn)yn+1y(xn)+Δxf(xn,yn).

于是(1)成了

(3)yn+1=yn+Δx(yn2xnyn).

myFn函数表示余项 yn2xnyn

function myFn(x, y) {
  return y - 2 * x / y;
}

Euler可以这样实现

function calculate(x0, y0, delta, xn) {
  var yn;
  while(x0 < xn) {
    yn = y0 + delta * myFn(x0, y0);
    y0 = yn;
    x0 = x0 + delta;
  }
  return yn;
}

现在可以开始试验. 理论上

y=1+2xy(1)=31.7321

3 是方程的精确解程序的目标是通过计算得到尽量接近精确解的结果.

x0=0y0=1Δx=0.1程序计算结果为

ans = 1.784771

误差 ε1=3.04%. 现在减小 Δx比如 Δx=0.0001计算结果为

ans = 1.732112

ε2=0.0007%比较接近真值了.

尽管这个方法可以求到比较精确的解但是 Δx 太小的话显然while会执行很多次 Nwhile\prop1Δx效率低下.

引入定积分的梯形公式

xnxn+1f(x,y)dxΔx2[f(xn,yn)+f(xn+1,yn+1)]

(3)可以写成

(4)yn+1yn+Δx2[f(xn,yn)+f(xn+1,yn+1)].

(3)(4)的特点是前者速度快精度低后者速度慢精度高. 所以对于粗算可以使用

yn+1=yn+Δxf(xn,yn)

精算可以用

yn+1=yn+Δx2[f(xn,yn)+f(xn+1,yn+1)].

结合起来先通过粗算得到 yn+1 的近似值再进行精算得到高精度的最终解. 这是一个比较均衡的折衷既保证了计算结果的准确度又保证了计算效率. 下面是改进后的代码

function calculate(x0, y0, delta, xn) {
  var yp, yc;
  while(x0 < xn) {
    yp = y0 + delta * myFn(x0, y0);
    yc = y0 + delta * myFn(x0 + delta, yp);
    y0 = 1 / 2 * (yp + yc);
    x0 = x0 + delta;
  }
  return y0;
}

x0=0y0=1Δx=0.1

ans = 1.737867

ε3=0.33%.

ε1 相比Δx 相同——意味着执行时间相近——的情况下精度提高了10倍.

手工求微分方程基本是这么个思路. 当然更多的时候做个伸手党其实很不错的大把的现成玩意儿可以用我干嘛还要费那劲呢

The End.

posted on2019-02-21   Conmajia  阅读(6654)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2018-02-21 命令行程序增加 GUI 外壳
2018-02-21 🖥️ 自制虚拟机 - 概念和汇编器
2017-02-21 字符型液晶屏模拟控件(En)
点击右上角即可分享
微信分享提示