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