---
title: 数学公式优化
description: "对于一些数学算子，常常采用泰勒级数用无限项连加式来拟合，这些相加的项由函数在某一点的导数求得，通过函数在自变量零点的导数求得的泰勒级数又叫做麦克劳林级数。在数学上，对于一个在实数或复数α邻域上，以实数作为变量或以复数作为变量、无穷可微的函数放f(x)，它的泰勒级数是以下这种形式的幂级数："
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/others/tbeaicpudevg/atlasopdev_10_0114.html
sourcePath: /source/zh/canncommercial/900/others/tbeaicpudevg/atlasopdev_10_0114.html
indexId: b090cd3fb9fd70e8f755dbda94a0d32d5529aac8e70ea2ba7860b25ea444f26c73
---
# 数学公式优化

对于一些数学算子，常常采用泰勒级数用无限项连加式来拟合，这些相加的项由函数在某一点的导数求得，通过函数在自变量零点的导数求得的泰勒级数又叫做麦克劳林级数。在数学上，对于一个在实数或复数α邻域上，以实数作为变量或以复数作为变量、无穷可微的函数放f(x)，它的泰勒级数是以下这种形式的幂级数：


这里，表示的阶乘，而表示函数在点处的阶导数。

对于函数，虽然它们的展开式会收敛，但函数与其泰勒级数也可能不相等。实际应用中，泰勒级数需要截断，只取有限项，可以用根据误差的上限选取泰勒展开的阶数。函数在进行泰勒展开的时候，在展开点附近拟合误差比较小，一般定义域离展开点越远，收敛越慢，误差越大。为了简化级数表达式，一般函数往往采用在处进行泰勒展开（即麦克劳林展开）来拟合，例如：


它们分别采用6阶麦克劳林展开和7阶麦克劳林展开即可达到双万分之一的精度。

而有些函数在某些区间的收敛十分缓慢，如下图所示为arcsin函数的拟合曲线，当x接近1的时候拟合误差很大，无法直接采用麦克劳林展开进行表示（由于收敛过慢即使提高展开阶数也达不到精度要求），因此需要针对这类函数进行分区间拟合。针对这种情况，为了达到精度的要求，可以采用分区间在不同的展开点进行泰勒展开，或者将精度达标的展开区间的拟合结果通过数学公式映射到其他区间。

图1 反正弦函数及其泰勒展开拟合图

接下来以arcsin函数为例，介绍了三种解决拟合精度问题的方法。

#### arcsin x定义

反正弦函数arcsin x是正弦函数sin x将值域限制在[-π/2, π/2]的反函数，定义域区间为 [-1, 1]，关于原点对称，为奇函数。其麦克劳林展开的无穷级数表示为：


除此之外，它还满足：


#### 方法1：区间映射

由于 y = arcsin x 在零点附近收敛很快，拟合精度很高，因此可以考虑利用公式将零点附近的区间映射到x=1附近的区间。经过分析arcsin x的相关公式，公式 可用于进行区间映射过程。将区间分界点选在的时候，正好可以利用上述公式将区间上的麦克劳林展开拟合结果映射到区间。

如下图所示为拟合的结果：

图2 反正弦函数对应拟合图

但当区间上的麦克劳林展开阶数小于等于13阶（7个系数）时，x在0.68到0.73左右有精度问题（即不满足万分之一的相对误差要求），如下图所示：

图3 13阶麦克劳林展开下的相对误差曲线

这时候我们首先可以考虑直接提高麦克劳林展开阶数从而降低误差。


#### 方法2：提高泰勒展开阶数

一般情况下，我们可以直接通过MATLAB或者OCTAVE等工具仿真最少需要用多少阶展开可以达到精度要求，虽然展开阶数越多精度越高，但也会带来更多的乘加操作使得运行性能下降，因此需要选择满足精度要求的条件下更小的展开阶数。

在进行OCTAVE仿真的时候，如下图所示，可以看到当麦克劳林展开15阶（8个系数）时，误差全都小于万分之一。

图4 15阶麦克劳林展开下的相对误差曲线

但针对有些函数在某些区间难以收敛，即使提高泰勒展开阶数也无法满足精度要求，可以再次通过区间映射方法将精度较高区间的计算结果映射到精度不达标区间（比如可以通过公式将区间[0, 0.5]的麦克劳林展开结果映射到区间），或者在不同的展开点进行泰勒展开。接下来就介绍分区间泰勒展开的方法。


#### 方法3：分区间泰勒展开

当对arcsin x在处进行泰勒展开时，其泰勒展开的无穷级数可以表示为：


我们可以考虑在区间[0, 0.5]继续采用麦克劳林展开来拟合，针对直接采用麦克劳林展开拟合精度较差的区间用处的泰勒展开来近似，区间的结果依旧采用将区间的麦克劳林展开结果映射得到。

如下图所示红线是泰勒展开的曲线，可以看到其在0.6邻域的拟合效果很好。

图5 反正弦函数及其在0.6处泰勒展开拟合图

通过octave分析这种方法的最大相对误差，可以得到最大误差为0.000070770，因此该方法的拟合结果均满足双万分之一的要求。

```
# y为arcsin x的真实值，z为拟合值
>> max(abs(y-z)./z)
ans =  0.000070770
```

或者我们也可以通过octave画图来看相应的误差曲线，具体代码如下：

```
# x是区间[0,1]上的自变量，y为arcsin x的真实值，z为拟合值，m是值全为0.0001的向量
figure
plot(x,abs(y-z)./z)
hold on
plot(x,m)
```


#### 注意事项

进行公式展开时有以下注意事项：- 使用展开的公式会增加编译、运行时间，降低了性能，所以在精度误差可接受的情况下尽量不要进行公式展开。
- 进行公式展开请遵循如下原则：
  首先确定替换前的公式精度达标区间，对于达标范围内的计算不需要进行展开；对于不达标的区间，进行公式展开只能满足固定区间内的精度达标。所以首先要确定展开后的公式精度达标区间，然后推导公式，将不达标的区间的计算映射到达标区间内计算。

- 建议将重复调用的展开公式封装成函数进行计算，有以下两点优势：

  - 减少单函数的中间变量个数。
  - 出错时便于修改。
