资讯详情

数值分析上机题(上)

第一章

一、问题

设 S N = ∑ j = 2 N 1 j 2 ? 1 S_N = \sum_{j=2}^N \frac{1}{j^2 - 1} SN=∑j=2Nj2?11,其精确值为 1 2 ( 3 2 ? 1 N ? 1 N 1 ) \frac{1}{2}(\frac{3}{2} - \frac{1}{N} - \frac{1}{N 1}) 21​(23​−N1​−N+11​)

  • 编制按从大到小的顺序 S N = 1 2 2 − 1 + 1 3 2 − 1 + ⋯ + 1 N 2 − 1 S_N = \frac{1}{2^2 - 1} + \frac{1}{3^2 - 1} + \cdots + \frac{1}{N^2 - 1} SN​=22−11​+32−11​+⋯+N2−11​,计算 S N S_N SN​ 的通用程序
  • 编制按从小到大的顺序 S N = 1 N 2 − 1 + 1 ( N − 1 ) 2 − 1 + ⋯ + 1 N 2 − 1 S_N = \frac{1}{N^2 - 1} + \frac{1}{(N-1)^2 - 1} + \cdots + \frac{1}{N^2 - 1} SN​=N2−11​+(N−1)2−11​+⋯+N2−11​,计算 S N S_N SN​ 的通用程序
  • 按两种顺序分别计算 S 1 0 2 S_{10^2} S102​, S 1 0 4 S_{10^4} S104​, S 1 0 6 S_{10^6} S106​,并指出有效位数
  • 通过本上机题你明白了什么

二、通用程序

def my_fun(n):
    sn, sn1, sn2 = 1/2 * (3/2 - 1/n - 1/(n+1)), 0, 0

    for i in range(2, n+1):
        sn1 += 1/(i**2 - 1)

    for i in range(n, 1, -1):
        sn2 += 1/(i**2 - 1)

    print('The N we use in calculate Sn:', n, '\nThe accurate sum: Sn =', sn,
          '\nFrom large to small sum: Sn1 =', sn1, '\nFrom small to large sum: Sn2 =', sn2)
    print('abs(Sn-Sn1) =', abs(sn-sn1), '\nabs(Sn-Sn2) =', abs(sn-sn2))
    print('-' * 55)


if __name__ == '__main__':
    N = [100, 10000, 1000000]

    for num in N:
        my_fun(num)

三、程序结果

The N we use in calculate Sn: 100 
The accurate sum: Sn = 0.740049504950495 
From large to small sum: Sn1 = 0.7400495049504949 
From small to large sum: Sn2 = 0.7400495049504949
abs(Sn-Sn1) = 1.1102230246251565e-16 
abs(Sn-Sn2) = 1.1102230246251565e-16
-------------------------------------------------------
The N we use in calculate Sn: 10000 
The accurate sum: Sn = 0.7499000049995 
From large to small sum: Sn1 = 0.7499000049995057 
From small to large sum: Sn2 = 0.7499000049995
abs(Sn-Sn1) = 5.662137425588298e-15 
abs(Sn-Sn2) = 0.0
-------------------------------------------------------
The N we use in calculate Sn: 1000000 
The accurate sum: Sn = 0.7499990000005 
From large to small sum: Sn1 = 0.7499990000005217 
From small to large sum: Sn2 = 0.7499990000004999
abs(Sn-Sn1) = 2.1649348980190553e-14 
abs(Sn-Sn2) = 1.1102230246251565e-16
-------------------------------------------------------

四、有效位分析

n==10^2 n==10^4 n==10^6
从小到大 15 ? 15
从大到小 15 13 13

五、结果分析

  • 从有效位可以看出,程序算法对实验的误差具有一定的影响,一个好的算法可以使结果更加精确
  • 以该程序为例,从大到小会出现“大数吃小数”的现象,导致其精度随轮次的增加而相应减少
  • 从小到大顺序可能因为机器问题,导致其误差为 0

第二章

一、问题

  • 给定初值 x 0 x_0 x0​ 及容许误差 ϵ \epsilon ϵ,编制 Newton 法解方程 f ( x ) = 0 f(x) = 0 f(x)=0 根的通用程序
  • 给定方程 f ( x ) = x 3 3 − x = 0 f(x) = \frac{x^3}{3} - x = 0 f(x)=3x3​−x=0,易知其有三个根 x 1 ∗ = − 3 x_1^* = -\sqrt{3} x1∗​=−3 ​, x 2 ∗ = 0 x_2^* = 0 x2∗​=0, x 3 ∗ = 3 x_3^* = \sqrt{3} x3∗​=3
    • 由 Newton 方法的局部收敛性可知存在 δ > 0 \delta \gt 0 δ>0,当 x 0 ∈ ( − δ , δ ) x_0 \in (-\delta, \delta) x0​∈(−δ,δ) 时 Newton 迭代序列收敛于根 x 2 ∗ x_2^* x2∗​,试确定尽可能大的 δ \delta δ
    • 试取若干初始值,观察当 x 0 ∈ ( − ∞ , − 1 ) x_0 \in (-\infty, -1) x0​∈(−∞,−1), ( − 1 , − δ ) (-1, -\delta) (−1,−δ), ( − δ , δ ) (-\delta, \delta) (−δ,δ), ( δ , 1 ) (\delta, 1) (δ,1), ( 1 , + ∞ ) (1, +\infty) (1,+∞) 时 Newton 序列是否收敛以及收敛于哪一根
  • 通过本上机题,你明白了什么

二、通用程序

from sympy import *


# 牛顿法通用程序
def newton_fun():
    x = Symbol('x')
    epson = eval(input('Enter the absolute error: '))  # 误差
    x0 = eval(input('Enter the initial value: '))      # 初值
    fun = eval(input('Enter the function: '))          # 函数

    derivative = diff(fun, x, 1)                       # 一阶导
    x1 = x0 - fun.subs('x', x0) / derivative.subs('x', x0)

    while abs(x1 - x0) > epson:
        # Newton 迭代格式
        x0, x1 = x1, x1 - fun.subs('x', x1) / derivative.subs('x', x1)
        print(x0, x1)


# 返回收敛值
def discriminant(left, right, x0=0):
    x = Symbol('x')
    epson, fun = 1e-13, x ** 3 / 3 - x
    x0 = (left + right) / 2 if x0 == 0 else x0

    derivative = diff(fun, x, 1)
    x1 = x0 - fun.subs('x', x0) / derivative.subs('x', x0)

    while abs(x1 - x0) > epson:
        x0, x1 = x1, x1 - fun.subs('x', x1) / derivative.subs('x', x1)

    return x1


# 二分法搜索
def search():
    l, r, delta, e = 0.0, 1.0, 0.0, 1e-13
    while abs(delta - (l + r) / 2) > e:
        delta = (l + r) / 2
        res = discriminant(l, r)
        if res == 0:
            l = (l + r) / 2  # 收敛于 0 则将 l 设为中点
        else:
            r = (l + r) / 2  # 不收敛于 0(收敛于根号3) 则将 r 设为中点

    return l  # delta 值可能使函数不收敛于0,故返回 l


if __name__ == '__main__':
    newton_fun()
    print('-' * 50)
    delta = search()
    print('delta =', delta)
    print('-' * 50
        标签: abs轮速传感器s102端盖

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台