对具有特殊对称性的 DFT 进行输入会发生在各种应用程序中。利用对称性进行的变换通常能节省存储空间并减少计算次数,就像实数到复数和复数到实数 FFT 变换那样。性能库余弦和正弦变换是 FFT 例程的特殊情况,它利用了偶函数和奇函数中的对称特性。
以下各表列出了 Oracle Developer Studio 性能库快速余弦和正弦变换。双精度例程名称位于方括号中。名称以 'V' 开头的例程可同时计算一个或多个序列的变换。名称以 'I' 结尾的例程是初始化例程。
|
|
|
M:要变换的序列数。
LEN、LEN-1、LEN+1:输入序列的长度。
X:包含要变换的序列的实数数组。在输出时,实数变换结果将存储在 X 中。
TABLE:变换例程所需的特定于变换大小的常数数组。常数是由初始化例程计算得出的。
WORK:变换例程所需的工作区。在对单一序列进行运算的例程中,WORK 还包含由初始化例程计算得出的常数。
经常遇到的另一种类型的对称性是奇对称,其中对于 n = -N+1, …, 0, …, N,x(n) = -x(-n)。与快速余弦变换相同,快速正弦变换 (Fast Sine Transform, FST) 利用奇对称来节省存储空间并减少计算次数。对于实数奇序列 x,对称意味着 x(0) = -x(0) = 0。因此,如果 x 的长度为 2N,那么只需要 x 的 N = 1 个值来计算 FST。例程 SINT 可计算单一实数奇序列的 FST,而 VSINT 可计算一个或多个序列的 FST。在调用 [V]SINT 之前,必须调用 [V]SINTI 来计算与输入长度 N-1 相关的三角常数和因子。FST 是其自身的逆变换。调用 VSINT 两次将会生成原始的 N -1 个数据点。调用 SINT 两次将会生成原始的 N -1 个数据点乘以 2N。
对称的奇序列(如 x(n) = -x(-n - 1),其中 -N+1, …, 0, …, N)被认为具有四分之一波长奇对称性。SINQF 和 SINQB 分别计算单一实数四分之一波长奇序列的 FST 及其逆变换,而 VSINQF 和 VSINQB 可对一个或多个序列进行运算。SINQB 未经过归一化处理,因此使用 SINQF 的结果作为 SINQB 中的输入会生成按 4N 的因子缩放的原始序列。不过,VSINQB 经过了归一化处理,因此调用 VSINQF 之后再调用 VSINQB 将会生成原始序列。长度为 2N 且具有四分之一波长奇对称的实数序列的 FST 需要 N 个输入数据点,并生成一个 N 点结果序列。在调用变换例程之前,需要通过调用 [V]SINQI 来进行初始化。
对实数偶序列进行运算的一种特殊形式的 FFT 是快速余弦变换 (Fast Cosine Transform, FCT)。如果 x(n) = x(-n),其中 n = -N + 1, …, 0, …, N,则认为实数序列 x 具有偶对称性。长度为 2N 的序列的 FCT 需要 N + 1 个输入数据点,并生成大小为 N + 1 的序列。例程 COST 可计算单一实数偶序列的 FCT,而 VCOST 可计算一个或多个序列的 FCT。在调用 [V]COST 之前,必须调用 [V]COSTI 来计算与输入长度 N + 1 相关的三角常数和因子。FCT 是其自身的逆变换。调用 VCOST 两次将会生成原始的 N +1 个数据点。调用 COST 两次将会生成原始的 N +1 个数据点乘以 2N。
对称的偶序列 x(如 x(n) = x(-n - 1),其中 n = ‐N + 1, … , 0, …, N)被认为具有四分之一波长偶对称性。COSQF 和 COSQB 分别计算单一实数四分之一波长偶序列的 FCT 及其逆变换。VCOSQF 和 VCOSQB 可对一个或多个序列进行运算。[V]COSQB 的结果未经过归一化处理,如果按 缩放,则会获得原始序列。长度为 2N 且具有四分之一波长偶对称的实数序列的 FCT 需要 N 个输入数据点,并生成一个 N 点结果序列。在调用变换例程之前,需要通过调用 [V]COSQI 来进行初始化。
Oracle Developer Studio 性能库例程使用以下部分中的方程来计算快速余弦和正弦变换以及逆变换。
[D]COST 注:
需要 N + 1 个值来计算 N 点序列的 FCT。
[D]COST 还可以用来计算逆变换。如果调用两次 [D]COST,结果将是缩放了 倍的原始序列。
对于 i = 0,M - 1
.
V[D]COST 注:
需要 M × (N+1) 个值来计算 M N 点序列的 VFCT。
输入和输出序列将逐行存储。
V[D]COST 已经过归一化处理,并且是其自身的逆变换。如果调用两次 V[D]COST,结果将是原始数据。
需要 N 个值来计算 N 点四分之一波长偶序列的 FCT。
.
调用正向和逆向例程将会生成缩放了 倍的原始输入。
对于 i = 0,M - 1
V[D]COSQF 注:
输入和输出序列将逐行存储。
变换已进行了归一化处理,因此,如果在调用 V[D]COSQF 之后立即调用逆向例程 V[D]COSQB,则会获得原始数据。
对于 i = 0,M - 1
V[D]COSQB 注:
输入和输出序列将逐行存储。
变换已进行了归一化处理,因此,如果在调用 V[D]COSQF 之后立即调用 V[D]COSQB,则会获得原始数据。
.
[D]SINT 注:
需要 N-1 个值来计算 N 点序列的 FST。
[D]SINT 还可用来计算逆变换。如果调用两次 [D]SINT,结果将是缩放了 倍的原始序列。
对于 i = 0,M - 1
.
V[D]SINT 注:
需要 M × (N - 1) 个值来计算 M N 点序列的 VFST。
输入和输出序列将逐行存储。
V[D]SINT 已经过归一化处理,并且是其自身的逆变换。调用 V[D]SINT 两次将生成原始数据。
.
需要 N 个值来计算 N 点四分之一波长奇序列的 FST。
.
调用正向和逆向例程将会生成缩放了 倍的原始输入。
对于 i = 0,M - 1
.
V[D]SINQF 注:
输入和输出序列将逐行存储。
变换已进行了归一化处理,因此,如果在调用 V[D]SINQF 之后立即调用逆向例程 V[D]SINQB,则会获得原始数据。
对于 i = 0,M - 1
.
V[D]SINQB 注:
输入和输出序列将逐行存储。
变换已进行了归一化处理,因此,如果在调用 V[D]SINQF 之后立即调用 V[D]SINQB,则会获得原始数据。
示例 15调用 COST 来计算实数偶序列的 FCT 和逆变换。如果实数序列的长度为 2N,则只需要存储 N + 1 个输入数据点,所产生的数据点的数量也是 N + 1。结果存储在输入数组中。
示例 15 计算单一实数偶序列的 FCT 和逆向 FCTmy_system% cat cost.f program Drive cost implicit none integer,parameter :: len=4 real x(0:len),work(3*(len+1)+15), z(0:len), scale integer i scale = 1.0/(2.0*len) call RANDOM_NUMBER(x(0:len)) z(0:len) = x(0:len) write(*,'(a25,i1,a10,i1,a12)')'Input sequence of length ', $ len,' requires ', len+1,' data points' write(*,'(5(f8.3,2x),/)')(x(i),i=0,len) call costi(len+1, work) call cost(len+1, z, work) write(*,*)'Forward fast cosine transform' write(*,'(5(f8.3,2x),/)')(z(i),i=0,len) call cost(len+1, z, work) write(*,*) $ 'Inverse fast cosine transform (results scaled by 1/2*N)' write(*,'(5(f8.3,2x),/)')(z(i)*scale,i=0,len) end my_system% f95 -dalign cost.f -library=sunperf my_system% a.out Input sequence of length 4 requires 5 data points 0.557 0.603 0.210 0.352 0.867 Forward fast cosine transform 3.753 0.046 1.004 -0.666 -0.066 Inverse fast cosine transform (results scaled by 1/2*N) 0.557 0.603 0.210 0.352 0.867
示例 16调用 VCOSQF 和 VCOSQB 来分别计算两个实数四分之一波长偶序列的 FCT 和逆向 FCT。如果实数序列的长度为 2N,则只需要存储 N 个输入数据点,所产生的数据点的数量也是 N。结果存储在输入数组中。
示例 16 计算两个实数四分之一波长偶序列的 FCT 和逆向 FCTmy_system% cat vcosq.f program vcosq implicit none integer,parameter :: len=4, m = 2, ld = m+1 real x(ld,len),xt(ld,len),work(3*len+15), z(ld,len) integer i, j call RANDOM_NUMBER(x) z = x write(*,'(a27,i1)')' Input sequences of length ',len do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(x(j,i),i=1,len),')' end do call vcosqi(len, work) call vcosqf(m,len, z, xt, ld, work) write(*,*) $ 'Forward fast cosine transform for quarter-wave even sequences' do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(z(j,i),i=1,len),')' end do call vcosqb(m,len, z, xt, ld, work) write(*,*) $ 'Inverse fast cosine transform for quarter-wave even sequences' write(*,*)'(results are normalized)' do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(z(j,i),i=1,len),')' end do end my_system% f95 -dalign vcosq.f -library=sunperf my_system% a.out Input sequences of length 4 seq1 = (0.557 0.352 0.990 0.539 ) seq2 = (0.603 0.867 0.417 0.156 ) Forward fast cosine transform for quarter-wave even sequences seq1 = (0.755 -.392 -.029 0.224 ) seq2 = (0.729 0.097 -.091 -.132 ) Inverse fast cosine transform for quarter-wave even sequences (results are normalized) seq1 = (0.557 0.352 0.990 0.539 ) seq2 = (0.603 0.867 0.417 0.156 )
在以下示例示例 17中,将调用 SINT 来计算实数奇序列的 FST 和逆变换。如果实数序列的长度为 2N,则只需要存储 N - 1 个输入数据点,所产生的数据点的数量也是 N - 1。结果存储在输入数组中。
示例 17 计算两个实数四分之一波长偶序列的 FCT 和逆向 FCTmy_system% cat sint.f program Drive sint implicit none integer,parameter :: len=4 real x(0:len-2),work(3*(len-1)+15), z(0:len-2), scale integer i call RANDOM_NUMBER(x(0:len-2)) z(0:len-2) = x(0:len-2) scale = 1.0/(2.0*len) write(*,'(a25,i1,a10,i1,a12)')'Input sequence of length ', $ len,' requires ', len-1,' data points' write(*,'(3(f8.3,2x),/)')(x(i),i=0,len-2) call sinti(len-1, work) call sint(len-1, z, work) write(*,*)'Forward fast sine transform' write(*,'(3(f8.3,2x),/)')(z(i),i=0,len-2) call sint(len-1, z, work) write(*,*) $ 'Inverse fast sine transform (results scaled by 1/2*N)' write(*,'(3(f8.3,2x),/)')(z(i)*scale,i=0,len-2) end my_system% f95 -dalign sint.f -library=sunperf my_system% a.out Input sequence of length 4 requires 3 data points 0.557 0.603 0.210 Forward fast sine transform 2.291 0.694 -0.122 Inverse fast sine transform (results scaled by 1/2*N) 0.557 0.603 0.210
在以下示例示例 18中,将调用 VSINQF 和 VSINQB 来分别计算两个实数四分之一波长奇序列的 FST 和逆向 FST。如果实数序列的长度为 2N,则只需要存储 N 个输入数据点,所产生的数据点的数量也是 N。结果存储在输入数组中。
示例 18 计算两个实数四分之一波长奇序列的 FST 和逆向 FSTmy_system% cat vsinq.f program vsinq implicit none integer,parameter :: len=4, m = 2, ld = m+1 real x(ld,len),xt(ld,len),work(3*len+15), z(ld,len) integer i, j call RANDOM_NUMBER(x) z = x write(*,'(a27,i1)')' Input sequences of length ',len do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(x(j,i),i=1,len),')' end do call vsinqi(len, work) call vsinqf(m,len, z, xt, ld, work) write(*,*) $ 'Forward fast sine transform for quarter-wave odd sequences' do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(z(j,i),i=1,len),')' end do call vsinqb(m,len, z, xt, ld, work) write(*,*) $ 'Inverse fast sine transform for quarter-wave odd sequences' write(*,*)'(results are normalized)' do j = 1,m write(*,'(a3,i1,a4,4(f5.3,2x),a1,/)') $ 'seq',j,' = (',(z(j,i),i=1,len),')' end do end my_system% f95 vsinq.f -library=sunperf my_system% a.out Input sequences of length 4 seq1 = (0.557 0.352 0.990 0.539 ) seq2 = (0.603 0.867 0.417 0.156 ) Forward fast sine transform for quarter-wave odd sequences seq1 = (0.823 0.057 0.078 0.305 ) seq2 = (0.654 0.466 -.069 -.037 ) Inverse fast sine transform for quarter-wave odd sequences (results are normalized) seq1 = (0.557 0.352 0.990 0.539 ) seq2 = (0.603 0.867 0.417 0.156 )