github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/dsp/fourier/quarter.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 package fourier 6 7 import "github.com/jingcheng-WU/gonum/dsp/fourier/internal/fftpack" 8 9 // QuarterWaveFFT implements Fast Fourier Transform for quarter wave data. 10 type QuarterWaveFFT struct { 11 work []float64 12 ifac [15]int 13 } 14 15 // NewQuarterWaveFFT returns a QuarterWaveFFT initialized for work on sequences of length n. 16 func NewQuarterWaveFFT(n int) *QuarterWaveFFT { 17 var t QuarterWaveFFT 18 t.Reset(n) 19 return &t 20 } 21 22 // Len returns the length of the acceptable input. 23 func (t *QuarterWaveFFT) Len() int { return len(t.work) / 3 } 24 25 // Reset reinitializes the QuarterWaveFFT for work on sequences of length n. 26 func (t *QuarterWaveFFT) Reset(n int) { 27 if 3*n <= cap(t.work) { 28 t.work = t.work[:3*n] 29 } else { 30 t.work = make([]float64, 3*n) 31 } 32 fftpack.Cosqi(n, t.work, t.ifac[:]) 33 } 34 35 // CosCoefficients computes the Fast Fourier Transform of quarter wave data for 36 // the input sequence, seq, placing the cosine series coefficients in dst and 37 // returning it. 38 // This transform is unnormalized; a call to CosCoefficients followed by a call 39 // to CosSequence will multiply the input sequence by 4*n, where n is the length 40 // of the sequence. 41 // 42 // If the length of seq is not t.Len(), CosCoefficients will panic. 43 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 44 // the length of dst does not equal t.Len(), CosCoefficients will panic. 45 // It is safe to use the same slice for dst and seq. 46 func (t *QuarterWaveFFT) CosCoefficients(dst, seq []float64) []float64 { 47 if len(seq) != t.Len() { 48 panic("fourier: sequence length mismatch") 49 } 50 if dst == nil { 51 dst = make([]float64, t.Len()) 52 } else if len(dst) != t.Len() { 53 panic("fourier: destination length mismatch") 54 } 55 copy(dst, seq) 56 fftpack.Cosqf(len(dst), dst, t.work, t.ifac[:]) 57 return dst 58 } 59 60 // CosSequence computes the Inverse Fast Fourier Transform of quarter wave data for 61 // the input cosine series coefficients, coeff, placing the sequence data in dst 62 // and returning it. 63 // This transform is unnormalized; a call to CosSequence followed by a call 64 // to CosCoefficients will multiply the input sequence by 4*n, where n is the length 65 // of the sequence. 66 // 67 // If the length of seq is not t.Len(), CosSequence will panic. 68 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 69 // the length of dst does not equal t.Len(), CosSequence will panic. 70 // It is safe to use the same slice for dst and seq. 71 func (t *QuarterWaveFFT) CosSequence(dst, coeff []float64) []float64 { 72 if len(coeff) != t.Len() { 73 panic("fourier: coefficients length mismatch") 74 } 75 if dst == nil { 76 dst = make([]float64, t.Len()) 77 } else if len(dst) != t.Len() { 78 panic("fourier: destination length mismatch") 79 } 80 copy(dst, coeff) 81 fftpack.Cosqb(len(dst), dst, t.work, t.ifac[:]) 82 return dst 83 } 84 85 // SinCoefficients computes the Fast Fourier Transform of quarter wave data for 86 // the input sequence, seq, placing the sine series coefficients in dst and 87 // returning it. 88 // This transform is unnormalized; a call to SinCoefficients followed by a call 89 // to SinSequence will multiply the input sequence by 4*n, where n is the length 90 // of the sequence. 91 // 92 // If the length of seq is not t.Len(), SinCoefficients will panic. 93 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 94 // the length of dst does not equal t.Len(), SinCoefficients will panic. 95 // It is safe to use the same slice for dst and seq. 96 func (t *QuarterWaveFFT) SinCoefficients(dst, seq []float64) []float64 { 97 if len(seq) != t.Len() { 98 panic("fourier: sequence length mismatch") 99 } 100 if dst == nil { 101 dst = make([]float64, t.Len()) 102 } else if len(dst) != t.Len() { 103 panic("fourier: destination length mismatch") 104 } 105 copy(dst, seq) 106 fftpack.Sinqf(len(dst), dst, t.work, t.ifac[:]) 107 return dst 108 } 109 110 // SinSequence computes the Inverse Fast Fourier Transform of quarter wave data for 111 // the input sine series coefficients, coeff, placing the sequence data in dst 112 // and returning it. 113 // This transform is unnormalized; a call to SinSequence followed by a call 114 // to SinCoefficients will multiply the input sequence by 4*n, where n is the length 115 // of the sequence. 116 // 117 // If the length of seq is not t.Len(), SinSequence will panic. 118 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 119 // the length of dst does not equal t.Len(), SinSequence will panic. 120 // It is safe to use the same slice for dst and seq. 121 func (t *QuarterWaveFFT) SinSequence(dst, coeff []float64) []float64 { 122 if len(coeff) != t.Len() { 123 panic("fourier: coefficients length mismatch") 124 } 125 if dst == nil { 126 dst = make([]float64, t.Len()) 127 } else if len(dst) != t.Len() { 128 panic("fourier: destination length mismatch") 129 } 130 copy(dst, coeff) 131 fftpack.Sinqb(len(dst), dst, t.work, t.ifac[:]) 132 return dst 133 }