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