Oracle® Developer Studio 12.5:性能库用户指南

退出打印视图

更新时间: 2016 年 6 月
 
 

余弦和正弦变换

对具有特殊对称性的 DFT 进行输入会发生在各种应用程序中。利用对称性进行的变换通常能节省存储空间并减少计算次数,就像实数到复数和复数到实数 FFT 变换那样。性能库余弦和正弦变换是 FFT 例程的特殊情况,它利用了偶函数和奇函数中的对称特性。


注 - Oracle Developer Studio 性能库正弦和余弦变换例程以 FFTPACK (http://www.netlib.org/fftpack/) 中包含的例程为基础。具有 V 前缀的例程是根据 VFFTPACK (http://www.netlib.org/vfftpack/) 中包含的例程进行了向量化处理的例程。

快速余弦和正弦变换例程

以下各表列出了 Oracle Developer Studio 性能库快速余弦和正弦变换。双精度例程名称位于方括号中。名称以 'V' 开头的例程可同时计算一个或多个序列的变换。名称以 'I' 结尾的例程是初始化例程。

表 15  偶序列例程的快速余弦变换及其参数
例程名称
参数
COST [DCOST]
(LEN+1, X, WORK)
COSTI [DCOSTI]
(LEN+1, WORK)
VCOST [VDCOST]
(M, LEN+1, X, WORK, LD, TABLE)
VCOSTI [VDCOSTI]
(LEN+1, TABLE)
表 16  四分之一波长偶序列例程的快速余弦变换及其参数
例程名称
参数
COSQF [DCOSQF]
(LEN, X, WORK)
COSQB [DCOSQB]
(LEN, X, WORK)
COSQI [DCOSQI]
(LEN, WORK)
VCOSQF [VDCOSQF]
(M, LEN, X, WORK, LD, TABLE)
VCOSQB [VDCOSQB]
(M, LEN, X, WORK, LD, TABLE)
VCOSQI [VDCOSQI]
(LEN, TABLE)
表 17  奇序列例程的快速正弦变换及其参数
例程名称
参数
SINT [DSINT]
(LEN-1, X, WORK)
SINTI [DSINTI]
(LEN-1, WORK)
VSINT [VDSINT]
(M, LEN-1, X, WORK, LD, TABLE)
VSINTI [VDSINTI]
(LEN-1, TABLE)
表 18  四分之一波长奇序列例程的快速正弦变换及其参数
例程名称
参数
SINQF [DSINQF]
(LEN, X, WORK)
SINQB [DSINQB]
(LEN, X, WORK)
SINQI [DSINQI]
(LEN, WORK)
VSINQF [VDSINQF]
(M, LEN, X, WORK, LD, TABLE)
VSINQB [VDSINQB]
(M, LEN, X, WORK, LD, TABLE)
VSINQI [VDSINQI]
(LEN, TABLE) 注:

注 -  请注意以下有关上述表格的信息:
  • M:要变换的序列数。

  • LENLEN-1LEN+1:输入序列的长度。

  • X:包含要变换的序列的实数数组。在输出时,实数变换结果将存储在 X 中。

  • TABLE:变换例程所需的特定于变换大小的常数数组。常数是由初始化例程计算得出的。

  • WORK:变换例程所需的工作区。在对单一序列进行运算的例程中,WORK 还包含由初始化例程计算得出的常数。


快速正弦变换

经常遇到的另一种类型的对称性是奇对称,其中对于 n = -N+1, …, 0, …, Nx(n) = -x(-n)。与快速余弦变换相同,快速正弦变换 (Fast Sine Transform, FST) 利用奇对称来节省存储空间并减少计算次数。对于实数奇序列 x,对称意味着 x(0) = -x(0) = 0。因此,如果 x 的长度为 2N,那么只需要 xN = 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)被认为具有四分之一波长奇对称性。SINQFSINQB 分别计算单一实数四分之一波长奇序列的 FST 及其逆变换,而 VSINQFVSINQB 可对一个或多个序列进行运算。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)被认为具有四分之一波长偶对称性。COSQFCOSQB 分别计算单一实数四分之一波长偶序列的 FCT 及其逆变换。VCOSQFVCOSQB 可对一个或多个序列进行运算。[V]COSQB 的结果未经过归一化处理,如果按 image:1 over 4N 缩放,则会获得原始序列。长度为 2N 且具有四分之一波长偶对称的实数序列的 FCT 需要 N 个输入数据点,并生成一个 N 点结果序列。在调用变换例程之前,需要通过调用 [V]COSQI 来进行初始化。

