github.com/gopherd/gonum@v0.0.4/dsp/fourier/internal/fftpack/sint.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 sint 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 // Sinti initializes the array work which is used in subroutine Sint. 14 // The prime factorization of n together with a tabulation of the 15 // 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 with at least ceil(2.5*n) locations. 25 // Different work arrays are required for different values 26 // of n. The contents of work must not be changed between 27 // calls of Sint. 28 // 29 // ifac An integer work array of length at least 15. 30 func Sinti(n int, work []float64, ifac []int) { 31 if len(work) < 5*(n+1)/2 { 32 panic("fourier: short work") 33 } 34 if len(ifac) < 15 { 35 panic("fourier: short ifac") 36 } 37 if n <= 1 { 38 return 39 } 40 dt := math.Pi / float64(n+1) 41 for k := 0; k < n/2; k++ { 42 work[k] = 2 * math.Sin(float64(k+1)*dt) 43 } 44 Rffti(n+1, work[n/2:], ifac) 45 } 46 47 // Sint computes the Discrete Fourier Sine Transform of an odd 48 // sequence x(i). The transform is defined below at output parameter x. 49 // 50 // Sint is the unnormalized inverse of itself since a call of Sint 51 // followed by another call of Sint will multiply the input sequence 52 // x by 2*(n+1). 53 // 54 // The array work which is used by subroutine Sint must be 55 // initialized by calling subroutine Sinti(n,work). 56 // 57 // Input parameters 58 // 59 // n The length of the sequence to be transformed. The method 60 // is most efficient when n+1 is the product of small primes. 61 // 62 // x An array which contains the sequence to be transformed. 63 // 64 // 65 // work A work array with dimension at least ceil(2.5*n) 66 // in the program that calls Sint. The work array must be 67 // initialized by calling subroutine Sinti(n,work) and a 68 // different work array must be used for each different 69 // value of n. This initialization does not have to be 70 // repeated so long as n remains unchanged thus subsequent 71 // transforms can be obtained faster than the first. 72 // 73 // ifac An integer work array of length at least 15. 74 // 75 // Output parameters 76 // 77 // x for i=1,...,n 78 // x(i)= the sum from k=1 to k=n 79 // 2*x(k)*sin(k*i*pi/(n+1)) 80 // 81 // A call of Sint followed by another call of 82 // Sint will multiply the sequence x by 2*(n+1). 83 // Hence Sint is the unnormalized inverse 84 // of itself. 85 // 86 // work Contains initialization calculations which must not be 87 // destroyed between calls of Sint. 88 // ifac Contains initialization calculations which must not be 89 // destroyed between calls of Sint. 90 func Sint(n int, x, work []float64, ifac []int) { 91 if len(x) < n { 92 panic("fourier: short sequence") 93 } 94 if len(work) < 5*(n+1)/2 { 95 panic("fourier: short work") 96 } 97 if len(ifac) < 15 { 98 panic("fourier: short ifac") 99 } 100 if n == 0 { 101 return 102 } 103 sint1(n, x, work, work[n/2:], work[n/2+n+1:], ifac) 104 } 105 106 func sint1(n int, war, was, xh, x []float64, ifac []int) { 107 const sqrt3 = 1.73205080756888 108 109 for i := 0; i < n; i++ { 110 xh[i] = war[i] 111 war[i] = x[i] 112 } 113 114 switch n { 115 case 1: 116 xh[0] *= 2 117 case 2: 118 xh[0], xh[1] = sqrt3*(xh[0]+xh[1]), sqrt3*(xh[0]-xh[1]) 119 default: 120 x[0] = 0 121 for k := 0; k < n/2; k++ { 122 kc := n - k - 1 123 t1 := xh[k] - xh[kc] 124 t2 := was[k] * (xh[k] + xh[kc]) 125 x[k+1] = t1 + t2 126 x[kc+1] = t2 - t1 127 } 128 if n%2 != 0 { 129 x[n/2+1] = 4 * xh[n/2] 130 } 131 rfftf1(n+1, x, xh, war, ifac) 132 xh[0] = 0.5 * x[0] 133 for i := 2; i < n; i += 2 { 134 xh[i-1] = -x[i] 135 xh[i] = xh[i-2] + x[i-1] 136 } 137 if n%2 == 0 { 138 xh[n-1] = -x[n] 139 } 140 } 141 142 for i := 0; i < n; i++ { 143 x[i] = war[i] 144 war[i] = xh[i] 145 } 146 }