7
回答
高精度AD导致的计算溢出问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
如果有一组数据,这组数据有些是用20位AD采集而来的,有些是用10位AD采集而来的,但并不知道这组数据里面哪些是20位的哪些是10位的(或者数据很大,不可能人为查看哪些是20位哪些是10位),如果要对这组数据进行滤波处理,为了尽量减少精度损失,滤波器系数一般都会尽量选用精度较高的数字(如在matlab中选用含有十几位小数的数字,在vc中会先将系数转为尽可能大的整数(即相当于多取小数点后面的位数),然后最后结果再除以一个整数),但是这样难免会带来运算时间的开销,特别是在VC中,直接采用浮点运算会耗掉大量的运算时间,结果得不偿失,将浮点数转为整数再计算又很容易导致计算溢出,因为如果遇到20位AD采集而来的数据,再乘以一个12位的系数,很可能就溢出了。请问有什么好方法解决这种问题么?
举报
中中中
发帖于6年前 7回/1K+阅
共有7个答案 最后回答: 6年前

你AD上来的,就没有浮点这么一说。希望你要理解。浮点和定点,是说的小数点在数值描述时的位置是否可以浮动。浮点是通过后面的指数改变来浮动的。

因此你始终是定点问题。余下就是滤波窗中,加乘溢出问题。基本上是没有办法的。你需要扩展到64位。但对于特殊的数据表现,可以做优化,如果你是32位系统,64位加乘需要进行仿真实现。

也就是在每次加乘其实就是卷积的一个点的计算啦,判断是否32位溢出,如果没有,则不要64位扩展计算,只要对低32位的最高位做个符号位扩展就可以。如果有就调函数扩展。

其实大多数滤波系数是对称分布,且最终会归一化,这必然带来个加乘后右移的工作,或者,系数存在正负的情况。合理调整加乘的顺序,可以有效降低上面说的哪些32位计算溢出导致64位计算的方式。

 

另外,对你说个题外化,如果是AD采样,通常位宽足够的情况下,转浮点是SB做法。我最讨厌浮点和除法,这两样东西。浮点也不是无限数,也是有限值,而且同样位宽下,浮点可表现的值的数量(不是范围)比定点方式要少。

--- 共有 3 条评论 ---
asdfsx真强+1 6年前 回复
中山野鬼回复 @红薯 : 多年前的讨论,毕业论文就忽悠用改良的高斯滤波增强图像,还TNND的2维的,总算让我忽悠过去了。哈。 6年前 回复
红薯哥哥,你真强! 6年前 回复

引用来自“中山野鬼”的答案

你AD上来的,就没有浮点这么一说。希望你要理解。浮点和定点,是说的小数点在数值描述时的位置是否可以浮动。浮点是通过后面的指数改变来浮动的。

因此你始终是定点问题。余下就是滤波窗中,加乘溢出问题。基本上是没有办法的。你需要扩展到64位。但对于特殊的数据表现,可以做优化,如果你是32位系统,64位加乘需要进行仿真实现。

也就是在每次加乘其实就是卷积的一个点的计算啦,判断是否32位溢出,如果没有,则不要64位扩展计算,只要对低32位的最高位做个符号位扩展就可以。如果有就调函数扩展。

其实大多数滤波系数是对称分布,且最终会归一化,这必然带来个加乘后右移的工作,或者,系数存在正负的情况。合理调整加乘的顺序,可以有效降低上面说的哪些32位计算溢出导致64位计算的方式。

 

另外,对你说个题外化,如果是AD采样,通常位宽足够的情况下,转浮点是SB做法。我最讨厌浮点和除法,这两样东西。浮点也不是无限数,也是有限值,而且同样位宽下,浮点可表现的值的数量(不是范围)比定点方式要少。

中山野鬼 神人也.膜拜之..嘎嘎.

引用来自“中山野鬼”的答案

你AD上来的,就没有浮点这么一说。希望你要理解。浮点和定点,是说的小数点在数值描述时的位置是否可以浮动。浮点是通过后面的指数改变来浮动的。