离散快速余弦和正弦变换及其逆变换

Oracle Developer Studio 性能库例程使用以下部分中的方程来计算快速余弦和正弦变换以及逆变换。

[D]COST:序列的正向和逆向快速余弦变换 (FCT)

序列的正向和逆向 FCT 计算如下:

image:X(k) = x(0) + 2 times sum to {N-1} from {n=1} x(n) cos((%pi nk) over N) + x(N) cos(%pi k), k=0,...,N

[D]COST 注:

  • 需要 N + 1 个值来计算 N 点序列的 FCT。

  • [D]COST 还可以用来计算逆变换。如果调用两次 [D]COST,结果将是缩放了 image:1 over 2N 倍的原始序列。

V[D]COST:多个序列的正向和逆向快速余弦变换 (VFCT)

多个序列的正向和逆向 FCT 计算如下:

对于 i = 0,M - 1

image:X(i,k) = {x(i,0)}over 2N + 1 over N sum to {N - 1} from {n=1} x(i,n) cos ({%pi nk} over N ) + x(i,N) over 2N cos(%pi k), k= 0, ..., N1 .

V[D]COST 注:

  • 需要 M × (N+1) 个值来计算 M N 点序列的 VFCT。

  • 输入和输出序列将逐行存储。

  • V[D]COST 已经过归一化处理,并且是其自身的逆变换。如果调用两次 V[D]COST,结果将是原始数据。

[D]COSQF:四分之一波长偶序列的正向 FCT

四分之一波长偶序列的正向 FCT 计算如下:

image:X(k)= x(0)+ 2 sum to {N - 1} from {n = 1} x(n) cos({%pi (2k+1)} over 2N), k= 0, ..., N - 1

需要 N 个值来计算 N 点四分之一波长偶序列的 FCT。

[D]COSQB:四分之一波长偶序列的逆向 FCT

四分之一波长偶序列的逆向 FCT 计算如下

image:x(n) = sum to {N - 1} from {k = 0} X(k) cos ({%pi n(2k + 1)} over 2N ), n = 0,...,N - 1 .

调用正向和逆向例程将会生成缩放了 image:1 over 4N 倍的原始输入。

V[D]COSQF:一个或多个四分之一波长偶序列的正向 FCT

一个或多个四分之一波长偶序列的正向 FCT 计算如下

对于 i = 0,M - 1

image:X(i,k) = 1 over N [ x(i,0)+ 2 sum to {N - 1} from {n = 1} x(i,n) cos ({%pi n(2k + 1)} over 2N )], k = 0, ..., N - 1

V[D]COSQF 注:

  • 输入和输出序列将逐行存储。

  • 变换已进行了归一化处理,因此,如果在调用 V[D]COSQF 之后立即调用逆向例程 V[D]COSQB,则会获得原始数据。

V[D]COSQB:一个或多个四分之一波长偶序列的逆向 FCT

一个或多个四分之一波长偶序列的逆向 FCT 计算如下

对于 i = 0,M - 1

image:x(i,n) = sum to {N - 1} from {k = 0} X(i,k) cos ({%pi n(2k + 1)} over 2N), n = 0,...,N - 1

V[D]COSQB 注:

  • 输入和输出序列将逐行存储。

  • 变换已进行了归一化处理,因此,如果在调用 V[D]COSQF 之后立即调用 V[D]COSQB,则会获得原始数据。

[D]SINT:序列的正向和逆向快速正弦变换 (FST)

序列的正向和逆向 FST 计算如下

image:X(k) = 2 times sum to {N - 2} from {n = 0} x(n) sin ({%pi (n+1)(k+1)} over N), k = 0,...,N - 2 .

