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

news2024/12/27 13:25:14

任务

在这里插入图片描述

  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小于给定控制精度时停止计算.
注:下面代码中数组下标从0开始.

代码

C++实现Romberg积分运算

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

int satisfiedCount;

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

int main() 
{
    long double eps = 1e-6, proportion;
    int maxIter;

    satisfiedCount = 0;
    maxIter = 4;
    cout << "maxIter = " << maxIter << endl;
    for (long double t = 0.1; t <= 10; t += 0.1) 
    { 
        long double vx = romberg(ax, 0, t, eps, maxIter, 0);
        long double vy = romberg(ay, 0, t, eps, maxIter, 0);
        long double x = romberg([&](long double t) { return vx; }, 0, t, eps, maxIter, 1);
        long double y = romberg([&](long double t) { return vy; }, 0, t, eps, maxIter, 0);
        cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << vx << ", vy = " << setprecision(6) << vy << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;
    }
    proportion = (long double)satisfiedCount / 100;
    cout << "At maxIter = " << maxIter << ", proportion of times the error requirement of x was satisfied: " << proportion << endl;

    satisfiedCount = 0;
    maxIter = 8;
    cout << "maxIter = " << maxIter << endl;
    ofstream outFile("trajectory.txt");
    for (long double t = 0.1; t <= 10; t += 0.1) 
    {
        long double vx = romberg(ax, 0, t, eps, maxIter, 0);
        long double vy = romberg(ay, 0, t, eps, maxIter, 0);
        long double x = romberg([&](long double t) { return vx; }, 0, t, eps, maxIter, 1);
        long double y = romberg([&](long double t) { return vy; }, 0, t, eps, maxIter, 0);
        cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << vx << ", vy = " << setprecision(6) << vy << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;
        outFile << fixed << setprecision(6) << x << " " << y << "\n";//把坐标写入文件,方便画轨迹
    }
    proportion = (long double)satisfiedCount / 100;
    cout << "At maxIter = " << maxIter << ", proportion of times the error requirement of x was satisfied: " << proportion << endl;

    satisfiedCount = 0;
    maxIter = 12;
    cout << "maxIter = " << maxIter << endl;
    for (long double t = 0.1; t <= 10; t += 0.1) 
    {
        long double vx = romberg(ax, 0, t, eps, maxIter, 0);
        long double vy = romberg(ay, 0, t, eps, maxIter, 0);
        long double x = romberg([&](long double t) { return vx; }, 0, t, eps, maxIter, 1);
        long double y = romberg([&](long double t) { return vy; }, 0, t, eps, maxIter, 0);
        cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << vx << ", vy = " << setprecision(6) << vy << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;
    }
    proportion = (long double)satisfiedCount / 100;
    cout << "At maxIter = " << maxIter << ", proportion of times the error requirement of x was satisfied: " << proportion << endl;

    satisfiedCount = 0;
    maxIter = 16;
    cout << "maxIter = " << maxIter << endl;
    for (long double t = 0.1; t <= 10; t += 0.1) 
    {
        long double vx = romberg(ax, 0, t, eps, maxIter, 0);
        long double vy = romberg(ay, 0, t, eps, maxIter, 0);
        long double x = romberg([&](long double t) { return vx; }, 0, t, eps, maxIter, 1);
        long double y = romberg([&](long double t) { return vy; }, 0, t, eps, maxIter, 0);
        cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << vx << ", vy = " << setprecision(6) << vy << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;
    }
    proportion = (long double)satisfiedCount / 100;
    cout << "At maxIter = " << maxIter << ", proportion of times the error requirement of x was satisfied: " << proportion << endl;

    satisfiedCount = 0;
    maxIter = 20;
    cout << "maxIter = " << maxIter << endl;
    for (long double t = 0.1; t < 10.1; t += 0.1) 
    {
        long double vx = romberg(ax, 0, t, eps, maxIter, 0);
        long double vy = romberg(ay, 0, t, eps, maxIter, 0);
        long double x = romberg([&](long double t) { return vx; }, 0, t, eps, maxIter, 1);
        long double y = romberg([&](long double t) { return vy; }, 0, t, eps, maxIter, 0);
        cout << fixed << setprecision(1) << "At t = " << t << ", vx = " << setprecision(6) << vx << ", vy = " << setprecision(6) << vy << ", " << "(x, y) = (" << setprecision(6) << x << ", " << setprecision(6) << y << ")" << endl;
    }
    proportion = (long double)satisfiedCount / 100;
    cout << "At maxIter = " << maxIter << ", proportion of times the error requirement of x 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);
}

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

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

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

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

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()

