10

sin并且cos功能很慢,需要大量资源才能在嵌入式系统上运行。如何以更节省资源和更快的方式计算sin和运行?cos

4

11 回答 11

16

计算泰勒傅里叶级数总是很耗时。

在嵌入式系统中,您应该考虑查找表

'Net 上可能还有关于惠普如何在其早期科学计算器中优化此类计算的有趣信息。

我记得当时看到这样的东西

于 2009-10-15T10:26:47.500 回答
10

毫无疑问,带有插值的查找表将是最有效的解决方案。但是,如果您想使用更少的内存,CORDIC是一种非常有效的计算三角函数值的算法,并且通常在手持计算器中实现。

顺便说一句,使用傅立叶级数表示这些函数没有任何意义,因为您只是在创建一个循环问题,即如何评估级数的 sin/cos 项。泰勒级数是一种众所周知的近似方法,但在许多情况下误差大得无法接受。

您可能还想查看这个问题及其答案,关于 Java 的快速三角函数(因此可以轻松移植代码)。它提到了 CORDIC 和 Chebyshev 近似等。其中之一无疑将满足您的需求。

于 2009-10-15T10:35:50.310 回答
4

取决于你需要它做什么。如果您对角度精度不是很在意(例如,如果到最接近的度数就可以),那么只需使用值查找表。如果您没有 FPU,请在定点工作。

计算正弦/余弦函数的一种简单方法是使用泰勒级数(如此处的三角函数所示)。您使用的术语越少,值越不准确,但计算速度越快。

傅立叶级数计算需要知道一些正弦/余弦值。但是,如果您大部分时间将事物存储在频域中,则可能会节省计算量 - 取决于您正在做什么。

于 2009-10-15T10:29:57.477 回答
4

Dobb 博士的这篇文章:Optimizing Math-Intensive Applications with Fixed-Point Arithmetic很好地解释了 CORDIC 算法,并为文章中讨论的库提供了完整的源代码。

于 2009-10-15T16:01:38.743 回答
2

请参阅堆栈溢出问题三角函数如何工作? 那里接受的答案解释了如何减少范围,然后使用 CORDIC,然后进行一些进一步优化的一些细节。

于 2009-10-15T11:57:25.553 回答
2
  1. 查找表
  2. 泰勒级数,就像你说的

请注意,使用查找表,您通常可以通过限制域来优化事物,例如将角度表示为无符号字符,这样您只能绕圆 256 步,但也是一个非常紧凑的表。可以对值做类似的事情,比如使用定点。

于 2009-10-15T10:27:55.587 回答
0

这可能有一些帮助/灵感: Quake III 中的神奇平方根

于 2012-06-22T18:26:14.320 回答
0

我参加聚会有点晚了,但无论如何我想分享一个使用查找表(包括表生成器)的现成有效解决方案:DFTrig

DFTrig 由两部分组成:

  • 查找表生成器tablegen(用 Java 编写,但这并不重要),它接收多个选项并生成 C 代码(带有查找表的 const 结构)
  • 与 .生成的查找表一起使用的小型 C 模块tablegen

当然,查找表仅包含最少的信息:仅单个象限的正弦值,即[0, 90]度数。这足以计算任何角度的正弦/余弦。

该行为是完全可定制的。您可以指定:

  • 查找表中每个项目乘以的因子(基于每个表);
  • 表中每个项目之间的步长(基于每个表);表中项的类型(整个 C 项目通用)。

因此,根据您的需要,您可以:

  • 为整个应用程序生成具有最大因子的单个表,以便您的 C 项目的任何子系统都可以使用该单个表,提供所需的因子,如果请求的因子不是表的因子,它将重新计算;
  • 生成多个表,每个表都具有特定因素,并且 C 项目的每个子系统都使用其专用表。然后,可以按原样从表中返回值,而无需重新计算;工作得更快。

我在我的嵌入式项目中使用它,它工作得很好。

于 2015-03-23T09:59:42.433 回答
0

在某些情况下,可以只使用 IIR 滤波器进行管理,调谐到所需频率的谐振。看这里:http ://www.ee.ic.ac.uk/pcheung/teaching/ee3_Study_Project/Sinewave%20Generation(708).pdf

于 2010-01-06T20:14:44.987 回答
0

这里似乎有一个很好的伪代码示例和这里的显式代码。

但是,正如@unwind 建议的那样,您可能希望尝试在一台体面的计算机上预先计算这些表并将这些表加载到嵌入式设备。

如果您的答案不必非常准确,则查找表会相当小,您可以将其存储在设备的内存中。如果您需要更高的精度,则需要在设备内进行计算。这是内存、时间和所需精度之间的权衡;答案取决于您项目的具体性质。

于 2009-10-15T10:26:59.557 回答
0

您可以查看这个用于 8 位 AVR 微控制器的任意定点库: https ://community.atmel.com/projects/afp-arbitrary-fixed-point-lib

编辑:链接已更新

于 2012-06-25T12:47:46.710 回答