github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/dsp/fourier/internal/fftpack/sinq.go (about)

     1  // Copyright ©2018 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This is a translation of the FFTPACK sinq functions by
     6  // Paul N Swarztrauber, placed in the public domain at
     7  // http://www.netlib.org/fftpack/.
     8  
     9  package fftpack
    10  
    11  import "math"
    12  
    13  // Sinqi initializes the array work which is used in both Sinqf and
    14  // Sinqb. The prime factorization of n together with a tabulation
    15  // of the trigonometric functions are computed and stored in work.
    16  //
    17  // Input parameter
    18  //
    19  // n       The length of the sequence to be transformed. The method
    20  //         is most efficient when n+1 is a product of small primes.
    21  //
    22  // Output parameter
    23  //
    24  // work    A work array which must be dimensioned at least 3*n.
    25  //         The same work array can be used for both Sinqf and Sinqb
    26  //         as long as n remains unchanged. Different work arrays
    27  //         are required for different values of n. The contents of
    28  //         work must not be changed between calls of Sinqf or Sinqb.
    29  //
    30  // ifac    An integer work array of length at least 15.
    31  func Sinqi(n int, work []float64, ifac []int) {
    32  	if len(work) < 3*n {
    33  		panic("fourier: short work")
    34  	}
    35  	if len(ifac) < 15 {
    36  		panic("fourier: short ifac")
    37  	}
    38  	dt := 0.5 * math.Pi / float64(n)
    39  	for k := range work[:n] {
    40  		work[k] = math.Cos(float64(k+1) * dt)
    41  	}
    42  	Rffti(n, work[n:], ifac)
    43  }
    44  
    45  // Sinqf computes the Fast Fourier Transform of quarter wave data.
    46  // That is, Sinqf computes the coefficients in a sine series
    47  // representation with only odd wave numbers. The transform is
    48  // defined below at output parameter x.
    49  //
    50  // Sinqb is the unnormalized inverse of Sinqf since a call of Sinqf
    51  // followed by a call of Sinqb will multiply the input sequence x
    52  // by 4*n.
    53  //
    54  // The array work which is used by subroutine Sinqf must be
    55  // initialized by calling subroutine Sinqi(n,work).
    56  //
    57  // Input parameters
    58  //
    59  // n       The length of the array x to be transformed. The method
    60  //         is most efficient when n is a product of small primes.
    61  //
    62  // x       An array which contains the sequence to be transformed.
    63  //
    64  // work    A work array which must be dimensioned at least 3*n.
    65  //         in the program that calls Sinqf. The work array must be
    66  //         initialized by calling subroutine Sinqi(n,work) and a
    67  //         different work array must be used for each different
    68  //         value of n. This initialization does not have to be
    69  //         repeated so long as n remains unchanged thus subsequent
    70  //         transforms can be obtained faster than the first.
    71  //
    72  // ifac    An integer work array of length at least 15.
    73  //
    74  // Output parameters
    75  //
    76  // x       for i=0, ..., n-1
    77  //           x[i] = (-1)^(i)*x[n-1]
    78  //             + the sum from k=0 to k=n-2 of
    79  //               2*x[k]*sin((2*i+1)*k*pi/(2*n))
    80  //
    81  //         A call of Sinqf followed by a call of
    82  //         Sinqb will multiply the sequence x by 4*n.
    83  //         Therefore Sinqb is the unnormalized inverse
    84  //         of Sinqf.
    85  //
    86  // work    Contains initialization calculations which must not
    87  //         be destroyed between calls of Sinqf or Sinqb.
    88  func Sinqf(n int, x, work []float64, ifac []int) {
    89  	if len(x) < n {
    90  		panic("fourier: short sequence")
    91  	}
    92  	if len(work) < 3*n {
    93  		panic("fourier: short work")
    94  	}
    95  	if len(ifac) < 15 {
    96  		panic("fourier: short ifac")
    97  	}
    98  	if n == 1 {
    99  		return
   100  	}
   101  	for k := 0; k < n/2; k++ {
   102  		kc := n - k - 1
   103  		x[k], x[kc] = x[kc], x[k]
   104  	}
   105  	Cosqf(n, x, work, ifac)
   106  	for k := 1; k < n; k += 2 {
   107  		x[k] = -x[k]
   108  	}
   109  }
   110  
   111  // Sinqb computes the Fast Fourier Transform of quarter wave data.
   112  // That is, Sinqb computes a sequence from its representation in
   113  // terms of a sine series with odd wave numbers. The transform is
   114  // defined below at output parameter x.
   115  //
   116  // Sinqf is the unnormalized inverse of Sinqb since a call of Sinqb
   117  // followed by a call of Sinqf will multiply the input sequence x
   118  // by 4*n.
   119  //
   120  // The array work which is used by subroutine Sinqb must be
   121  // initialized by calling subroutine Sinqi(n,work).
   122  //
   123  // Input parameters
   124  //
   125  // n       The length of the array x to be transformed. The method
   126  //         is most efficient when n is a product of small primes.
   127  //
   128  // x       An array which contains the sequence to be transformed.
   129  //
   130  // work    A work array which must be dimensioned at least 3*n.
   131  //         in the program that calls Sinqb. The work array must be
   132  //         initialized by calling subroutine Sinqi(n,work) and a
   133  //         different work array must be used for each different
   134  //         value of n. This initialization does not have to be
   135  //         repeated so long as n remains unchanged thus subsequent
   136  //         transforms can be obtained faster than the first.
   137  //
   138  // ifac    An integer work array of length at least 15.
   139  //
   140  // Output parameters
   141  //
   142  // x       for i=0, ..., n-1
   143  //           x[i]= the sum from k=0 to k=n-1 of
   144  //             4*x[k]*sin((2*k+1)*i*pi/(2*n))
   145  //
   146  //         A call of Sinqb followed by a call of
   147  //         Sinqf will multiply the sequence x by 4*n.
   148  //         Therefore Sinqf is the unnormalized inverse
   149  //         of Sinqb.
   150  //
   151  // work    Contains initialization calculations which must not
   152  //         be destroyed between calls of Sinqb or Sinqf.
   153  func Sinqb(n int, x, work []float64, ifac []int) {
   154  	if len(x) < n {
   155  		panic("fourier: short sequence")
   156  	}
   157  	if len(work) < 3*n {
   158  		panic("fourier: short work")
   159  	}
   160  	if len(ifac) < 15 {
   161  		panic("fourier: short ifac")
   162  	}
   163  	switch n {
   164  	case 1:
   165  		x[0] *= 4
   166  		fallthrough
   167  	case 0:
   168  		return
   169  	default:
   170  		for k := 1; k < n; k += 2 {
   171  			x[k] = -x[k]
   172  		}
   173  		Cosqb(n, x, work, ifac)
   174  		for k := 0; k < n/2; k++ {
   175  			kc := n - k - 1
   176  			x[k], x[kc] = x[kc], x[k]
   177  		}
   178  	}
   179  }