数值分析实验:误差的影响

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lancecrazy/article/details/82853835

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

猜你喜欢

转载自blog.csdn.net/lancecrazy/article/details/82853835