计算方法实验9:Romberg积分求解速度、位移

30 篇文章 1 订阅
10 篇文章 0 订阅

任务

在这里插入图片描述

  1. 输出质点的轨迹 ( x ( t ) , y ( t ) ) , t ∈ { 0.1 , 0.2 , 0.3 , . . . , 10 } (x(t), y(t)), t\in \{0.1, 0.2, 0.3, ..., 10\} (x(t),y(t)),t{0.1,0.2,0.3,...,10},并在二维平面中画出该轨迹.
  2. 请比较M分别取4, 8, 12, 16, 20 时,Romberg积分达到要求精度的比例(达到误差要求的次数/调用总次数),分析该比例随M 的变化。

算法

现在要用数值方法求 ∫ a b f ( x )   d x \int_{a}^{b} f(x) \, dx abf(x)dx,设 h = b − a n h=\frac{b-a}{n} h=nba,已知:

复化梯形积分 T n ( f ) = h [ 1 2 f ( a ) + ∑ i = 1 n − 1 f ( a + i h ) + 1 2 f ( b ) ] T_{n}\left(f\right)=h\left[\frac{1}{2}f\left(a\right)+\sum_{i=1}^{n-1}f\left(a+ih\right)+\frac{1}{2}f\left(b\right)\right] Tn(f)=h[21f(a)+i=1n1f(a+ih)+21f(b)]

复化Simpson积分 S n ( f ) = h 3 [ f ( a ) + 4 ∑ i = 0 m − 1 f ( x 2 i + 1 ) + 2 ∑ i = 1 m − 1 f ( x 2 i ) + f ( b ) ] S_{n}\left(f\right)=\frac{h}{3}\left[f\left(a\right)+4\sum_{i=0}^{m-1}f\left(x_{2i+1}\right)+2\sum_{i=1}^{m-1}f\left(x_{2i}\right)+f\left(b\right)\right] Sn(f)=3h[f(a)+4i=0m1f(x2i+1)+2i=1m1f(x2i)+f(b)].

( T n ( f ) − T 2 n ( f ) ) ( T_n( f) - T_{2n}( f) ) (Tn(f)T2n(f)) 作 为 T 2 n ( f ) T_{2n}(f) T2n(f)的修正值补充到 I ( f ) I(f) I(f),即
I ( f ) ≈ T 2 n ( f ) + 1 3 ( T 2 n ( f ) − T n ( f ) ) = 4 3 T 2 n − 1 3 T n = S n I(f)\approx T_{2n}(f)+\frac{1}{3}\left(T_{2n}\left(f\right)-T_{n}\left(f\right)\right)=\frac{4}{3}T_{2n}-\frac{1}{3}T_{n}=S_{n} I(f)T2n(f)+31(T2n(f)Tn(f))=34T2n31Tn=Sn

其结果是将复化梯形求积公式组合成复化 Simpson 求积公式, 截断误差由 O ( h 2 ) O(h^2) O(h2)提高到 O ( h 4 ) O(h^4) O(h4),这种手段称为外推算法,该算法在不增加计算量的前提下提高了误差的精度.不妨对 S 2 n ( f ) , S n ( f ) S_{2n}(f),S_n(f) S2n(f),Sn(f)再作一次线性组合:

I ( f ) − S n ( f ) = − f ( 4 ) ( ξ ) 180 h 4 ( b − a ) ≈ d h 4 I\left(f\right)-S_{n}\left(f\right)=-\frac{f^{\left(4\right)}\left(\xi\right)}{180}h^{4}\left(b-a\right)\approx dh^{4} I(f)Sn(f)=180f(4)(ξ)h4(ba)dh4
I ( f ) − S 2 n ( f ) = − f ( 4 ) ( η ) 180 ( h 2 ) 4 ( b − a ) ≈ d ( h 2 ) 4 I(f)-S_{2n}(f)=-\frac{f^{(4)}(\eta)}{180}\left(\frac{h}{2}\right)^{4}(b-a)\approx d\left(\frac{h}{2}\right)^{4} I(f)S2n(f)=180f(4)(η)(2h)4(ba)d(2h)4

I ( f ) ≈ S 2 n ( f ) + 1 15 ( S 2 n ( f ) − S n ( f ) ) = C n ( f ) I\left(f\right)\approx S_{2n}\left(f\right)+\frac{1}{15}\left(S_{2n}\left(f\right)-S_{n}\left(f\right)\right)=C_{n}\left(f\right) I(f)S2n(f)+151(S2n(f)Sn(f))=Cn(f)
复化 Simpson 公式组成复化 Cotes 公式,其截断误差是 O ( h 6 ) . O(h^6). O(h6).同理对 Cotes公式进行线性组合:
I ( f ) − C 2 n ( f ) = e ( h 2 ) 6 I ( f ) − C n ( f ) = e h 6 I\left(f\right)-C_{2n}\left(f\right)=e\left(\frac{h}{2}\right)^{6}\\I\left(f\right)-C_{n}\left(f\right)=eh^{6} I(f)C2n(f)=e(2h)6I(f)Cn(f)=eh6
得到具有 7 次代数精度和截断误差是 O ( h 8 ) O(h^8) O(h8)的 Romberg 公式:
R n ( f ) = C 2 n ( f ) + 1 63 ( C 2 n ( f ) − C n ( f ) ) R_{n}\left(f\right)=C_{2n}\left(f\right)+\frac{1}{63}\left(C_{2n}\left(f\right)-C_{n}\left(f\right)\right) Rn(f)=C2n(f)+631(C2n(f)Cn(f))

