Algorithm 使用Excel'的快速傅里叶变换;s VBA

Algorithm 使用Excel'的快速傅里叶变换;s VBA,algorithm,excel,signal-processing,fft,vba,Algorithm,Excel,Signal Processing,Fft,Vba,我正试图在MS的Excel VBA中实现快速傅里叶变换(基数-2)。我正在使用的代码从工作表中的某个区域提取数据,进行计算,然后将结果转储到相邻的列中。我遇到的问题是1)知道如何处理生成的X[k]数组,2)将这些结果与Excel内置FFT的结果进行匹配(它们目前不匹配)。代码如下所示。提前感谢你的帮助 Sub Enforce_DecimationInTime() On Error GoTo ERROR_HANDLING Dim SubName As String SubName = "Enfo

我正试图在MS的Excel VBA中实现快速傅里叶变换(基数-2)。我正在使用的代码从工作表中的某个区域提取数据,进行计算,然后将结果转储到相邻的列中。我遇到的问题是1)知道如何处理生成的X[k]数组,2)将这些结果与Excel内置FFT的结果进行匹配(它们目前不匹配)。代码如下所示。提前感谢你的帮助

Sub Enforce_DecimationInTime()

On Error GoTo ERROR_HANDLING
Dim SubName As String
SubName = "Enforce_DecimationInTime()"

Dim WS As Worksheet
Dim n As Long, v As Long, LR As Long, x As Long

Set WS = Worksheets("FFT")
LR = WS.Range("A" & Rows.Count).End(xlUp).Row
n = LR - 1
Do Until 2 ^ x <= n And 2 ^ (x + 1) > n     'locates largest power of 2 from size of input array
    x = x + 1
Loop
n = n - (n - 2 ^ x) 'calculates n using the largest power of 2
If n + 1 <> WS.Range("A" & Rows.Count).End(xlUp).Row Then
    WS.Range("A" & 2 ^ x + 2 & ":A" & LR).Delete xlUp   'deletes extra input data
End If
v = WorksheetFunction.Log(n, 2)     'calculates number of decimations necessary

Application.ScreenUpdating = False
For x = 1 To v
    Call Called_Core.DecimationInTime(WS, n, 2 ^ x, x)  'calls decimation in time subroutine
Next x
Application.ScreenUpdating = True

Exit Sub
ERROR_HANDLING:
    MsgBox "Error encountered in " & SubName & ": exiting subroutine." _
    & vbNewLine _
    & vbNewLine & "Error description: " & Err.Description _
    & vbNewLine & "Error number: " & Err.Number, vbCritical, Title:="Error!"
    End

