mirror of
https://github.com/gonum/gonum.git
synced 2025-10-08 00:20:11 +08:00
dsp/window: add Values.TransformTo window functions and example
This commit is contained in:
@@ -118,3 +118,42 @@ func ExampleValues() {
|
||||
//
|
||||
// dst: [0.000000 0.164595 0.324699 0.475947 0.614213 0.735724 0.837166 0.915773 0.969400 0.996584 0.996584 0.969400 0.915773 0.837166 0.735724 0.614213 0.475947 0.324699 0.164595 0.000000]
|
||||
}
|
||||
|
||||
func ExampleValues_TransformTo_gabor() {
|
||||
src := []float64{1, 2, 1, 0, -1, -1, -2, -2, -1, -1,
|
||||
0, 1, 1, 2, 1, 0, -1, -2, -1, 0}
|
||||
|
||||
// Create a Gaussian Window lookup table for 4 samples.
|
||||
gaussian := window.NewValues(window.Gaussian{0.5}.Transform, 4)
|
||||
|
||||
// Prepare a destination.
|
||||
dst := make([]float64, 8)
|
||||
|
||||
// Apply the transformation to the src, placing it in dst.
|
||||
for i := 0; i < len(src)-len(gaussian); i++ {
|
||||
gaussian.TransformTo(dst[0:len(gaussian)], src[i:i+len(gaussian)])
|
||||
|
||||
// To perform the Gabor transform, we would calculate
|
||||
// the FFT on dst for each iteration.
|
||||
fmt.Printf("FFT(%f)\n", dst)
|
||||
}
|
||||
|
||||
// Output:
|
||||
//
|
||||
// FFT([0.135335 1.601475 0.800737 0.000000 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.270671 0.800737 0.000000 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.135335 0.000000 -0.800737 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.000000 -0.800737 -0.800737 -0.270671 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.135335 -0.800737 -1.601475 -0.270671 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.135335 -1.601475 -1.601475 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.270671 -1.601475 -0.800737 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.270671 -0.800737 -0.800737 0.000000 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.135335 -0.800737 0.000000 0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([-0.135335 0.000000 0.800737 0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.000000 0.800737 0.800737 0.270671 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.135335 0.800737 1.601475 0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.135335 1.601475 0.800737 0.000000 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.270671 0.800737 0.000000 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.135335 0.000000 -0.800737 -0.270671 0.000000 0.000000 0.000000 0.000000])
|
||||
// FFT([0.000000 -0.800737 -1.601475 -0.135335 0.000000 0.000000 0.000000 0.000000])
|
||||
}
|
||||
|
@@ -147,6 +147,24 @@ func (v Values) Transform(seq []float64) []float64 {
|
||||
return seq
|
||||
}
|
||||
|
||||
// TransformTo applies the weights in the receiver to src placing the result
|
||||
// in dst. If v is nil, TransformTo is a no-op, otherwise the length of v must
|
||||
// match the length of src and dst.
|
||||
func (v Values) TransformTo(dst, src []float64) {
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
if len(v) != len(src) {
|
||||
panic("window: seq length mismatch")
|
||||
}
|
||||
if len(v) != len(dst) {
|
||||
panic("window: dst length mismatch")
|
||||
}
|
||||
for i, w := range v {
|
||||
dst[i] = w * src[i]
|
||||
}
|
||||
}
|
||||
|
||||
// TransformComplex applies the weights in the receiver to seq in place, returning
|
||||
// the result. If v is nil, TransformComplex is a no-op, otherwise the length of v
|
||||
// must match the length of seq.
|
||||
@@ -163,3 +181,22 @@ func (v Values) TransformComplex(seq []complex128) []complex128 {
|
||||
}
|
||||
return seq
|
||||
}
|
||||
|
||||
// TransformComplexTo applies the weights in the receiver to src placing the
|
||||
// result in dst. If v is nil, TransformComplexTo is a no-op, otherwise the
|
||||
// length of v must match the length of src and dst.
|
||||
func (v Values) TransformComplexTo(dst, src []complex128) {
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
if len(v) != len(src) {
|
||||
panic("window: seq length mismatch")
|
||||
}
|
||||
if len(v) != len(dst) {
|
||||
panic("window: dst length mismatch")
|
||||
}
|
||||
for i, w := range v {
|
||||
sv := src[i]
|
||||
dst[i] = complex(w*real(sv), w*imag(sv))
|
||||
}
|
||||
}
|
||||
|
@@ -174,7 +174,18 @@ func TestWindows(t *testing.T) {
|
||||
src[i] = 1
|
||||
}
|
||||
|
||||
dst = NewValues(test.fn, len(src)).Transform(src)
|
||||
vals := NewValues(test.fn, len(src))
|
||||
dst = vals.Transform(src)
|
||||
if !floats.EqualApprox(dst, test.want, tol) {
|
||||
t.Errorf("unexpected result for lookup window function %q:\ngot:%#.6v\nwant:%#.6v", test.name, dst, test.want)
|
||||
}
|
||||
|
||||
for i := range src {
|
||||
src[i] = 1
|
||||
}
|
||||
|
||||
dst = make([]float64, len(src))
|
||||
vals.TransformTo(dst, src)
|
||||
if !floats.EqualApprox(dst, test.want, tol) {
|
||||
t.Errorf("unexpected result for lookup window function %q:\ngot:%#.6v\nwant:%#.6v", test.name, dst, test.want)
|
||||
}
|
||||
@@ -202,7 +213,18 @@ func TestWindowsComplex(t *testing.T) {
|
||||
src[i] = complex(1, 1)
|
||||
}
|
||||
|
||||
dst = NewValues(test.fn, len(src)).TransformComplex(src)
|
||||
vals := NewValues(test.fn, len(src))
|
||||
dst = vals.TransformComplex(src)
|
||||
if !equalApprox(dst, test.want, tol) {
|
||||
t.Errorf("unexpected result for lookup window function %q:\ngot:%#.6v\nwant:%#.6v", test.name, dst, test.want)
|
||||
}
|
||||
|
||||
for i := range src {
|
||||
src[i] = complex(1, 1)
|
||||
}
|
||||
|
||||
dst = make([]complex128, len(src))
|
||||
vals.TransformComplexTo(dst, src)
|
||||
if !equalApprox(dst, test.want, tol) {
|
||||
t.Errorf("unexpected result for lookup window function %q:\ngot:%#.6v\nwant:%#.6v", test.name, dst, test.want)
|
||||
}
|
||||
|
Reference in New Issue
Block a user