1. 程式人生 > >數值分析實驗:誤差的影響

數值分析實驗:誤差的影響

文章目錄

1 題目

利用 n 階泰勒展開多項式 i = 0 x ( x

i i ! ) \sum_{i=0}^{x}(\frac{x^{i}}{i!}) ,計算函式 f
( x ) = e x f(x)=e^{x}
在給定點 x x 的值。
要求:絕對誤差在最大階數  M A X N MAXN 以內達到給定精度 E P S EPS
使得: i = 0 x ( x i i ! ) e x < E P S |\sum_{i=0}^{x}(\frac{x^{i}}{i!})-e^{x}| < EPS ,並且 n < M A X N n < MAXN

函式介面定義:double Exp_Calculate( double x )
其中 x x 為給定點,函式返回達到精度要求的近似 e x e^{x} 的值。
常數 M A X N MAXN E P S EPS 在裁判程式中定義。
若無法在 M A X N MAXN 次疊加內達到精度,則函式返回 1 -1


2 c++程式碼實現

2.0 程式目錄

2.1 虛擬碼

2.2 main.cpp

2.3 func.h

2.4 input.txt

2.5 output.txt

2.1 虛擬碼

================================================================================
虛擬碼:Exp_Calculate

輸入:函式近似求解的自變數

輸出:函式近似求解的因變數,若無法在 M A X N MAXN 次疊加內達到精度,則函式返回 1 -1

================================================================================

01:init t e m p temp , p o w pow , f a c t r i a l factrial , s u m sum

02: t e m p x temp \leftarrow |x|

//累加求和,近似求解

03:for   i = 1 i=1   to   M A X N MAXN

04:   p o w x i pow \leftarrow x^{i}

05:   i ! f a c t r i a l i! \leftarrow factrial

06:   s u m p o w f a c t o r i a l sum \leftarrow \frac{pow}{factorial}

07:end

08:if   x < 0 x < 0  then

09:   s u m 1 s u m sum \leftarrow \frac{1}{sum}

10:end if

11:if   s u m e x < E P S |sum - e^{x}| < EPS  then

12:  return  sum

13:else

14:  return  -1

================================================================================

2.2 main.cpp

#include <cmath>
#include <iostream>

#define EPS 0.00001
#define MAXN 20

using namespace std;

double Exp_Calculate(double x);

int main()
{
    double x;

    freopen("test.txt", "r", stdin);

    while(scanf("%lf", &x) != EOF){
            //cin>>x
        printf("%.4lf\n", Exp_Calculate(x));
    }

    fclose(stdin);
    //關閉檔案

    return 0;
}

#include "func.h"

2.3 func.h

#ifndef FUNC_H_INCLUDED
#define FUNC_H_INCLUDED

double Exp_Calculate(double x){

    double pow = 1.0;
    double factorial = 1.0;
    double sum = 1.0;

    double temp=0;

    //化負為正
    //避免兩個較小數的相減
    if(x<0)
        temp = -x;
    else
        temp = x;

    //求taylor級數,近似求解
    for(int i=1;i<MAXN;i++){
        pow *= temp;
        factorial *= (double)i;
        sum += (pow)/factorial;
    }

    //再化負為正
    if(x<0)
        sum = 1.0/sum;


    if(abs(sum - exp(x)) < EPS)
        return sum;
    else
        return -1;
}


#endif // FUNC_H_INCLUDED

2.4 input.txt

1 2 3 4 5 6 -1 -2 -3 -4 -5 -6 

2.5 output.txt

2.7183
7.3891
20.0855
54.5981
-1.0000
-1.0000
0.3679
0.1353
0.0498
0.0183
0.0067
0.0025

3 難點解析 – func.h

3.1 對泰勒級數近似求解的原理與構造

要求:按照公式編寫即可,儘可能節約記憶體

3.2 降低數值計算中的誤差積累

避免::小數減小數

根本原因::計算機所使用二進位制01程式碼無法準確表示某些帶小數位的十進位制資料。

過程分析::當x為負數時,在sum累加求和過程中,會出現小數減小數,從而造成誤差累計

解決方法::將 e x e^{-x} 轉化為計算 e x e^{x} ,最後求得 1 e x \frac{1}{e^{x}} ,即 e x e^{-x} ,就可以減小誤差了


4 誤差分析

4.1 計算機程式演算基本步驟:

1)建模:實際問題建立數學模型

2)數值化:將數學問題轉化為數值問題

3)演算法設計

4)根據演算法程式設計計算

4.2 存在的誤差

1)模型誤差(Modeling Error):數學模型是對具體問題忽略次要因素進行抽象而獲得的,本身即是問題的近似,由此產生的誤差為模型誤差

2)觀測誤差(Observation Error):數學模型中包含(依賴)的引數如溫度、密度、長度、時間、電壓等由人的觀測或工具測量獲得,與實際資料存在誤差,稱為觀測誤差

3)方法誤差(Method Error)(截斷誤差 Truncation Error))演算法中包含的計算公式如泰勒公式等本身是一種求解的近似(連續的離散化處理,無窮的有限話處理),由此產生的誤差稱為方法誤差或截斷誤差

4)舍入誤差(Roundoff Error):計算機中的數(機器數)是具有有限精度的實數的有限子集,稱為浮點數(floating number),由於計算時的四捨五入,或者因計算機的字長有限而使原始資料只能用有限位數表示,由此產生的誤差為舍入誤差

4.3 設計演算法過程中減小誤差的tips

保證數值穩定性

(1)控制舍入誤差的傳播

(2)合理安排量級相差懸殊數間的運算次序,防止大數吃小數

(3)避免兩個相近數相減

(4)避免接近0的數左除數,防止溢位

(5)簡化計算步驟,減少運算次數



Author

lance

2018·9·18