github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/dsp/fourier/sincos.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 // DCT implements Discrete Cosine Transform for real sequences. 10 type DCT struct { 11 work []float64 12 ifac [15]int 13 } 14 15 // NewDCT returns a DCT initialized for work on sequences of length n. 16 // NewDCT will panic is n is not greater than 1. 17 func NewDCT(n int) *DCT { 18 var t DCT 19 t.Reset(n) 20 return &t 21 } 22 23 // Len returns the length of the acceptable input. 24 func (t *DCT) Len() int { return len(t.work) / 3 } 25 26 // Reset reinitializes the DCT for work on sequences of length n. 27 // Reset will panic is n is not greater than 1. 28 func (t *DCT) Reset(n int) { 29 if n <= 1 { 30 panic("fourier: n less than 2") 31 } 32 if 3*n <= cap(t.work) { 33 t.work = t.work[:3*n] 34 } else { 35 t.work = make([]float64, 3*n) 36 } 37 fftpack.Costi(n, t.work, t.ifac[:]) 38 } 39 40 // Transform computes the Discrete Fourier Cosine Transform of 41 // the input data, src, placing the result in dst and returning it. 42 // This transform is unnormalized; a call to Transform followed by 43 // another call to Transform will multiply the input sequence by 2*(n-1), 44 // where n is the length of the sequence. 45 // 46 // If the length of src is not t.Len(), Transform will panic. 47 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 48 // the length of dst does not equal t.Len(), FFT will panic. 49 // It is safe to use the same slice for dst and src. 50 func (t *DCT) Transform(dst, src []float64) []float64 { 51 if len(src) != t.Len() { 52 panic("fourier: sequence length mismatch") 53 } 54 if dst == nil { 55 dst = make([]float64, t.Len()) 56 } else if len(dst) != t.Len() { 57 panic("fourier: destination length mismatch") 58 } 59 copy(dst, src) 60 fftpack.Cost(len(dst), dst, t.work, t.ifac[:]) 61 return dst 62 } 63 64 // DST implements Discrete Sine Transform for real sequences. 65 type DST struct { 66 work []float64 67 ifac [15]int 68 } 69 70 // NewDST returns a DST initialized for work on sequences of length n. 71 func NewDST(n int) *DST { 72 var t DST 73 t.Reset(n) 74 return &t 75 } 76 77 // Len returns the length of the acceptable input. 78 func (t *DST) Len() int { return (2*len(t.work)+1)/5 - 1 } 79 80 // Reset reinitializes the DCT for work on sequences of length n. 81 func (t *DST) Reset(n int) { 82 if 5*(n+1)/2 <= cap(t.work) { 83 t.work = t.work[:5*(n+1)/2] 84 } else { 85 t.work = make([]float64, 5*(n+1)/2) 86 } 87 fftpack.Sinti(n, t.work, t.ifac[:]) 88 } 89 90 // Transform computes the Discrete Fourier Sine Transform of the input 91 // data, src, placing the result in dst and returning it. 92 // This transform is unnormalized; a call to Transform followed by 93 // another call to Transform will multiply the input sequence by 2*(n-1), 94 // where n is the length of the sequence. 95 // 96 // If the length of src is not t.Len(), Transform will panic. 97 // If dst is nil, a new slice is allocated and returned. If dst is not nil and 98 // the length of dst does not equal t.Len(), FFT will panic. 99 // It is safe to use the same slice for dst and src. 100 func (t *DST) Transform(dst, src []float64) []float64 { 101 if len(src) != t.Len() { 102 panic("fourier: sequence length mismatch") 103 } 104 if dst == nil { 105 dst = make([]float64, t.Len()) 106 } else if len(dst) != t.Len() { 107 panic("fourier: destination length mismatch") 108 } 109 copy(dst, src) 110 fftpack.Sint(len(dst), dst, t.work, t.ifac[:]) 111 return dst 112 }