因此你始终是定点问题。余下就是滤波窗中,加乘溢出问题。基本上是没有办法的。你需要扩展到64位。但对于特殊的数据表现,可以做优化,如果你是32位系统,64位加乘需要进行仿真实现。

也就是在每次加乘其实就是卷积的一个点的计算啦,判断是否32位溢出,如果没有,则不要64位扩展计算,只要对低32位的最高位做个符号位扩展就可以。如果有就调函数扩展。

其实大多数滤波系数是对称分布,且最终会归一化,这必然带来个加乘后右移的工作,或者,系数存在正负的情况。合理调整加乘的顺序,可以有效降低上面说的哪些32位计算溢出导致64位计算的方式。

 

另外,对你说个题外化,如果是AD采样,通常位宽足够的情况下,转浮点是SB做法。我最讨厌浮点和除法,这两样东西。浮点也不是无限数,也是有限值,而且同样位宽下,浮点可表现的值的数量(不是范围)比定点方式要少。

嗯,AD输出无浮点这些了解,就是如何对AD输出做处理而已。但是如何对高精度的AD输出做处理,还不知道有什么好方法以至于计算不溢出,同时也不要耗费大量的时间。

引用来自“中中中”的答案

求高人指点
你把滤波公式和滤波表,列出来,你问的问题已经很具体了。我帮你看看,有什么快速方法。上面我抽象的谈,都是口水话对你没什么实用价值。

引用来自“中山野鬼”的答案

引用来自“中中中”的答案

求高人指点
你把滤波公式和滤波表,列出来,你问的问题已经很具体了。我帮你看看,有什么快速方法。上面我抽象的谈,都是口水话对你没什么实用价值。

例如随便一个IIR滤波器,其滤波公式为

y(n) =   0.8333437213445*x(n) + 0.98245332182*x(n-1) + 0.38573829987*y(n-1)

为了尽量减少精度的损失,所以滤波器系数的原始位数都选的比较高(当然这里只是随便举的例子),在matlab下可以用这些系数,但是在vc下就必须先转为整形然后再计算(运算时间要求),这样就会带来精度的损失,因为不能转为很大的整形数字,那样很容易就计算溢出了。

滤波表是什么?

--- 共有 1 条评论 ---
中山野鬼哈我的口头语,就是滤波系数表,不好意思。OK。我就这个问题,等我忙完公司手头上的事情,帮你分析一下。 6年前 回复

引用来自“中中中”的答案

引用来自“中山野鬼”的答案

引用来自“中中中”的答案

求高人指点
你把滤波公式和滤波表,列出来,你问的问题已经很具体了。我帮你看看,有什么快速方法。上面我抽象的谈,都是口水话对你没什么实用价值。

例如随便一个IIR滤波器,其滤波公式为

y(n) =   0.8333437213445*x(n) + 0.98245332182*x(n-1) + 0.38573829987*y(n-1)

为了尽量减少精度的损失,所以滤波器系数的原始位数都选的比较高(当然这里只是随便举的例子),在matlab下可以用这些系数,但是在vc下就必须先转为整形然后再计算(运算时间要求),这样就会带来精度的损失,因为不能转为很大的整形数字,那样很容易就计算溢出了。

滤波表是什么?

你这个问题我大概分析了一下,刚才我分析时有点跑题了。主要是你的工作重点我没有更多的信息。不过就两个问题回答。一个是精度保证的问题,一个是提升速度的问题。

首先你的上述公式可以抽象如下:

Y(n) = A1X(n) + A2X(n-1) + A3Y(n-1)

A1,A2,A3是确定正实数

上面公式可以展开如下

Y(n) = A1X(n) + A3^(0)(A2+A3*A1)X(n-1) + ... A3^(m-2)(A2+A3*A1)X(n-m+1) + A3^(m-1)A2X(n-m) + A3^(m)Y(n-m)

这里存在个小修正。 m >= 2。

由于你的x(n)是采样数据,也就是说,x(n)是个定点数,假设是2^20次方,就是说,你基于最小非0数为1时,最大可描述数为 2^20 - 1,则对应x(n)的系数如果小于 1/ 2^20就没有意义。

上面展开式肯定是收敛的,不是我的证明,而是你的滤波如果是这种带反馈的,展开式一旦不收敛,意味着到某个时刻后,你的数据就会有溢出可能,无论多少有限的位宽来表示Y。

由于是收敛的,则必然在多项式中,给点一个N,就是大n,则任意 f(m) m > N时,f(m)会小于一个定值。这里把f(m)看作系数表达式,则从存在一个N,使得 f(m) < 1/2^20。也就是说你的系数,无论多少精度的浮点表示,在N后,都没有意义。

简单说,这里至少有个A3的自己的次方,而你的A3 = 0.38...就算是0.39吧,求它的倒数,然后log 。就是说

如下

(1/0.39) ^ w > 2^20 --->
log(1/0.39) (2^20) = 20 * log2 / log(1/0.39)。
大约可以计算出w 在14到15附近。

由此你的多项式展开,在 14,15项后就没有任何意义了。因为你的任意采样的数据上来,经过系数的计算,用浮点描述,则小数点后,有足够多的0,导致你按照定点描述进行加法时,始终为0。我这个解释比较绕,哈,如果我直接描述为不可分辨怕你不知道我在说什么。

由此,你的问题就变成,确认上述15个系数。通过你无限精度的浮点系数,A1,A2,A3进行处理。这个工作不作为计算量的,就是我说的滤波表。有了这个滤波表,余下你的任意y就成了这个模样

Y(n) = A0 * X(n) + A1* X(n-1) + ... A14 * X(n-14)

那么到此,精度问题就描述完了,就是说,如果你的滤波是采用硬件设计,最多有15个delay层就足够了。再多,对于你而言已经没有任何意义了。都是0.

余下我们谈速度问题。

有两种方案。一种是通过上述(有限)二项展开式,进行压缩,形成递归嵌套方式,也就是你最初的表达方案

Y(n) = A1*X(n) + A2*X(n-1) + A3*Y(n-1)

这样做有好处,有坏处,好处如下:

每个点的计算量较少。尽可能的复用了前面的累计数据。只不过实际输出的y(n)存在一个高精度保留的y(n)需要供以后使用,如同加乘中存在多bits一样,例如32位加乘器通常内部有40位。

坏处如下:

无法并发处理。多项式展开,所有的输入输出是分在两个不相交的集合内的。而且是多对一的映射关系,因此根据你的硬件特性,比如如果是DSP我更倾向并发操作。

至于计算步骤中的溢出问题,都存在,没有谁能省的。

需要注意,前面多项式展开分析精度问题,并不是说是可以舍弃的,假设你最后滤波方式还是回到了递归嵌套的方案上。因为解决了你浮点转定点精度对Y(n-1)内部的问题。

而至于针对确定精度的计算优化,没有什么好方案。只有比如32位加乘,在64位空间进行。只不过低32位没有意义了。因为此处你的系数是归一化的。用定点整数描述,乘法后,自然存在个右移32位的事情。

不过有一点可以证明,你的64是不可能溢出的。因为你多项式完全展开,也就15项左右。而乘法AXB,其中一个只有20位精度。则你64位可以支持 2^11个(留一个做符号吧,谁知道呢。哈),加乘。除非你的多项式展开,发现N在1024以上。才会存在问题。

 补充一下,如果你是多项式展开并发计算时,是有个优化方式。因为你的输入x(n)是20位精度,当对应多项式的精度在小于2^12时,该项式的乘法是只要 32位目标空间。虽然最终结果会做右移32位,你这里的计算结果都始终在低32位,但你不能说就不算了。因为存在多项式累加,此处的结果,会可能影响到高32位的值。你可以省去,如果你可以容忍一定精度。甚至可以全部都是做成32位的目标加乘。哈。不过精度肯定有损失。工程上,有两种事情:

1、实际不可能的事情,例如你20bits的采样,分辨率不可能到 2^21次以上。

2、现有系统可描述精度下,某些高度精度无意义。可有损的计算。

我后面说的精度损失是说的第2点,不是第一点,切勿混淆。

 

 

 
顶部