[D]SINT 注:

  • 需要 N-1 个值来计算 N 点序列的 FST。

  • [D]SINT 还可用来计算逆变换。如果调用两次 [D]SINT,结果将是缩放了 image:1 over 2N 倍的原始序列。

V[D]SINT:多个序列的正向和逆向快速正弦变换 (VFST)

多个序列的正向和逆向快速正弦变换计算如下

对于 i = 0,M - 1

image:X(i,k) = (2 over sqrt 2N) times sum to {N - 2} from {n = 0} x(i,n) sin ({%pi (n+1)(k+1)} over N), k = 0,...,N - 2 .

V[D]SINT 注:

  • 需要 M × (N - 1) 个值来计算 M N 点序列的 VFST。

  • 输入和输出序列将逐行存储。

  • V[D]SINT 已经过归一化处理,并且是其自身的逆变换。调用 V[D]SINT 两次将生成原始数据。

[D]SINQF:四分之一波长奇序列的正向 FST

四分之一波长奇序列的正向 FST 计算如下

image:X(k) = 2 times sum to {N - 2} from {n = 0} x(n) sin ({%pi (n+1)(2k+1)} over 2N ) + x(N - 1) cos(%pi k), k = 0,...,N - 1 .

需要 N 个值来计算 N 点四分之一波长奇序列的 FST。

[D]SINQB:四分之一波长奇序列的逆向 FST

四分之一波长奇序列的逆向 FST 计算如下

image:x(n) = 2 times sum to {N - 1} from {k = 0} X(k) sin({%pi (n+1)(2k + 1)} over 2N), n = 0,...,N - 1 .

调用正向和逆向例程将会生成缩放了 image:1 over 4N 倍的原始输入。

V[D]SINQF:一个或多个四分之一波长奇序列的正向 FST

一个或多个四分之一波长奇序列的正向 FST 计算如下

对于 i = 0,M - 1

image:X(i,k) = 1 over sqrt 4N times [ 2 sum to {N - 2} from {n = 0} x(n,i) sin ({%pi (n+1)(2k+1)} over 2N ) + x(N - 1,i) cos %pi k ], k = 0, ...,N - 1 .

V[D]SINQF 注:

  • 输入和输出序列将逐行存储。

  • 变换已进行了归一化处理,因此,如果在调用 V[D]SINQF 之后立即调用逆向例程 V[D]SINQB,则会获得原始数据。

V[D]SINQB:一个或多个四分之一波长奇序列的逆向 FST

一个或多个四分之一波长奇序列的逆向 FST 计算如下

对于 i = 0,M - 1

image:x(n,i) = 4 over sqrt 4N times sum to {N - 1} from {k = 0} X(k,i) sin ({%pi (n+1)(2k+1)} over 2N ), n = 0, ...,N - 1 .

V[D]SINQB 注:

  • 输入和输出序列将逐行存储。

  • 变换已进行了归一化处理,因此,如果在调用 V[D]SINQF 之后立即调用 V[D]SINQB,则会获得原始数据。

快速余弦变换示例

示例 15调用 COST 来计算实数偶序列的 FCT 和逆变换。如果实数序列的长度为 2N,则只需要存储 N + 1 个输入数据点,所产生的数据点的数量也是 N + 1。结果存储在输入数组中。

示例 15  计算单一实数偶序列的 FCT 和逆向 FCT
my_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调用 VCOSQFVCOSQB 来分别计算两个实数四分之一波长偶序列的 FCT 和逆向 FCT。如果实数序列的长度为 2N,则只需要存储 N 个输入数据点,所产生的数据点的数量也是 N。结果存储在输入数组中。

示例 16  计算两个实数四分之一波长偶序列的 FCT 和逆向 FCT
my_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 和逆向 FCT
my_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中,将调用 VSINQFVSINQB 来分别计算两个实数四分之一波长奇序列的 FST 和逆向 FST。如果实数序列的长度为 2N,则只需要存储 N 个输入数据点,所产生的数据点的数量也是 N。结果存储在输入数组中。

示例 18  计算两个实数四分之一波长奇序列的 FST 和逆向 FST
my_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 )