第1章 绪论#

import numpy as np
import pandas as pd

例子1:计算\(e^{-1} \int_{0}^1 x^n e^n\ dx\)#

def In_almost_exact(n):
    # use quadrature to compute integral
    m = 10**6
    x = np.arange(0, stop=1, step=1/m)
    return np.trapz(np.exp(-1) * x**n * np.exp(x), x=x, dx=1/m)
    
def In_approx(n, r=4):
    # 课本里使用的迭代计算法
    # r是有效数字的位数
    value = np.zeros(n)
    value[0] = np.round((1-np.exp(-1))*10**r)*10**(-r)
    print("I_0 使用近似值 {:.10f}".format(value[0]))
    for j in np.arange(1, stop=n):
        value[j] = 1 - j * value[j-1]
    return value
n = 15
In_exact_value = np.zeros(n) # 可以被认为真实的积分值
for j in range(n):
    In_exact_value[j] = In_almost_exact(j)
    
# 使用4位有效数字
r = 4
approx_vec = In_approx(n, r=r) # 课本使用的近似法
err_vec = np.abs(approx_vec - In_exact_value) # 误差
pd.DataFrame({"n": np.array(np.arange(n)), \
              "真实" : In_exact_value, "近似": approx_vec, "误差": err_vec})
I_0 使用近似值 0.6321000000
n 真实 近似 误差
0 0 0.632120 6.321000e-01 1.955883e-05
1 1 0.367878 3.679000e-01 2.155883e-05
2 2 0.264240 2.642000e-01 4.011766e-05
3 3 0.207276 2.074000e-01 1.243530e-04
4 4 0.170892 1.704000e-01 4.924119e-04
5 5 0.145532 1.480000e-01 2.468059e-03
6 6 0.126801 1.120000e-01 1.480136e-02
7 7 0.112383 2.160000e-01 1.036175e-01
8 8 0.100931 -7.280000e-01 8.289310e-01
9 9 0.091611 7.552000e+00 7.460389e+00
10 10 0.083876 -7.452000e+01 7.460388e+01
11 11 0.077351 8.207200e+02 8.206426e+02
12 12 0.071772 -9.847640e+03 9.847712e+03
13 13 0.066947 1.280203e+05 1.280203e+05
14 14 0.062731 -1.792283e+06 1.792284e+06
r = 6 #有效位数变成6
approx_vec = In_approx(n, r=r)
err_vec = np.abs(approx_vec - In_exact_value)
pd.DataFrame({"n": np.array(np.arange(n)), \
              "真实" : In_exact_value, "近似": approx_vec, "误差": err_vec})
I_0 使用近似值 0.6321210000
n 真实 近似 误差
0 0 0.632120 0.632121 1.441171e-06
1 1 0.367878 0.367879 5.588274e-07
2 2 0.264240 0.264242 1.882341e-06
3 3 0.207276 0.207274 1.647031e-06
4 4 0.170892 0.170904 1.158811e-05
5 5 0.145532 0.145480 5.194058e-05
6 6 0.126801 0.127120 3.186434e-04
7 7 0.112383 0.110160 2.222504e-03
8 8 0.100931 0.118720 1.778903e-02
9 9 0.091611 -0.068480 1.600913e-01
10 10 0.083876 1.684800 1.600924e+00
11 11 0.077351 -17.532800 1.761015e+01
12 12 0.071772 211.393600 2.113218e+02
13 13 0.066947 -2747.116800 2.747184e+03
14 14 0.062731 38460.635194 3.846057e+04

例子2:大数吃小数#

例子来源于潘建瑜教授的讲义

(10**9 + 10**-9 - 10**9)/(10**-9)
0.0
(10**9 + 10**-9) == 10**9
True

例子3: 解线性方程组#

alpha = 0.99
A = np.matrix([[1, alpha],[alpha,1]])
b = np.array([1,0])
np.linalg.solve(A,b)
array([ 50.25125628, -49.74874372])

对于\(\alpha\),一个小的扰动就可能造成解的误差很大。

该问题是源自线性方程组自身的问题,即矩阵的条件数过大(又叫做病态问题)。

alpha = 0.991
A = np.matrix([[1, alpha],[alpha,1]])
b = np.array([1,0])
np.linalg.solve(A,b)
array([ 55.80668564, -55.30442547])