【发布时间】:2009-10-15 10:23:25
【问题描述】:
sin 和 cos 函数速度很慢,需要大量资源才能在嵌入式系统上运行。如何以更节省资源和更快的方式计算sin 和cos 函数?
【问题讨论】:
-
如果输入参数是“角度”,那么查找表是好的,但如果它只是对面和斜边,那么你可以使用精度降低的除法
标签: c math embedded trigonometry
sin 和 cos 函数速度很慢,需要大量资源才能在嵌入式系统上运行。如何以更节省资源和更快的方式计算sin 和cos 函数?
【问题讨论】:
标签: c math embedded trigonometry
【讨论】:
带有插值的查找表无疑是最有效的解决方案。但是,如果您想使用更少的内存,CORDIC 是一种非常有效的计算三角函数值的算法,并且通常在手持计算器中实现。
顺便说一句,使用傅立叶级数表示这些函数没有任何意义,因为您只是在创建一个循环问题,即如何评估级数的 sin/cos 项。泰勒级数是一种众所周知的近似方法,但在许多情况下,误差会大到无法接受。
您可能还想查看this question and its answers,了解 Java 的快速三角函数(因此可以轻松移植代码)。它提到了 CORDIC 和 Chebyshev 近似等。其中之一无疑会满足您的需求。
【讨论】:
取决于你需要什么。如果您对角度精度不是很在意(例如,如果到最接近的度数就可以了),那么只需使用值查找表。如果您没有 FPU,请在 fixed-point 工作。
计算 sin/cos 函数的一种简单方法是使用泰勒级数(如三角函数here 下所示)。使用的术语越少,数值越不准确,但计算速度越快。
傅立叶级数计算需要知道一些正弦/余弦值。但是,如果您大部分时间将内容存储在 frequency domain 中,则可能会节省计算费用 - 取决于您正在执行的操作。
【讨论】:
Dobb 博士的这篇文章:Optimizing Math-Intensive Applications with Fixed-Point Arithmetic 很好地解释了 CORDIC 算法,并提供了文章中讨论的库的完整源代码。
【讨论】:
请注意,使用查找表,您通常可以通过限制域来优化事物,例如将角度表示为无符号字符,只为您提供 256 步绕圆,但也是一个非常紧凑的表格。可以对值做类似的事情,比如使用定点。
【讨论】:
查看 Stack Overflow 问题 How do Trigonometric functions work? 接受的答案解释了如何减少范围,然后使用 CORDIC,然后进行一些进一步优化的一些细节。
【讨论】:
在某些情况下,只需使用 IIR 滤波器即可进行管理,将其调谐到所需频率的谐振。 看这里:http://www.ee.ic.ac.uk/pcheung/teaching/ee3_Study_Project/Sinewave%20Generation(708).pdf
【讨论】:
这可能会有所帮助/启发: Magical square root in Quake III
【讨论】:
我参加聚会有点晚了,但无论如何我想分享一个使用查找表(包括表生成器)的现成有效解决方案:DFTrig。
DFTrig 由两部分组成:
tablegen(用 Java 编写,但这并不重要)接收多个选项并生成 C 代码(带有查找表的 const 结构)tablegen 生成的查找表配合使用的小型 C 模块。当然,查找表只包含最少的信息:仅单个象限的正弦值,即[0, 90] 度。这足以计算任何角度的正弦/余弦。
行为是完全可定制的。您可以指定:
因此,根据您的需要,您可以:
我在我的嵌入式项目中使用它,效果很好。
【讨论】:
您可以查看这个用于 8 位 AVR 微控制器的任意定点库: https://community.atmel.com/projects/afp-arbitrary-fixed-point-lib
编辑:链接已更新
【讨论】: