云梦 发表于 2013-5-29 18:58:20

-10.993328883944023249699765318886
3.9966644419720116248498826594432917614691341389767918250399831407458936016591770 E0 +8.6544766818683163506484864487038110093137290377930209906096344044161329614064250 E0 i
3.9966644419720116248498826594432917614691341389767918250399831407458936016591770 E0 -8.6544766818683163506484864487038110093137290377930209906096344044161329614064250 E0 i
我正准备设计FFTvb 程序

ysr 发表于 2013-6-1 12:04:36

云梦 发表于 2013-6-1 15:00:39

如果不使用FFT快速乘除法,要提高运算的速度确不容易。虽然在定精度计算中我采用了多钟技巧,但在多位数超过512时不能令人满意。1024位Gamma函数我需要0.1秒以下,才可能对更多复杂函数快速计算。但这个目标还需要尝试。

ysr 发表于 2013-6-2 22:00:56

云梦 发表于 2013-6-8 15:47:14

VB 编写的FFT(8点的基2FFT)
Ft=8
入口参数:数组 ax_sz()
出口参数: FFT_Nr()(实数部分) ;FFT_Ni() (虚数部分) 数据类型 Variant

Function FFT(ax_sz() As Variant)   'FFT2 傅里叶变换 2013-.6-08
Dim Ar(), Ai() As Variant
Dim x1(1, 8), x2(1, 8) As Variant
Dim x11(1, 8), x12(1, 8), x21(1, 8), x22(1, 8) As Variant
Dim Np, u, i As Integer
Np = Ft

ReDim Ar(Np), Ai(Np) As Variant
'Dim ax_sz(512)

x11(1, 0) = 0
x12(1, 0) = 0
x21(1, 0) = 0
x22(1, 0) = 0

x11(0, 1) = ax_sz(0)
x12(0, 1) = ax_sz(2)
x21(0, 1) = ax_sz(1)
x22(0, 1) = ax_sz(3)

x11(1, 1) = -ax_sz(4)
x12(1, 1) = -ax_sz(6)
x21(1, 1) = -ax_sz(5)
x22(1, 1) = -ax_sz(7)

x11(0, 0) = x11(0, 1) - x11(1, 1)
x12(0, 0) = x12(0, 1) - x12(1, 1)
x21(0, 0) = x21(0, 1) - x21(1, 1)
x22(0, 0) = x22(0, 1) - x22(1, 1)

'k=2
x11(0, 2) = x11(0, 1) + x11(1, 1)
x12(0, 2) = x12(0, 1) + x12(1, 1)
x21(0, 2) = x21(0, 1) + x21(1, 1)
x22(0, 2) = x22(0, 1) + x22(1, 1)

x11(1, 2) = x11(1, 0)
x12(1, 2) = x12(1, 0)
x21(1, 2) = x21(1, 0)
x22(1, 2) = x22(1, 0)

'k=3
x11(0, 3) = x11(0, 1)
x12(0, 3) = x12(0, 1)
x21(0, 3) = x21(0, 1)
x22(0, 3) = x22(0, 1)

x11(1, 3) = -x11(1, 1)
x12(1, 3) = -x12(1, 1)
x21(1, 3) = -x21(1, 1)
x22(1, 3) = -x22(1, 1)
'k=4
x11(0, 4) = x11(0, 0)
x11(1, 4) = x11(1, 0)

x12(0, 4) = x12(0, 0)
x12(1, 4) = x12(1, 0)
   
x21(0, 4) = x21(0, 0)
x21(1, 4) = x21(1, 0)
   
x22(0, 4) = x22(0, 0)
x22(1, 4) = x22(1, 0)

'FFT 值
x1(0, 0) = x11(0, 0) + x12(0, 0)
x1(1, 0) = 0
x2(0, 0) = x21(0, 0) + x22(0, 0)
x2(1, 0) = 0

x1(0, 4) = x11(0, 4) - x12(0, 4)
x1(1, 4) = 0
x2(0, 4) = x21(0, 4) - x22(0, 4)
x2(1, 4) = x1(1, 4)
For i = 1 To 3
    u = 32 * i Mod 256
    x1(0, i) = x11(0, i) + x12(0, i) * Sbi(0, u) - x12(1, i) * Sbi(1, u)
    x1(1, i) = x11(1, i) + x12(0, i) * Sbi(1, u) + x12(1, i) * Sbi(0, u)
   
    x1(0, 8 - i) = x1(0, i)
    x1(1, 8 - i) = -x1(1, i)
   
    x2(0, i) = x21(0, i) + x22(0, i) * Sbi(0, u) - x22(1, i) * Sbi(1, u)
    x2(1, i) = x21(1, i) + x22(0, i) * Sbi(1, u) + x22(1, i) * Sbi(0, u)
   
    x2(0, 8 - i) = x2(0, i)
    x2(1, 8 - i) = -x2(1, i)
Next
x1(0, 8) = x1(0, 0)
x1(1, 8) = x1(1, 0)
x2(0, 8) = x2(0, 0)
x2(1, 8) = x2(1, 0)

FFT_Nr(0) = x11(0, 0) + x12(0, 0) + x21(0, 0) + x22(0, 0)
FFT_Ni(0) = 0
FFT_Nr(4) = x1(0, 4)
FFT_Ni(4) = -x2(0, 4)

For i = 1 To 8
    u = 16 * i Mod 256
    FFT_Nr(i) = x1(0, i) + x2(0, i) * Sbi(0, u) - x2(1, i) * Sbi(1, u)
    FFT_Ni(i) = x1(1, i) + x2(0, i) * Sbi(1, u) + x2(1, i) * Sbi(0, u)

    FFT_Nr(Np - i) = FFT_Nr(i)
    FFT_Ni(Np - i) = -FFT_Ni(i)
Next
End Function

云梦 发表于 2013-6-8 15:50:49

Sbi(0,u) 余弦函数 2πk/256 (k=0,1,.......,256)
Sbi(1,u) 正弦函数 2πk/256(k=0,1,........,256)

liangbch 发表于 2013-6-8 17:00:23

FFT适用于有效数字很多的情况,对于像1024位精度的计算,FFT的效果并不好,如果优化的不是足够好,甚至没有分治法快。
另外,VB并不适合做科学计算,如果想最求性能的话,C+汇编是更好的选择,建议楼主不妨学学C语言。如果我没有记错的话,站长在多年前写的等幂和计算器就是用VB做的,但是现在,站长已经把c语言和汇编用的非常熟练了。

云梦 发表于 2013-6-8 17:22:58

27# liangbch


C语言曾学过,但太费脑子,我就是编着玩,如真的需要我会用C语言的。

ysr 发表于 2013-6-11 21:31:10

云梦 发表于 2013-6-14 14:22:40

FFT适用于有效数字很多的情况,对于像1024位精度的计算,FFT的效果并不好,如果优化的不是足够好,甚至没有分治法快。
另外,VB并不适合做科学计算,如果想最求性能的话,C+汇编是更好的选择,建议楼主不妨学学C语 ...
liangbch 发表于 2013-6-8 17:00 http://bbs.emath.ac.cn/images/common/back.gif

FFT对于不太大的数据来说并非有益,尝试了一下1024位FFT的速度还不如硬乘快。采用了部分分治法结果反而有所效果,虽然不大可比硬乘好些。
页: 1 2 [3] 4 5
查看完整版本: 几个VB小程序