End Sub
Sub-efforce_DecimationInTime()
关于错误转到错误处理
作为字符串的Dim子名称
SubName=“强制执行决策时间()
将WS设置为工作表
尺寸n为长,v为长,LR为长,x为长
设置WS=工作表(“FFT”)
LR=WS.Range(“A”&Rows.Count).End(xlUp).Row
n=LR-1
直到2^x n'从输入数组的大小找到2的最大幂为止
x=x+1
环
n=n-(n-2^x)'使用2的最大幂计算n
如果n+1 WS.Range(“A”&Rows.Count).End(xlUp).Row然后
WS.Range(“A”&2^x+2&“:A”&LR.Delete xlUp”删除额外的输入数据
如果结束
v=工作表函数。Log(n,2)“计算所需的决策数
Application.ScreenUpdating=False
对于x=1到v
调用_Core.decimationitime(WS,n,2^x,x)'调用时间内的抽取子例程
下一个x
Application.ScreenUpdating=True
出口接头
错误处理:
MsgBox“在子名称(&SubName&)”中遇到错误:正在退出子例程。”_
&vbNewLine_
&vbNewLine&“错误描述:”&错误描述_
&vbNewLine&“错误号:”&错误号,vbCritical,标题:=“错误!”
终点
端接头
上面的子例程通过For/Next循环调用下面的子例程,使计数为“v”

Sub-decimationitime(WS作为工作表,n作为长,因子作为整数,x作为长)
关于错误转到错误处理
作为字符串的Dim子名称
SubName=“DecimationInTime()”
尺寸f_1()为单个,f_2()为单个
我一样长,我一样长,k一样长
Dim TFactor_N1作为字符串,TFactor_N2作为字符串,X_k()作为字符串
尺寸G_1()作为变量,G_2()作为变量
将f_1(0到n/系数-1)重新定义为单个
将f_2(0到n/系数-1)重新定义为单个
将G_1(0到n/1-1)重新定义为变量
将G_2(0到n/1-1)重新定义为变量
将X_k(0到n-1)重新指定为字符串
TFactor_N1=工作表函数.Complex(0,-2*工作表函数.Pi/(n/1))'n的旋转因子
TFactor_N2=工作表函数.Complex(0,-2*工作表函数.Pi/(n/2))'n/2的旋转因子
对于i=0到n/系数-1
f_1(i)=WS.范围(“A”&2*i+2).值“分配输入数据”
f_2(i)=WS.范围(“A”&2*i+3).值“分配输入数据”
接下来我
WS.Cells(1,1+x).Value=“x[”&x&“]”用k编号标记x[k]列
对于k=0到n/2-1
对于m=0到n/系数-1
G_1(m)=工作表函数.ImProduct(工作表函数.ImPower(TFactor_N2,k*m),工作表函数.Complex(f_1(m),0))'定义了G_1[m]
G_2(m)=工作表函数.ImProduct(工作表函数.ImPower(TFactor_N2,k*m),工作表函数.Complex(f_2(m),0))'定义了G_2[m]
下一个m
X_k(k)=WorksheetFunction.ImSum(WorksheetFunction.ImSum(G_1)、WorksheetFunction.ImProduct(WorksheetFunction.ImSum(G_2)、WorksheetFunction.ImPower(TFactor_N1,k))”为k定义X[k]

如果k我回到这个过程并确定我的问题是我给旋转因子TFactor_N1和TFactor_N2分配了错误的值。在解决了这个问题并调整了显示的值之后,我能够得到与Excel内置FFT相同的结果。固定代码如下所示

Sub Enforce_DecimationInTime()

On Error GoTo ERROR_HANDLING
Dim SubName As String
SubName = "Enforce_DecimationInTime()"

Dim WS As Worksheet
Dim n As Long, v As Long, LR As Long, x As Long
Dim TFactor_N1 As String, TFactor_N2 As String

Set WS = Worksheets("FFT")
LR = WS.Range("A" & Rows.Count).End(xlUp).Row
n = LR - 1
Do Until 2 ^ x <= n And 2 ^ (x + 1) > n                                                                     'locates largest power of 2 from size of input array
    x = x + 1
Loop
n = n - (n - 2 ^ x)                                                                                         'calculates n using the largest power of 2
If n + 1 <> WS.Range("A" & Rows.Count).End(xlUp).Row Then
    WS.Range("A" & 2 ^ x + 2 & ":A" & LR).Delete xlUp                                                       'deletes extra input data
End If
v = WorksheetFunction.Log(n, 2)                                                                             'calculates number of decimations necessary

TFactor_N1 = WorksheetFunction.ImExp(WorksheetFunction.Complex(0, -2 * WorksheetFunction.Pi / (n / 1)))     'twiddle factor for N
TFactor_N2 = WorksheetFunction.ImExp(WorksheetFunction.Complex(0, -2 * WorksheetFunction.Pi / (n / 2)))     'twiddle factor for N/2

Application.ScreenUpdating = False
For x = 1 To v
    Call Called_Core.DecimationInTime(WS, n, 2 ^ x, x, TFactor_N1, TFactor_N2)                              'calls decimation in time subroutine
Next x
Application.ScreenUpdating = True

Exit Sub
ERROR_HANDLING:
    MsgBox "Error encountered in " & SubName & ": exiting subroutine." _
    & vbNewLine _
    & vbNewLine & "Error description: " & Err.Description _
    & vbNewLine & "Error number: " & Err.Number, vbCritical, Title:="Error!"
    End

End Sub


Sub DecimationInTime(WS As Worksheet, n As Long, Factor As Integer, x As Long, TFactor_N1 As String, TFactor_N2 As String)

On Error GoTo ERROR_HANDLING
Dim SubName As String
SubName = "DecimationInTime()"

Dim f_1() As String, f_2() As String
Dim i As Long, m As Long, k As Long
Dim X_k() As String
Dim G_1() As Variant, G_2() As Variant

ReDim f_1(0 To n / Factor - 1) As String
ReDim f_2(0 To n / Factor - 1) As String
ReDim G_1(0 To n / 1 - 1) As Variant
ReDim G_2(0 To n / 1 - 1) As Variant
ReDim X_k(0 To n - 1) As String

For i = 0 To n / Factor - 1
    f_1(i) = WS.Cells(2 * i + 2, 1).Value                                                                   'assign input data
    f_2(i) = WS.Cells(2 * i + 3, 1).Value                                                                   'assign input data
Next i
For k = 0 To n / 2 - 1
    For m = 0 To n / Factor - 1                                                                             'defines G_1[m] and G_2[m]
        G_1(m) = WorksheetFunction.ImProduct(WorksheetFunction.ImPower(TFactor_N2, k * m), f_1(m))
        G_2(m) = WorksheetFunction.ImProduct(WorksheetFunction.ImPower(TFactor_N2, k * m), f_2(m))
    Next m                                                                                                  'defines X[k] for k and k + n/2
    X_k(k) = WorksheetFunction.ImSum(WorksheetFunction.ImSum(G_1), WorksheetFunction.ImProduct(WorksheetFunction.ImSum(G_2), WorksheetFunction.ImPower(TFactor_N1, k)))
    If k <= n / 2 Then X_k(k + n / 2) = WorksheetFunction.ImSub(WorksheetFunction.ImSum(G_1), WorksheetFunction.ImProduct(WorksheetFunction.ImSum(G_2), WorksheetFunction.ImPower(TFactor_N1, k)))
    If x = 1 Then
        WS.Cells(k + 2, 1 + x).Value = X_k(k)
        WS.Cells(k + 2 + n / 2, 1 + x).Value = X_k(k + n / 2)
    End If
Next k

Exit Sub
ERROR_HANDLING:
    MsgBox "Error encountered in " & SubName & ": exiting subroutine." _
    & vbNewLine _
    & vbNewLine & "Error description: " & Err.Description _
    & vbNewLine & "Error number: " & Err.Number, vbCritical, Title:="Error!"
    End

End Sub
Sub-efforce_DecimationInTime()
关于错误转到错误处理
作为字符串的Dim子名称
SubName=“强制执行决策时间()
将WS设置为工作表
尺寸n为长,v为长,LR为长,x为长
调暗TFactor_N1作为字符串,TFactor_N2作为字符串
设置WS=工作表(“FFT”)
LR=WS.Range(“A”&Rows.Count).End(xlUp).Row
n=LR-1
直到2^x n'从输入数组的大小找到2的最大幂为止
x=x+1
环
n=n-(n-2^x)'使用2的最大幂计算n
如果n+1 WS.Range(“A”&Rows.Count).End(xlUp).Row然后
WS.Range(“A”&2^x+2&“:A”&LR.Delete xlUp”删除额外的输入数据
如果结束
v=工作表函数。Log(n,2)“计算所需的决策数
TFactor_N1=WorksheetFunction.ImExp(WorksheetFunction.Complex(0,-2*WorksheetFunction.Pi/(n/1)))n的旋转因子
TFactor_N2=WorksheetFunction.ImExp(WorksheetFunction.Complex(0,-2*WorksheetFunction.Pi/(n/2)))n/2的旋转因子
Application.ScreenUpdating=False
对于x=1到v
decimationitime(WS,n,2^x,x,TFactor_N1,TFactor_N2)调用时间内的抽取子例程
下一个x
Application.ScreenUpdating=True
出口接头
错误处理:
MsgBox“在子名称(&SubName&)”中遇到错误:正在退出子例程。”_
&vbNewLine_
&vbNewLine&“错误描述:”&错误描述_
&vbNewLine&“错误号:”&错误号,vbCritical,标题:=“错误!”
终点
端接头
次决策时间(WS作为工作表,n作为长,因子作为整数,x作为长,TFactor_N1作为字符串,TFactor_N2作为字符串)
关于错误转到错误处理
作为字符串的Dim子名称
SubName=“DecimationInTime()”
尺寸f_1()作为字符串,f_2()作为字符串
我一样长,我一样长,k一样长
Dim X_k()作为字符串
尺寸G_1()作为变量,G_2()作为变量
将f_1(0到n/因子-1)重定为字符串
将f_2(0到n/因子-1)重新定义为字符串
将G_1(0到n/1-1)重新定义为变量
将G_2(0到n/1-1)重新定义为变量
将X_k(0到n-1)重新指定为字符串
对于i=0到n/系数-1
f_1(i)=WS.Cells(2*i+2,1).值
Sub Enforce_DecimationInTime()

On Error GoTo ERROR_HANDLING
Dim SubName As String
SubName = "Enforce_DecimationInTime()"

Dim WS As Worksheet
Dim n As Long, v As Long, LR As Long, x As Long
Dim TFactor_N1 As String, TFactor_N2 As String

Set WS = Worksheets("FFT")
LR = WS.Range("A" & Rows.Count).End(xlUp).Row
n = LR - 1
Do Until 2 ^ x <= n And 2 ^ (x + 1) > n                                                                     'locates largest power of 2 from size of input array
    x = x + 1
Loop
n = n - (n - 2 ^ x)                                                                                         'calculates n using the largest power of 2
If n + 1 <> WS.Range("A" & Rows.Count).End(xlUp).Row Then
    WS.Range("A" & 2 ^ x + 2 & ":A" & LR).Delete xlUp                                                       'deletes extra input data
End If
v = WorksheetFunction.Log(n, 2)                                                                             'calculates number of decimations necessary

TFactor_N1 = WorksheetFunction.ImExp(WorksheetFunction.Complex(0, -2 * WorksheetFunction.Pi / (n / 1)))     'twiddle factor for N
TFactor_N2 = WorksheetFunction.ImExp(WorksheetFunction.Complex(0, -2 * WorksheetFunction.Pi / (n / 2)))     'twiddle factor for N/2

Application.ScreenUpdating = False
For x = 1 To v
    Call Called_Core.DecimationInTime(WS, n, 2 ^ x, x, TFactor_N1, TFactor_N2)                              'calls decimation in time subroutine
Next x
Application.ScreenUpdating = True

Exit Sub
ERROR_HANDLING:
    MsgBox "Error encountered in " & SubName & ": exiting subroutine." _
    & vbNewLine _
    & vbNewLine & "Error description: " & Err.Description _
    & vbNewLine & "Error number: " & Err.Number, vbCritical, Title:="Error!"
    End

End Sub


Sub DecimationInTime(WS As Worksheet, n As Long, Factor As Integer, x As Long, TFactor_N1 As String, TFactor_N2 As String)

On Error GoTo ERROR_HANDLING
Dim SubName As String
SubName = "DecimationInTime()"

Dim f_1() As String, f_2() As String
Dim i As Long, m As Long, k As Long
Dim X_k() As String
Dim G_1() As Variant, G_2() As Variant

ReDim f_1(0 To n / Factor - 1) As String
ReDim f_2(0 To n / Factor - 1) As String
ReDim G_1(0 To n / 1 - 1) As Variant
ReDim G_2(0 To n / 1 - 1) As Variant
ReDim X_k(0 To n - 1) As String

For i = 0 To n / Factor - 1
    f_1(i) = WS.Cells(2 * i + 2, 1).Value                                                                   'assign input data
    f_2(i) = WS.Cells(2 * i + 3, 1).Value                                                                   'assign input data
Next i
For k = 0 To n / 2 - 1
    For m = 0 To n / Factor - 1                                                                             'defines G_1[m] and G_2[m]
        G_1(m) = WorksheetFunction.ImProduct(WorksheetFunction.ImPower(TFactor_N2, k * m), f_1(m))
        G_2(m) = WorksheetFunction.ImProduct(WorksheetFunction.ImPower(TFactor_N2, k * m), f_2(m))
    Next m                                                                                                  'defines X[k] for k and k + n/2
    X_k(k) = WorksheetFunction.ImSum(WorksheetFunction.ImSum(G_1), WorksheetFunction.ImProduct(WorksheetFunction.ImSum(G_2), WorksheetFunction.ImPower(TFactor_N1, k)))
    If k <= n / 2 Then X_k(k + n / 2) = WorksheetFunction.ImSub(WorksheetFunction.ImSum(G_1), WorksheetFunction.ImProduct(WorksheetFunction.ImSum(G_2), WorksheetFunction.ImPower(TFactor_N1, k)))
    If x = 1 Then
        WS.Cells(k + 2, 1 + x).Value = X_k(k)
        WS.Cells(k + 2 + n / 2, 1 + x).Value = X_k(k + n / 2)
    End If
Next k

Exit Sub
ERROR_HANDLING:
    MsgBox "Error encountered in " & SubName & ": exiting subroutine." _
    & vbNewLine _
    & vbNewLine & "Error description: " & Err.Description _
    & vbNewLine & "Error number: " & Err.Number, vbCritical, Title:="Error!"
    End

End Sub