数值分析与算法设计--实验报告1

姜智浩 Lv5

一、实验名称

了解计算方法思想

二 实验目的

  1. 了解误差分析的重要性;
  2. 考察误差在数值计算中的传播情况, 掌握算法稳定性的重要性;
  3. 学会在数值计算中避免误差伤害, 了解设计算法时应遵循的原则.

三、实验题目

3.1 题目1

分别利用正向递推与反向递推计算

给出python语言程序 并比较计算得到的数值结果(保留4位小数)

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
import numpy as np

e_inv = 1 / np.exp(1)

I0_forward = 0.6321 # 选用1 - 1/e效果会好点
I9_backward = (e_inv + 1) / 20

# 正向递推
I_forward = [0.0] * 11
I_forward[0] = I0_forward
for n in range(1, 11):
I_forward[n] = 1 - n * I_forward[n-1]

# 反向递推
I_backward = [0.0] * 11
I_backward[9] = I9_backward

for n in range(9, 0, -1):
I_backward[n-1] = (1 - I_backward[n]) / n

for n in range(1, 11):
I_backward[n] = 1 - n * I_backward[n-1]

print("n\t正向递推 I_n\t反向递推 I_n")
print("-" * 35)
for n in range(11):
print(f"{n}\t{I_forward[n]:.4f}\t{I_backward[n]:.4f}")
n 正向递推 反向递推
0 0.6321 0.6321
1 0.3679 0.3679
2 0.2642 0.2642
3 0.2074 0.2073
4 0.1704 0.1709
5 0.1480 0.1455
6 0.1120 0.1268
7 0.2160 0.1121
8 -0.7280 0.1035
9 7.5520 0.0684
10 -74.5200 0.3161

发现 正向递推的时候 当n=8时 其结果非常奇怪 说明误差对结果产生了很大的影响 逆向递推的时候 其结果看起来比较稳定

3.2 题目2

已知函数

进行计算,结果保留4位小数

1
2
3
4
5
6
7
8
9
10
11
12
13
import math

def f(x):
return (1 - math.cos(x)) / (x ** 2)

x_values = [1e-5, 1e-6, 1e-7, 1e-8, 1e-9, 1e-10]

print("x\t\t\tf(x)")
print("-" * 30)
for x in x_values:
result = f(x)
print(f"{x:.1e}\t{result:.4f}")

x f(x)
1.0e-05 0.5000
1.0e-06 0.5000
1.0e-07 0.4996
1.0e-08 0.0000
1.0e-09 0.0000
1.0e-10 0.0000

发现 当x值在1e-8之后 结果都为0 这是因为尽管0.000000000001和0.000000000000001对人类来说是一个约等于的关系 但是对于计算机来说 其保存的浮点数精度是有限的 在他看来这两个数是相等的
在x很小的时候 cos(x)对于计算机来说就是1 1- cos(x)对于计算机就是0了 因此计算结果就变成0了
我们可以对这个函数进行变换 由倍角公式得

得到

我们使用此函数进行计算

1
2
3
def f_new(x):
y = x / 2
return 0.5 * (math.sin(y) / y)**2

解得

x f(x)
1.0e-05 0.5000
1.0e-06 0.5000
1.0e-07 0.5000
1.0e-08 0.5000
1.0e-09 0.5000
1.0e-10 0.5000

3.3题目3

已知函数

进行计算,结果保留4位小数

1
2
3
4
5
6
7
8
9
10
11
12
import math

def f(x):
return x * (math.log(x + 1) - math.log(x))

x_values = [1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16]

print("x\t\t\tf(x)")
print("-" * 30)
for x in x_values:
result = f_new(x)
print(f"{x:.1e}\t{result:.4f}")

解得

x f(x)
1.0e+10 1.0000
1.0e+11 0.9997
1.0e+12 1.0019
1.0e+13 0.9948
1.0e+14 0.7105
1.0e+15 0.0000
1.0e+16 0.0000

在算到1.0e+15后 结果是0了
当x的值非常大的时候,ln(x+1)-ln(x)的值非常小,计算机无法保存如此大的精度 因此ln(x+1)-ln(x)=0
我们需要对等式进行变形 由对数运算的性质得

因此

1
2
def f_new(x):
return x * math.log1p(1 / x)
x f(x)
1.0e+10 1.0000
1.0e+11 1.0000
1.0e+12 1.0000
1.0e+13 1.0000
1.0e+14 1.0000
1.0e+15 1.0000
1.0e+16 1.0000

五、实验总结

本次实验让我了解到了尽管在数学中看似合理的公式放到计算机上运行时还要考虑到截断误差 看似非常小的误差在经过n次计算后误差可能会放大好几万倍 计算机由于储存有限 无法保存准确值 只能保存精确值 因此我们必须避免那些无穷小减无穷小、大数减小数 可以通过对公式进行一定的变换来避免这些误差

  • Title: 数值分析与算法设计--实验报告1
  • Author: 姜智浩
  • Created at : 2025-09-24 11:45:14
  • Updated at : 2025-09-24 20:16:36
  • Link: https://super-213.github.io/zhihaojiang.github.io/2025/09/24/20250924数值分析与算法设计--实验报告1/
  • License: This work is licensed under CC BY-NC-SA 4.0.