为了便于在计算机上实现 Romberg 算法,将 T n , S n , C n , R n , ⋯ T_n,S_n,C_n,R_n,\cdots Tn,Sn,Cn,Rn,统一用 R k , j R_{k,j} Rk,j 表示,列标 j = 1 , 2 , 3 , 4 j=1,2,3,4 j=1,2,3,4分别表示梯形、Simpson、Cotes 、Romberg积分,行标 k k k表示步长 h k = h 2 k − 1 h_k=\frac h{2^{k-1}} hk=2k1h,得到Romberg 计算公式:
R k , j = R k , j − 1 + R k , j − 1 − R k − 1 , j − 1 4 j − 1 − 1 , k = 2 , 3 , ⋯ R_{k,j}=R_{k,j-1}+\frac{R_{k,j-1}-R_{k-1,j-1}}{4^{j-1}-1},k=2,3,\cdots Rk,j=Rk,j1+4j11Rk,j1Rk1,j1,k=2,3,
对每一个 k , j k,j k,j从 2 做到 k k k,一直做到 ∣ R k , k − R k − 1 , k − 1 ∣ |R_k,k-R_{k-1,k-1}| Rk,kRk1,k1小于给定控制精度时停止计算.

代码

C++实现Romberg积分运算

#include<bits/stdc++.h>
using namespace std;

int satisfiedCount;
int M;
long double eps = 1e-6, proportion;
vector<long double> Vx(100), Vy(100);

long double ax(long double t);
long double ay(long double t);
long double vx(long double t);
long double vy(long double t);
long double romberg(function<long double(long double)> f, long double a, long double b, long double eps, int M, bool isX);// Perform the Romberg integration

int main() 
{
    for (M = 4; M <= 20; M += 4)
    {
        satisfiedCount = 0; 
        cout << "M = " << M << endl;
        ofstream outFile("trajectory.txt", ios::app);
        for (long double t = 0.1; t < 10.1; t += 0.1) 
        { 
            long double v_x = vx(t);
            long double v_y = vy(t);
            long double x = romberg(vx, 0.0, t, eps, M, 1);
            long double y = romberg(vy, 0.0, t, eps, M, 1);
            cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << v_x << ", vy = " << setprecision(6) << v_y << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;

            if (M == 8)
                outFile << fixed << setprecision(6) << x << " " << y << "\n";
        }
        long double proportion = (long double)satisfiedCount / 200;
        cout << "At M = " << M << ", proportion of times the error requirement of (x,y) was satisfied: " << proportion << endl;
    }
    return 0;
}

long double ax(long double t) 
{
    return sin(t) / (1 + sqrt(t));
}

long double ay(long double t) 
{
    return log(t + 1) / (t + 1);
}

long double vx(long double t) 
{
    return romberg(ax, 0.0, t, eps, M, 0);
}

long double vy(long double t) 
{
    return romberg(ay, 0.0, t, eps, M, 0);
}

// Perform the Romberg integration
long double romberg(function<long double(long double)> f, long double a, long double b, long double eps, int M, bool isX) {
    long double h[M+1], r[M+1][M+1];
    h[1] = b - a;
    r[1][1] = 0.5 * h[1] * (f(a) + f(b));

    for (int k = 2; k <= M; k++) 
    {
        h[k] = 0.5 * h[k-1];
        long double sum = 0;
        for (int i = 1; i <= pow(2, k-2); i++)
            sum += f(a + (2*i-1) * h[k]);
        r[k][1] = 0.5 * (r[k-1][1] + h[k-1] * sum);

        for (int j = 2; j <= k; j++)
            r[k][j] = r[k][j-1] + (r[k][j-1] - r[k-1][j-1]) / (pow(4, j-1) - 1);

        if (k > 2 && fabs(r[k][k] - r[k-1][k-1]) < eps)
        {
            if(isX)
                satisfiedCount++;
            return r[k][k];
        }
    }
    return r[M][M];
}

python可视化运动轨迹

import matplotlib.pyplot as plt

with open('trajectory.txt', 'r') as file:
    lines = file.readlines()

x, y = zip(*[(float(line.split()[0]), float(line.split()[1])) for line in lines])

plt.plot(x, y, 'o-')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Plot of points with smooth curve')
plt.show()

结果

部分运算结果

在这里插入图片描述

轨迹可视化结果

在这里插入图片描述

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里澄江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值