结果

部分运算结果

在这里插入图片描述

轨迹可视化结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1657303.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

去除视频背景音乐或人物声音的4种方法,建议收藏

你是否曾想移除视频中令人分心的声音呢&#xff1f;对于需要裁剪声音或去除背景噪音的视频来说&#xff0c;消音是一种非常有用的技能。那么&#xff0c;视频怎么消除声音&#xff1f;看看下文就知道了。 方法一&#xff1a;使用 智优影 去除视频中的音频 在线转换工具不仅支持…

Python轻量级Web框架Flask(13)—— Flask个人博客项目

0、前言: ★这部分内容是基于之前Flask学习内容的一个实战项目梳理内容,没有可以直接抄下来跑的代码,是学习了之前Flask基础知识之后,再来看这部分内容,就会对Flask项目开发流程有更清楚的认知,对一些开发细节可以进一步的学习。项目功能,通过Flask制作个人博客。项目架…

又一个限时免费生成图片的AI平台

网址 https://jimeng.jianying.com/ai-tool/image/generate 抖音官方的文升图&#xff0c;用抖音登录就可以&#xff0c;每天送60积分&#xff0c;目前看文生图好像是限时免费。 随手试了一下&#xff0c;速度很快&#xff0c;质量也还可以&#xff0c;背靠大厂&#xff0c;…

福建 | 福建铭发用行动诠释“敢为天下先”的泉州精神

福建铭发 泉州TOP级企业 在福建&#xff0c;提到混凝土搅拌站&#xff0c;铭发是绕不开的一个存在。 他们是当地最早一批建成的商砼企业&#xff0c;也是如今发展规模最大的TOP级企业。 从2007年建站至今&#xff0c;近15年的发展&#xff0c;他们形成了一套铭发特色的企业经…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

WPF之改变任务栏图标及预览

1&#xff0c;略缩图添加略缩按钮。 <Window.TaskbarItemInfo><TaskbarItemInfo x:Name"taskInfo" ProgressState"None" ProgressValue"0.6" ><TaskbarItemInfo.ThumbButtonInfos><ThumbButtonInfo x:Name"btiPlay&q…

分享10个高质量宝藏网站~

分享一波高质量宝藏网站~ 这10个宝藏网站&#xff0c;个个都好用到爆&#xff0c;娱乐、办公、学习都能在这里找到&#xff01; 1、Z-Library https://zh.zlibrary-be.se/ 世界最大的免费电子书下载网站&#xff01;电子书资源超千万&#xff0c;不过这个网站不太稳定&#…

[Kubernetes] KubeKey 部署 K8s v1.28.8

文章目录 1.K8s 部署方式2.操作系统基础配置3.安装部署 K8s4.验证 K8s 集群5.部署测试资源 1.K8s 部署方式 kubeadm: kubekey, sealos, kubespray二进制: kubeaszrancher 2.操作系统基础配置 主机名内网IP外网IPmaster192.168.66.2139.198.9.7node1192.168.66.3139.198.40.17…

Java_File

介绍&#xff1a; File对象表示路径&#xff0c;可以是文件&#xff0c;也可以是文件夹。这个路径可以是存在的&#xff0c;也可以是不存在的&#xff0c;带盘符的路径是绝对路径&#xff0c;不带盘符的路径是相对路径&#xff0c;相对路径默认到当前项目下去找 构造方法&…

