github.com/gopherd/gonum@v0.0.4/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 }