MGRE 实验

需求&#xff1a;1、R2为ISP&#xff0c;其上只能配置IP地址。 2、R1-R2之间为HDLC封装 3、R2-R3之间为ppp封装&#xff0c;pap认证&#xff0c;R2为主认证方。 4、R2-R4之间为ppp封装&#xff0c;chap认证&#xff0c;R2为主认证方。 5、R1、R2、R3构建MGRE环境&#xff0…

汽车之家,如何在“以旧换新”浪潮中大展拳脚?

北京车展刚刚落幕&#xff0c;两重利好正主导汽车市场持续升温&#xff1a;新能源渗透率首破50%&#xff0c;以及以旧换新详细政策进入落地期。 图源&#xff1a;中国政府网 在政策的有力指引下&#xff0c;汽车产业链的各个环节正经历着一场深刻的“连锁反应”。在以旧换新的…

STM32——GPIO输出(点亮第一个LED灯)

代码示例&#xff1a; #include "stm32f10x.h" // Device headerint main() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitSt…

【JAVA基础之Stream流】掌握Stream流

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 目录 1.Stream流 1.1 概述 2.2 常见方法 2.2.1 实现步骤 2.2.2 获取Stream的方式 2.2.3 中间方法 2.2.4 终结方法 1.Stream流 1.1 概述 Stream流可以让你通过链…

Spring AOP(2)

目录 Spring AOP详解 PointCut 切面优先级Order 切点表达式 execution表达式 切点表达式示例 annotation 自定义注解MyAspect 切面类 添加自定义注解 Spring AOP详解 PointCut 上面代码存在一个问题, 就是对于excution(* com.example.demo.controller.*.*(..))的大量重…

Cmake编译源代码生成库文件以及使用

在项目实战中&#xff0c;通过模块化设计能够使整个工程更加简洁明了。简单的示例如下&#xff1a; 1、项目结构 project_folder/├── CMakeLists.txt├── src/│ ├── my_library.cpp│ └── my_library.h└── app/└── main.cpp2、CMakeList文件 # CMake …

[机器学习系列]深入探索回归决策树:从参数选择到模型可视化

目录 一、回归决策树的参数 二、准备数据 三、构建回归决策树 (一)拟合模型 (二)预测数据 (三)查看特征重要性 (四)查看模型拟合效果 (五) 可视化回归决策树真实值和预测值 (六)可视化决策树并保存 部分结果如下&#xff1a; 一、回归决策树的参数 DecisionTreeRegress…

基于springboot+mybatis+vue的项目实战之增删改查CRUD

目录结构 PeotController.java package com.example.controller;import com.example.pojo.Peot; import com.example.pojo.Result; import com.example.service.PeotService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web…

分布式锁讲解

概括 分布式锁是一种用于在分布式系统中实现同步机制的锁。在单机系统中&#xff0c;我们可以使用如Java中的synchronized关键字或者 ReentrantLock来实现线程间的同步&#xff0c;但在分布式系统中&#xff0c;由于多个节点&#xff08;服务器&#xff09;之间的并发操作&am…

谷歌CEO最新访谈:AI浪潮仍处于早期阶段,公司未来最大威胁是执行力不足

作为搜索领域无可争议的霸主&#xff0c;谷歌改变了我们生活的方方面面&#xff0c;从日常琐事到工作事务&#xff0c;再到我们的沟通方式。多年来&#xff0c;谷歌一直是互联网的窗口&#xff0c;为我们提供大量知识和信息&#xff0c;但如今&#xff0c;随着其他类似平台的崛…

融知财经:期货交易的规则和操作方法

期货交易是指在未来的某一特定时期&#xff0c;买卖双方通过签订合约的方式&#xff0c;约定以某种价格买卖一定数量的某种商品或资产的行为。期货交易的规则和操作方法如下&#xff1a; 期货交易的规则和操作方法 1、双向交易&#xff1a; 期货市场允许投资者进行多头&#xf…