blob: 6a0fd0aca214af9d3cab69f81ff432da52a2231e [file] [log] [blame]
// 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.
// This is a translation and extension of the FFTPACK test
// functions by Paul N Swarztrauber, placed in the public
// domain at http://www.netlib.org/fftpack/.
package fftpack
import (
"math"
"math/cmplx"
"reflect"
"testing"
"gonum.org/v1/gonum/floats"
)
func TestRfft(t *testing.T) {
const tol = 1e-12
for _, test := range rfftTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 2*test.n)
ifac := make([]int, 15)
Rffti(test.n, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to rffti for n=%d", test.n)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to rffti for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
modn := test.n % 2
fn := float64(test.n)
nm1 := test.n - 1
x, y, xh := series(test.n)
dt := 2 * math.Pi / fn
ns2 := (test.n + 1) / 2
if ns2 >= 2 {
for k := 1; k < ns2; k++ { //eek
var sum1, sum2 float64
arg := float64(k) * dt
for i := 0; i < test.n; i++ {
arg1 := float64(i) * arg
sum1 += x[i] * math.Cos(arg1)
sum2 += x[i] * math.Sin(arg1)
}
y[2*k-1] = sum1
y[2*k] = -sum2
}
}
var sum1, sum2 float64
for i := 0; i < nm1; i += 2 {
sum1 += x[i]
sum2 += x[i+1]
}
if modn == 1 {
sum1 += x[test.n-1]
}
y[0] = sum1 + sum2
if modn == 0 {
y[test.n-1] = sum1 - sum2
}
Rfftf(test.n, x, work, ifac)
var rftf float64
for i := 0; i < test.n; i++ {
rftf = math.Max(rftf, math.Abs(x[i]-y[i]))
x[i] = xh[i]
}
rftf /= fn
if !floats.EqualWithinAbsOrRel(rftf, 0, tol, tol) {
t.Errorf("unexpected rftf value for n=%d: got:%f want:0", test.n, rftf)
}
// Construct a frequency spectrum and compare the computed sequence.
for i := 0; i < test.n; i++ {
sum := x[0] / 2
arg := float64(i) * dt
if ns2 >= 2 {
for k := 1; k < ns2; k++ { //eek
arg1 := float64(k) * arg
sum += x[2*k-1]*math.Cos(arg1) - x[2*k]*math.Sin(arg1)
}
}
if modn == 0 {
// This is how it was written in FFTPACK.
sum += 0.5 * math.Pow(-1, float64(i)) * x[test.n-1]
}
y[i] = 2 * sum
}
Rfftb(test.n, x, work, ifac)
var rftb float64
for i := 0; i < test.n; i++ {
rftb = math.Max(rftb, math.Abs(x[i]-y[i]))
x[i] = xh[i]
y[i] = xh[i]
}
if !floats.EqualWithinAbsOrRel(rftb, 0, tol, tol) {
t.Errorf("unexpected rftb value for n=%d: got:%f want:0", test.n, rftb)
}
// Check that Rfftb and Rfftf are inverses.
Rfftb(test.n, y, work, ifac)
Rfftf(test.n, y, work, ifac)
cf := 1.0 / fn
var rftfb float64
for i := 0; i < test.n; i++ {
rftfb = math.Max(rftfb, math.Abs(cf*y[i]-x[i]))
}
if !floats.EqualWithinAbsOrRel(rftfb, 0, tol, tol) {
t.Errorf("unexpected rftfb value for n=%d: got:%f want:0", test.n, rftfb)
}
}
}
var rfftTests = []struct {
n int
// The following two fields are added as there is no unit testing in
// FFTPACK for RFFTI.
//
// wantiwork is obtained from the FFTPACK test.f with modification.
// The W array is zeroed at each iteration and the first 2n elements
// of W are printed after the call to RFFTI.
wantiwork []float64
// wantiifac is obtained from the FFTPACK rffti1.f with modification.
// The IFAC array is zeroed at each iteration of test.f and the 15 elements
// of IFAC are printed before RFFTI1 returns.
wantiifac []int
}{
{
n: 120,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.9986295, 0.5233596E-01, 0.9945219, 0.1045285, 0.9876884, 0.1564345, 0.9781476, 0.2079117,
0.9659258, 0.2588190, 0.9510565, 0.3090170, 0.9335804, 0.3583679, 0.9135454, 0.4067366,
0.8910065, 0.4539905, 0.8660254, 0.5000000, 0.8386706, 0.5446391, 0.8090170, 0.5877852,
0.7771459, 0.6293204, 0.7431448, 0.6691306, 0.7071068, 0.7071068, 0.6691306, 0.7431449,
0.6293204, 0.7771460, 0.5877852, 0.8090170, 0.5446390, 0.8386706, 0.5000000, 0.8660254,
0.4539905, 0.8910065, 0.4067366, 0.9135455, 0.3583679, 0.9335805, 0.3090170, 0.9510565,
0.2588191, 0.9659258, 0.2079117, 0.9781476, 0.1564344, 0.9876884, 0.1045284, 0.9945219,
0.5233597E-01, 0.9986295, 0.000000, 0.000000, 0.9945219, 0.1045285, 0.9781476, 0.2079117,
0.9510565, 0.3090170, 0.9135454, 0.4067366, 0.8660254, 0.5000000, 0.8090170, 0.5877852,
0.7431448, 0.6691306, 0.000000, 0.9781476, 0.2079117, 0.9135454, 0.4067366, 0.8090170,
0.5877852, 0.6691306, 0.7431449, 0.5000000, 0.8660254, 0.3090170, 0.9510565, 0.1045284,
0.9945219, 0.000000, 0.9510565, 0.3090170, 0.8090170, 0.5877852, 0.5877852, 0.8090170,
0.3090170, 0.9510565, -0.4371139E-07, 1.000000, -0.3090170, 0.9510565, -0.5877852, 0.8090170,
0.000000, 0.9135454, 0.4067366, 0.6691306, 0.7431449, 0.000000, 0.6691306, 0.7431449,
-0.1045285, 0.9945219, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{120, 4, 2, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 54,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.9932383, 0.1160929,
0.9730449, 0.2306159, 0.9396926, 0.3420201, 0.8936327, 0.4487992, 0.8354878, 0.5495090,
0.7660444, 0.6427876, 0.6862416, 0.7273737, 0.5971586, 0.8021232, 0.5000000, 0.8660254,
0.3960797, 0.9182161, 0.2868032, 0.9579895, 0.1736482, 0.9848077, 0.5814485E-01, 0.9983082,
0.000000, 0.9730449, 0.2306159, 0.8936327, 0.4487992, 0.7660444, 0.6427876, 0.5971586,
0.8021232, 0.000000, 0.8936327, 0.4487992, 0.5971586, 0.8021232, 0.1736482, 0.9848077,
-0.2868032, 0.9579895, 0.000000, 0.7660444, 0.6427876, 0.000000, 0.1736482, 0.9848077,
0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{54, 4, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 49,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.9917900, 0.1278772, 0.9672949, 0.2536546, 0.9269168, 0.3752670, 0.000000,
0.9672949, 0.2536546, 0.8713187, 0.4907176, 0.7183493, 0.6956826, 0.000000, 0.9269168,
0.3752670, 0.7183493, 0.6956826, 0.4047833, 0.9144127, 0.000000, 0.8713187, 0.4907176,
0.5183925, 0.8551428, 0.3205151E-01, 0.9994862, 0.000000, 0.8014136, 0.5981106, 0.2845275,
0.9586679, -0.3453652, 0.9384683, 0.000000, 0.7183493, 0.6956826, 0.3205151E-01, 0.9994862,
-0.6723010, 0.7402779, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000,
},
wantiifac: []int{49, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 32,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.9807853, 0.1950903, 0.9238795, 0.3826835, 0.8314696, 0.5555702, 0.7071068, 0.7071068,
0.5555702, 0.8314697, 0.3826834, 0.9238795, 0.1950902, 0.9807853, 0.000000, 0.000000,
0.9238795, 0.3826835, 0.000000, 0.000000, 0.7071068, 0.7071068, 0.000000, 0.000000,
0.3826834, 0.9238795, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{32, 3, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 25,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.968583, 0.248690, 0.876307, 0.481754, 0.00000, 0.876307, 0.481754,
0.535827, 0.844328, 0.00000, 0.728969, 0.684547, 0.627904E-01, 0.998027, 0.00000,
0.535827, 0.844328, -0.425779, 0.904827, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000,
},
wantiifac: []int{25, 2, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 4,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{4, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 3,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 2,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
func TestCfft(t *testing.T) {
const tol = 1e-12
for _, test := range cfftTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 4*test.n)
ifac := make([]int, 15)
Cffti(test.n, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to cffti for n=%d", test.n)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to cffti for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
fn := float64(test.n)
cn := complex(fn, 0)
x, y1 := cmplxSeries(test.n)
cx := cmplxAsFloat(x)
Cfftf(test.n, cx, work, ifac)
x = floatAsCmplx(cx)
var cftf float64
for i := 0; i < test.n; i++ {
cftf = math.Max(cftf, cmplx.Abs(x[i]-y1[i]))
x[i] /= cn
}
cftf /= fn
if !floats.EqualWithinAbsOrRel(cftf, 0, tol, tol) {
t.Errorf("unexpected cftf value for n=%d: got:%f want:0", test.n, cftf)
}
// Construct a frequency spectrum and compare the computed sequence.
y2 := updatedCmplxSeries(x)
cx = cmplxAsFloat(x)
Cfftb(test.n, cx, work, ifac)
x = floatAsCmplx(cx)
var cftb float64
for i := 0; i < test.n; i++ {
cftb = math.Max(cftb, cmplx.Abs(x[i]-y2[i]))
x[i] = y2[i]
}
if !floats.EqualWithinAbsOrRel(cftb, 0, tol, tol) {
t.Errorf("unexpected cftb value for n=%d: got:%f want:0", test.n, cftb)
}
// Check that Cfftb and Cfftf are inverses.
cx = cmplxAsFloat(x)
Cfftf(test.n, cx, work, ifac)
Cfftb(test.n, cx, work, ifac)
x = floatAsCmplx(cx)
var cftfb float64
for i := 0; i < test.n; i++ {
cftfb = math.Max(cftfb, cmplx.Abs(x[i]/cn-y2[i]))
}
if !floats.EqualWithinAbsOrRel(cftfb, 0, tol, tol) {
t.Errorf("unexpected cftfb value for n=%d: got:%f want:0", test.n, cftfb)
}
}
}
func cmplxSeries(n int) (x, y []complex128) {
x = make([]complex128, n)
for i := 0; i < n; i++ {
x[i] = complex(math.Cos(math.Sqrt2*float64(i+1)), math.Sin(math.Sqrt2*float64((i+1)*(i+1))))
}
y = make([]complex128, n)
dt := 2 * math.Pi / float64(n)
for i := 0; i < n; i++ {
arg1 := -float64(i) * dt
for k := 0; k < n; k++ {
arg2 := float64(k) * arg1
y[i] += complex(math.Cos(arg2), math.Sin(arg2)) * x[k]
}
}
return x, y
}
func updatedCmplxSeries(x []complex128) (y []complex128) {
y = make([]complex128, len(x))
dt := 2 * math.Pi / float64(len(x))
for i := range x {
arg1 := float64(i) * dt
for k, xv := range x {
arg2 := float64(k) * arg1
y[i] += complex(math.Cos(arg2), math.Sin(arg2)) * xv
}
}
return y
}
func cmplxAsFloat(c []complex128) []float64 {
f := make([]float64, 2*len(c))
for i, v := range c {
f[2*i] = real(v)
f[2*i+1] = imag(v)
}
return f
}
func floatAsCmplx(f []float64) []complex128 {
c := make([]complex128, len(f)/2)
for i := range c {
c[i] = complex(f[2*i], f[2*i+1])
}
return c
}
var cfftTests = []struct {
n int
// The following two fields are added as there is no unit testing in
// FFTPACK for RFFTI.
//
// wantiwork is obtained from the FFTPACK test.f with modification.
// The W array is zeroed at each iteration and the first 4n elements
// of W are printed after the call to RFFTI.
wantiwork []float64
// wantiifac is obtained from the FFTPACK rffti1.f with modification.
// The IFAC array is zeroed at each iteration of test.f and the 15 elements
// of IFAC are printed before RFFTI1 returns.
wantiifac []int
}{
{
n: 120,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
1.00000, 0.00000, 0.998630, 0.523360E-01, 0.994522, 0.104528, 0.987688, 0.156434,
0.978148, 0.207912, 0.965926, 0.258819, 0.951057, 0.309017, 0.933580, 0.358368,
0.913545, 0.406737, 0.891007, 0.453991, 0.866025, 0.500000, 0.838671, 0.544639,
0.809017, 0.587785, 0.777146, 0.629320, 0.743145, 0.669131, 0.707107, 0.707107,
0.669131, 0.743145, 0.629320, 0.777146, 0.587785, 0.809017, 0.544639, 0.838671,
0.500000, 0.866025, 0.453991, 0.891007, 0.406737, 0.913545, 0.358368, 0.933580,
0.309017, 0.951057, 0.258819, 0.965926, 0.207912, 0.978148, 0.156434, 0.987688,
0.104528, 0.994522, 0.523360E-01, 0.998630, -0.437114E-07, 1.00000, -0.523361E-01, 0.998630,
-0.104529, 0.994522, -0.156434, 0.987688, -0.207912, 0.978148, -0.258819, 0.965926,
-0.309017, 0.951056, -0.358368, 0.933580, -0.406737, 0.913545, -0.453991, 0.891006,
-0.500000, 0.866025, -0.544639, 0.838671, -0.587785, 0.809017, -0.629321, 0.777146,
-0.669131, 0.743145, -0.707107, 0.707107, -0.743145, 0.669130, -0.777146, 0.629320,
-0.809017, 0.587785, -0.838671, 0.544639, -0.866025, 0.500000, -0.891007, 0.453990,
-0.913545, 0.406737, -0.933580, 0.358368, -0.951057, 0.309017, -0.965926, 0.258819,
-0.978148, 0.207912, -0.987688, 0.156434, -0.994522, 0.104528, -0.998630, 0.523358E-01,
1.00000, 0.00000, 0.994522, 0.104528, 0.978148, 0.207912, 0.951057, 0.309017,
0.913545, 0.406737, 0.866025, 0.500000, 0.809017, 0.587785, 0.743145, 0.669131,
0.669131, 0.743145, 0.587785, 0.809017, 0.500000, 0.866025, 0.406737, 0.913545,
0.309017, 0.951057, 0.207912, 0.978148, 0.104528, 0.994522, -0.437114E-07, 1.00000,
-0.104529, 0.994522, -0.207912, 0.978148, -0.309017, 0.951056, -0.406737, 0.913545,
1.00000, 0.00000, 0.978148, 0.207912, 0.913545, 0.406737, 0.809017, 0.587785,
0.669131, 0.743145, 0.500000, 0.866025, 0.309017, 0.951057, 0.104528, 0.994522,
-0.104529, 0.994522, -0.309017, 0.951056, -0.500000, 0.866025, -0.669131, 0.743145,
-0.809017, 0.587785, -0.913545, 0.406737, -0.978148, 0.207912, -1.00000, -0.874228E-07,
-0.978148, -0.207912, -0.913545, -0.406737, -0.809017, -0.587785, -0.669131, -0.743145,
1.00000, 0.00000, 0.951057, 0.309017, 0.809017, 0.587785, 0.587785, 0.809017,
0.309017, 0.951057, 1.00000, 0.00000, 0.809017, 0.587785, 0.309017, 0.951057,
-0.309017, 0.951056, -0.809017, 0.587785, 1.00000, 0.00000, 0.587785, 0.809017,
-0.309017, 0.951056, -0.951057, 0.309017, -0.809017, -0.587785, 1.00000, 0.00000,
1.00000, 0.00000, 1.00000, 0.00000, 1.00000, 0.00000, 0.309017, -0.951056,
},
wantiifac: []int{120, 4, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 54,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, 0.993238, 0.116093,
0.973045, 0.230616, 0.939693, 0.342020, 0.893633, 0.448799, 0.835488, 0.549509,
0.766044, 0.642788, 0.686242, 0.727374, 0.597159, 0.802123, 0.500000, 0.866025,
0.396080, 0.918216, 0.286803, 0.957990, 0.173648, 0.984808, 0.581449E-01, 0.998308,
-0.581448E-01, 0.998308, -0.173648, 0.984808, -0.286803, 0.957990, -0.396080, 0.918216,
-0.500000, 0.866025, -0.597159, 0.802123, -0.686242, 0.727374, -0.766044, 0.642788,
-0.835488, 0.549509, -0.893633, 0.448799, -0.939693, 0.342020, -0.973045, 0.230616,
-0.993238, 0.116093, 1.00000, 0.00000, 0.973045, 0.230616, 0.893633, 0.448799,
0.766044, 0.642788, 0.597159, 0.802123, 0.396080, 0.918216, 0.173648, 0.984808,
-0.581448E-01, 0.998308, -0.286803, 0.957990, 1.00000, 0.00000, 0.893633, 0.448799,
0.597159, 0.802123, 0.173648, 0.984808, -0.286803, 0.957990, -0.686242, 0.727374,
-0.939693, 0.342020, -0.993238, -0.116093, -0.835488, -0.549509, 1.00000, 0.00000,
0.766044, 0.642788, 0.173648, 0.984808, 1.00000, 0.00000, 0.173648, 0.984808,
-0.939693, 0.342020, 1.00000, 0.00000, 1.00000, 0.00000, -0.500000, -0.866025,
},
wantiifac: []int{54, 4, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 49,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.623490, 0.781832, 0.991790, 0.127877, 0.967295, 0.253655,
0.926917, 0.375267, 0.871319, 0.490718, 0.801414, 0.598111, 0.718349, 0.695683,
-0.222521, 0.974928, 0.967295, 0.253655, 0.871319, 0.490718, 0.718349, 0.695683,
0.518393, 0.855143, 0.284527, 0.958668, 0.320515E-01, 0.999486, -0.900969, 0.433884,
0.926917, 0.375267, 0.718349, 0.695683, 0.404783, 0.914413, 0.320515E-01, 0.999486,
-0.345365, 0.938468, -0.672301, 0.740278, -0.900969, -0.433884, 0.871319, 0.490718,
0.518393, 0.855143, 0.320515E-01, 0.999486, -0.462538, 0.886599, -0.838088, 0.545535,
-0.997945, 0.640701E-01, -0.222521, -0.974928, 0.801414, 0.598111, 0.284527, 0.958668,
-0.345365, 0.938468, -0.838088, 0.545535, -0.997945, -0.640705E-01, -0.761446, -0.648229,
0.623490, -0.781831, 0.718349, 0.695683, 0.320515E-01, 0.999486, -0.672301, 0.740278,
-0.997945, 0.640701E-01, -0.761446, -0.648228, -0.960227E-01, -0.995379, 0.623490, 0.781832,
-0.222521, 0.974928, -0.900969, 0.433884, -0.900969, -0.433884, -0.222521, -0.974928,
0.623490, -0.781831, 0.623490, -0.781831,
},
wantiifac: []int{49, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 32,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
1.00000, 0.00000, 0.980785, 0.195090, 0.923880, 0.382683, 0.831470, 0.555570,
0.707107, 0.707107, 0.555570, 0.831470, 0.382683, 0.923880, 0.195090, 0.980785,
-0.437114E-07, 1.00000, -0.195090, 0.980785, -0.382684, 0.923880, -0.555570, 0.831470,
-0.707107, 0.707107, -0.831470, 0.555570, -0.923880, 0.382683, -0.980785, 0.195090,
1.00000, 0.00000, 0.923880, 0.382683, 0.707107, 0.707107, 0.382683, 0.923880,
1.00000, 0.00000, 0.707107, 0.707107, -0.437114E-07, 1.00000, -0.707107, 0.707107,
1.00000, 0.00000, 0.382683, 0.923880, -0.707107, 0.707107, -0.923880, -0.382683,
1.00000, 0.00000, 1.00000, 0.00000, 1.00000, 0.00000, 0.119249E-07, -1.00000,
},
wantiifac: []int{32, 3, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 25,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.00000, 0.00000, 1.00000, 0.00000, 0.968583, 0.248690, 0.876307, 0.481754,
0.728969, 0.684547, 0.535827, 0.844328, 1.00000, 0.00000, 0.876307, 0.481754,
0.535827, 0.844328, 0.627904E-01, 0.998027, -0.425779, 0.904827, 1.00000, 0.00000,
0.728969, 0.684547, 0.627904E-01, 0.998027, -0.637424, 0.770513, -0.992115, 0.125333,
1.00000, 0.00000, 0.535827, 0.844328, -0.425779, 0.904827, -0.992115, 0.125333,
-0.637424, -0.770513, 1.00000, 0.00000, 1.00000, 0.00000, 1.00000, 0.00000,
1.00000, 0.00000, 0.309017, -0.951056,
},
wantiifac: []int{25, 2, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 4,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
1.00000, 0.00000, 1.00000, 0.00000, 1.00000, 0.00000, 0.119249E-07, -1.00000,
},
wantiifac: []int{4, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 3,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000,
1.00000, 0.00000, -0.500000, -0.866025,
},
wantiifac: []int{3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 2,
wantiwork: []float64{
0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 0.00000, -1.00000, -0.874228E-07,
},
wantiifac: []int{2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
func TestSint(t *testing.T) {
const tol = 1e-12
for _, test := range sintTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 5*(test.n)/2)
ifac := make([]int, 15)
Sinti(test.n-1, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to sinti for n=%d", test.n)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to sinti for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
fn := float64(test.n)
x, _, xh := series(test.n - 1)
y := make([]float64, test.n-1)
dt := math.Pi / fn
for i := 0; i < test.n-1; i++ {
arg1 := float64(i+1) * dt
for k := 0; k < test.n-1; k++ { //eek
y[i] += x[k] * math.Sin(float64(k+1)*arg1)
}
y[i] *= 2
}
Sint(test.n-1, x, work, ifac)
cf := 0.5 / fn
var sintt float64
for i := 0; i < test.n-1; i++ {
sintt = math.Max(sintt, math.Abs(x[i]-y[i]))
x[i] = xh[i]
y[i] = x[i]
}
sintt *= cf
if !floats.EqualWithinAbsOrRel(sintt, 0, tol, tol) {
t.Errorf("unexpected sintt value for n=%d: got:%f want:0", test.n, sintt)
}
// Check that the transform is its own inverse.
Sint(test.n-1, x, work, ifac)
Sint(test.n-1, x, work, ifac)
var sintfb float64
for i := 0; i < test.n-1; i++ {
sintfb = math.Max(sintfb, math.Abs(cf*x[i]-y[i]))
}
if !floats.EqualWithinAbsOrRel(sintfb, 0, tol, tol) {
t.Errorf("unexpected sintfb value for n=%d: got:%f want:0", test.n, sintfb)
}
}
}
var sintTests = []struct {
n int
// The following two fields are added as there is no unit testing in
// FFTPACK for SINTI.
//
// wantiwork is obtained from the FFTPACK test.f with modification.
// The W array is zeroed at each iteration and the first 2.5n elements
// of W are printed after the call to RFFTI.
wantiwork []float64
// wantiifac is obtained from the FFTPACK sint.f with modification.
// The IFAC array is zeroed at each iteration of test.f and the 15 elements
// of IFAC are printed before RFFTI returns.
wantiifac []int
}{
{
n: 120,
wantiwork: []float64{
0.5235390E-01, 0.1046719, 0.1569182, 0.2090569, 0.2610524, 0.3128690, 0.3644710, 0.4158234,
0.4668908, 0.5176381, 0.5680307, 0.6180340, 0.6676137, 0.7167359, 0.7653669, 0.8134733,
0.8610222, 0.9079810, 0.9543176, 1.000000, 1.044997, 1.089278, 1.132812, 1.175570,
1.217523, 1.258641, 1.298896, 1.338261, 1.376709, 1.414214, 1.450749, 1.486290,
1.520812, 1.554292, 1.586707, 1.618034, 1.648252, 1.677341, 1.705280, 1.732051,
1.757634, 1.782013, 1.805171, 1.827091, 1.847759, 1.867161, 1.885283, 1.902113,
1.917639, 1.931852, 1.944740, 1.956295, 1.966510, 1.975377, 1.982890, 1.989044,
1.993835, 1.997259, 1.999315, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.9986295, 0.5233596E-01, 0.9945219, 0.1045285, 0.9876884,
0.1564345, 0.9781476, 0.2079117, 0.9659258, 0.2588190, 0.9510565, 0.3090170, 0.9335804,
0.3583679, 0.9135454, 0.4067366, 0.8910065, 0.4539905, 0.8660254, 0.5000000, 0.8386706,
0.5446391, 0.8090170, 0.5877852, 0.7771459, 0.6293204, 0.7431448, 0.6691306, 0.7071068,
0.7071068, 0.6691306, 0.7431449, 0.6293204, 0.7771460, 0.5877852, 0.8090170, 0.5446390,
0.8386706, 0.5000000, 0.8660254, 0.4539905, 0.8910065, 0.4067366, 0.9135455, 0.3583679,
0.9335805, 0.3090170, 0.9510565, 0.2588191, 0.9659258, 0.2079117, 0.9781476, 0.1564344,
0.9876884, 0.1045284, 0.9945219, 0.5233597E-01, 0.9986295, 0.000000, 0.000000, 0.9945219,
0.1045285, 0.9781476, 0.2079117, 0.9510565, 0.3090170, 0.9135454, 0.4067366, 0.8660254,
0.5000000, 0.8090170, 0.5877852, 0.7431448, 0.6691306, 0.000000, 0.9781476, 0.2079117,
0.9135454, 0.4067366, 0.8090170, 0.5877852, 0.6691306, 0.7431449, 0.5000000, 0.8660254,
0.3090170, 0.9510565, 0.1045284, 0.9945219, 0.000000, 0.9510565, 0.3090170, 0.8090170,
0.5877852, 0.5877852, 0.8090170, 0.3090170, 0.9510565, -0.4371139E-07, 1.000000, -0.3090170,
0.9510565, -0.5877852, 0.8090170, 0.000000, 0.9135454, 0.4067366, 0.6691306, 0.7431449,
0.000000, 0.6691306, 0.7431449, -0.1045285, 0.9945219, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.1681558E-42,
},
wantiifac: []int{120, 4, 2, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 54,
wantiwork: []float64{
0.1162897, 0.2321858, 0.3472964, 0.4612317, 0.5736065, 0.6840402, 0.7921596, 0.8975984,
1.000000, 1.099018, 1.194317, 1.285575, 1.372483, 1.454747, 1.532089, 1.604246,
1.670976, 1.732051, 1.787265, 1.836432, 1.879385, 1.915979, 1.946090, 1.969615,
1.986477, 1.996616, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.9932383, 0.1160929, 0.9730449, 0.2306159, 0.9396926, 0.3420201, 0.8936327, 0.4487992,
0.8354878, 0.5495090, 0.7660444, 0.6427876, 0.6862416, 0.7273737, 0.5971586, 0.8021232,
0.5000000, 0.8660254, 0.3960797, 0.9182161, 0.2868032, 0.9579895, 0.1736482, 0.9848077,
0.5814485E-01, 0.9983082, 0.000000, 0.9730449, 0.2306159, 0.8936327, 0.4487992, 0.7660444,
0.6427876, 0.5971586, 0.8021232, 0.000000, 0.8936327, 0.4487992, 0.5971586, 0.8021232,
0.1736482, 0.9848077, -0.2868032, 0.9579895, 0.000000, 0.7660444, 0.6427876, 0.000000,
0.1736482, 0.9848077, 0.000000, 0.000000, 0.000000, 0.000000, 0.7567012E-43,
},
wantiifac: []int{54, 4, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 49,
wantiwork: []float64{
0.1281404, 0.2557543, 0.3823173, 0.5073092, 0.6302165, 0.7505341, 0.8677675, 0.9814351,
1.091070, 1.196221, 1.296457, 1.391365, 1.480556, 1.563663, 1.640345, 1.710286,
1.773199, 1.828825, 1.876937, 1.917336, 1.949856, 1.974364, 1.990758, 1.998972,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.9917900, 0.1278772, 0.9672949, 0.2536546, 0.9269168, 0.3752670, 0.000000,
0.9672949, 0.2536546, 0.8713187, 0.4907176, 0.7183493, 0.6956826, 0.000000, 0.9269168,
0.3752670, 0.7183493, 0.6956826, 0.4047833, 0.9144127, 0.000000, 0.8713187, 0.4907176,
0.5183925, 0.8551428, 0.3205151E-01, 0.9994862, 0.000000, 0.8014136, 0.5981106, 0.2845275,
0.9586679, -0.3453652, 0.9384683, 0.000000, 0.7183493, 0.6956826, 0.3205151E-01, 0.9994862,
-0.6723010, 0.7402779, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000,
},
wantiifac: []int{49, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 32,
wantiwork: []float64{
0.1960343, 0.3901806, 0.5805693, 0.7653669, 0.9427935, 1.111140, 1.268787, 1.414214,
1.546021, 1.662939, 1.763843, 1.847759, 1.913881, 1.961571, 1.990369, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.9807853,
0.1950903, 0.9238795, 0.3826835, 0.8314696, 0.5555702, 0.7071068, 0.7071068, 0.5555702,
0.8314697, 0.3826834, 0.9238795, 0.1950902, 0.9807853, 0.000000, 0.000000, 0.9238795,
0.3826835, 0.000000, 0.000000, 0.7071068, 0.7071068, 0.000000, 0.000000, 0.3826834,
0.9238795, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.4484155E-43,
},
wantiifac: []int{32, 3, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 25,
wantiwork: []float64{
0.2506665, 0.4973798, 0.7362491, 0.9635074, 1.175570, 1.369094, 1.541027, 1.688656,
1.809654, 1.902113, 1.964575, 1.996053, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.9685832, 0.2486899, 0.8763067,
0.4817537, 0.000000, 0.8763067, 0.4817537, 0.5358267, 0.8443279, 0.000000, 0.7289686,
0.6845471, 0.6279038E-01, 0.9980267, 0.000000, 0.5358267, 0.8443279, -0.4257794, 0.9048270,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{25, 2, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 4,
wantiwork: []float64{
1.414214, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000,
},
wantiifac: []int{4, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 3,
wantiwork: []float64{
1.732051, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 2,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
func TestCost(t *testing.T) {
const tol = 1e-12
for _, test := range costTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 3*(test.n+1))
ifac := make([]int, 15)
Costi(test.n+1, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to costi for n=%d", test.n)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to costi for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
fn := float64(test.n)
x, _, xh := series(test.n + 1)
y := make([]float64, test.n+1)
dt := math.Pi / fn
for i := 0; i < test.n+1; i++ {
y[i] = 0.5 * (x[0] + math.Pow(-1, float64(i))*x[test.n])
arg1 := float64(i) * dt
for k := 1; k < test.n; k++ { //eek
y[i] += x[k] * math.Cos(float64(k)*arg1)
}
y[i] *= 2
}
Cost(test.n+1, x, work, ifac)
cf := 0.5 / fn
var costt float64
for i := 0; i < test.n; i++ {
costt = math.Max(costt, math.Abs(x[i]-y[i]))
x[i] = xh[i]
y[i] = x[i]
}
costt *= cf
if !floats.EqualWithinAbsOrRel(costt, 0, tol, tol) {
t.Errorf("unexpected costt value for n=%d: got:%f want:0", test.n, costt)
}
// Check that the transform is its own inverse.
Cost(test.n+1, x, work, ifac)
Cost(test.n+1, x, work, ifac)
var costfb float64
for i := 0; i < test.n-1; i++ {
costfb = math.Max(costfb, math.Abs(cf*x[i]-y[i]))
}
if !floats.EqualWithinAbsOrRel(costfb, 0, tol, tol) {
t.Errorf("unexpected costfb value for n=%d: got:%f want:0", test.n, costfb)
}
}
}
var costTests = []struct {
n int
// The following two fields are added as there is no unit testing in
// FFTPACK for SINTI.
//
// wantiwork is obtained from the FFTPACK test.f with modification.
// The W array is zeroed at each iteration and the first 3n elements
// of W are printed after the call to RFFTI.
wantiwork []float64
// wantiifac is obtained from the FFTPACK sint.f with modification.
// The IFAC array is zeroed at each iteration of test.f and the 15 elements
// of IFAC are printed before RFFTI returns.
wantiifac []int
}{
{
n: 120,
wantiwork: []float64{
0.000000, 0.5235390E-01, 0.1046719, 0.1569182, 0.2090569, 0.2610524, 0.3128690, 0.3644710,
0.4158234, 0.4668908, 0.5176381, 0.5680307, 0.6180340, 0.6676137, 0.7167359, 0.7653669,
0.8134733, 0.8610222, 0.9079810, 0.9543176, 1.000000, 1.044997, 1.089278, 1.132812,
1.175570, 1.217523, 1.258641, 1.298896, 1.338261, 1.376709, 1.414214, 1.450749,
1.486290, 1.520812, 1.554292, 1.586707, 1.618034, 1.648252, 1.677341, 1.705280,
1.732051, 1.757634, 1.782013, 1.805171, 1.827091, 1.847759, 1.867161, 1.885283,
1.902113, 1.917639, 1.931852, 1.944740, 1.956295, 1.966510, 1.975377, 1.982890,
1.989044, 1.993835, 1.997259, 1.999315, 0.000000, 0.5235375E-01, 0.1046719, 0.1569182,
0.2090568, 0.2610523, 0.3128687, 0.3644710, 0.4158233, 0.4668906, 0.5176381, 0.5680307,
0.6180339, 0.6676136, 0.7167357, 0.7653669, 0.8134732, 0.8610221, 0.9079810, 0.9543175,
1.000000, 1.044997, 1.089278, 1.132812, 1.175570, 1.217523, 1.258641, 1.298896,
1.338261, 1.376709, 1.414214, 1.450749, 1.486290, 1.520812, 1.554292, 1.586707,
1.618034, 1.648252, 1.677341, 1.705280, 1.732051, 1.757634, 1.782013, 1.805171,
1.827091, 1.847759, 1.867161, 1.885283, 1.902113, 1.917639, 1.931852, 1.944740,
1.956295, 1.966510, 1.975377, 1.982890, 1.989044, 1.993835, 1.997259, 1.999315,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.9986295, 0.5233596E-01, 0.9945219, 0.1045285, 0.9876884, 0.1564345, 0.9781476,
0.2079117, 0.9659258, 0.2588190, 0.9510565, 0.3090170, 0.9335804, 0.3583679, 0.9135454,
0.4067366, 0.8910065, 0.4539905, 0.8660254, 0.5000000, 0.8386706, 0.5446391, 0.8090170,
0.5877852, 0.7771459, 0.6293204, 0.7431448, 0.6691306, 0.7071068, 0.7071068, 0.6691306,
0.7431449, 0.6293204, 0.7771460, 0.5877852, 0.8090170, 0.5446390, 0.8386706, 0.5000000,
0.8660254, 0.4539905, 0.8910065, 0.4067366, 0.9135455, 0.3583679, 0.9335805, 0.3090170,
0.9510565, 0.2588191, 0.9659258, 0.2079117, 0.9781476, 0.1564344, 0.9876884, 0.1045284,
0.9945219, 0.5233597E-01, 0.9986295, 0.000000, 0.000000, 0.9945219, 0.1045285, 0.9781476,
0.2079117, 0.9510565, 0.3090170, 0.9135454, 0.4067366, 0.8660254, 0.5000000, 0.8090170,
0.5877852, 0.7431448, 0.6691306, 0.000000, 0.9781476, 0.2079117, 0.9135454, 0.4067366,
0.8090170, 0.5877852, 0.6691306, 0.7431449, 0.5000000, 0.8660254, 0.3090170, 0.9510565,
0.1045284, 0.9945219, 0.000000, 0.9510565, 0.3090170, 0.8090170, 0.5877852, 0.5877852,
0.8090170, 0.3090170, 0.9510565, -0.4371139E-07, 1.000000, -0.3090170, 0.9510565, -0.5877852,
0.8090170, 0.000000, 0.9135454, 0.4067366, 0.6691306, 0.7431449, 0.000000, 0.6691306,
0.7431449, -0.1045285, 0.9945219, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.1681558E-42, 0.5605194E-44,
},
wantiifac: []int{120, 4, 2, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 54,
wantiwork: []float64{
0.000000, 0.1162897, 0.2321858, 0.3472964, 0.4612317, 0.5736065, 0.6840402, 0.7921596,
0.8975984, 1.000000, 1.099018, 1.194317, 1.285575, 1.372483, 1.454747, 1.532089,
1.604246, 1.670976, 1.732051, 1.787265, 1.836432, 1.879385, 1.915979, 1.946090,
1.969615, 1.986477, 1.996616, 0.000000, 0.1162897, 0.2321858, 0.3472964, 0.4612317,
0.5736064, 0.6840403, 0.7921594, 0.8975984, 1.000000, 1.099018, 1.194317, 1.285575,
1.372483, 1.454747, 1.532089, 1.604246, 1.670976, 1.732051, 1.787265, 1.836432,
1.879385, 1.915979, 1.946090, 1.969615, 1.986477, 1.996616, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.9932383, 0.1160929, 0.9730449,
0.2306159, 0.9396926, 0.3420201, 0.8936327, 0.4487992, 0.8354878, 0.5495090, 0.7660444,
0.6427876, 0.6862416, 0.7273737, 0.5971586, 0.8021232, 0.5000000, 0.8660254, 0.3960797,
0.9182161, 0.2868032, 0.9579895, 0.1736482, 0.9848077, 0.5814485E-01, 0.9983082, 0.000000,
0.9730449, 0.2306159, 0.8936327, 0.4487992, 0.7660444, 0.6427876, 0.5971586, 0.8021232,
0.000000, 0.8936327, 0.4487992, 0.5971586, 0.8021232, 0.1736482, 0.9848077, -0.2868032,
0.9579895, 0.000000, 0.7660444, 0.6427876, 0.000000, 0.1736482, 0.9848077, 0.000000,
0.000000, 0.000000, 0.000000, 0.7567012E-43, 0.5605194E-44,
},
wantiifac: []int{54, 4, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 49,
wantiwork: []float64{
0.000000, 0.1281404, 0.2557543, 0.3823173, 0.5073092, 0.6302165, 0.7505341, 0.8677675,
0.9814351, 1.091070, 1.196221, 1.296457, 1.391365, 1.480556, 1.563663, 1.640345,
1.710286, 1.773199, 1.828825, 1.876937, 1.917336, 1.949856, 1.974364, 1.990758,
1.998972, 0.6410302E-01, 0.1920458, 0.3191997, 0.4450417, 0.5690550, 0.6907300, 0.8095666,
0.9250766, 1.036785, 1.144233, 1.246980, 1.344602, 1.436699, 1.522892, 1.602827,
1.676176, 1.742637, 1.801938, 1.853834, 1.898111, 1.934590, 1.963118, 1.983580,
1.995891, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.9917900, 0.1278772, 0.9672949, 0.2536546, 0.9269168,
0.3752670, 0.000000, 0.9672949, 0.2536546, 0.8713187, 0.4907176, 0.7183493, 0.6956826,
0.000000, 0.9269168, 0.3752670, 0.7183493, 0.6956826, 0.4047833, 0.9144127, 0.000000,
0.8713187, 0.4907176, 0.5183925, 0.8551428, 0.3205151E-01, 0.9994862, 0.000000, 0.8014136,
0.5981106, 0.2845275, 0.9586679, -0.3453652, 0.9384683, 0.000000, 0.7183493, 0.6956826,
0.3205151E-01, 0.9994862, -0.6723010, 0.7402779, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.6866362E-43, 0.2802597E-44,
},
wantiifac: []int{49, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 32,
wantiwork: []float64{
0.000000, 0.1960343, 0.3901806, 0.5805693, 0.7653669, 0.9427935, 1.111140, 1.268787,
1.414214, 1.546021, 1.662939, 1.763843, 1.847759, 1.913881, 1.961571, 1.990369,
0.000000, 0.1960343, 0.3901805, 0.5805693, 0.7653669, 0.9427933, 1.111140, 1.268787,
1.414214, 1.546021, 1.662939, 1.763842, 1.847759, 1.913881, 1.961571, 1.990369,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.9807853, 0.1950903, 0.9238795, 0.3826835, 0.8314696, 0.5555702, 0.7071068,
0.7071068, 0.5555702, 0.8314697, 0.3826834, 0.9238795, 0.1950902, 0.9807853, 0.000000,
0.000000, 0.9238795, 0.3826835, 0.000000, 0.000000, 0.7071068, 0.7071068, 0.000000,
0.000000, 0.3826834, 0.9238795, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.4484155E-43, 0.4203895E-44,
},
wantiifac: []int{32, 3, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 25,
wantiwork: []float64{
0.000000, 0.2506665, 0.4973798, 0.7362491, 0.9635074, 1.175570, 1.369094, 1.541027,
1.688656, 1.809654, 1.902113, 1.964575, 1.996053, 0.1255808, 0.3747624, 0.6180339,
0.8515584, 1.071653, 1.274848, 1.457937, 1.618034, 1.752613, 1.859553, 1.937166,
1.984229, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.9685832, 0.2486899, 0.8763067, 0.4817537, 0.000000,
0.8763067, 0.4817537, 0.5358267, 0.8443279, 0.000000, 0.7289686, 0.6845471, 0.6279038E-01,
0.9980267, 0.000000, 0.5358267, 0.8443279, -0.4257794, 0.9048270, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.3503246E-43, 0.2802597E-44,
},
wantiifac: []int{25, 2, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 4,
wantiwork: []float64{
0.000000, 1.414214, 0.000000, 1.414214, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.5605194E-44, 0.1401298E-44,
},
wantiifac: []int{4, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 3,
wantiwork: []float64{
0.000000, 1.732051, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.4203895E-44, 0.1401298E-44,
},
wantiifac: []int{3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 2,
wantiwork: []float64{
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000,
},
wantiifac: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
func TestCosq(t *testing.T) {
const tol = 1e-12
for _, test := range sincosqTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 3*test.n)
ifac := make([]int, 15)
Cosqi(test.n, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to cosqi for n=%d", test.n)
t.Logf("\n%v\n%v", work, test.wantiwork)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to cosqi for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
fn := float64(test.n)
x := make([]float64, test.n)
y, _, xh := series(test.n)
dt := math.Pi / (2 * fn)
for i := 0; i < test.n; i++ {
arg := float64(i) * dt
for k := 0; k < test.n; k++ {
x[i] += y[k] * math.Cos(float64(2*k+1)*arg)
}
x[i] *= 4
}
Cosqb(test.n, y, work, ifac)
cf := 0.25 / fn
var cosqbt float64
for i := 0; i < test.n; i++ {
cosqbt = math.Max(cosqbt, math.Abs(x[i]-y[i]))
x[i] = xh[i]
}
cosqbt *= cf
if !floats.EqualWithinAbsOrRel(cosqbt, 0, tol, tol) {
t.Errorf("unexpected cosqbt value for n=%d: got:%f want:0", test.n, cosqbt)
}
// Construct a frequency spectrum and compare the computed sequence.
for i := 0; i < test.n; i++ {
y[i] = 0.5 * x[0]
arg := float64(2*i+1) * dt
for k := 1; k < test.n; k++ {
y[i] += x[k] * math.Cos(float64(k)*arg)
}
y[i] *= 2
}
Cosqf(test.n, x, work, ifac)
var cosqft float64
for i := 0; i < test.n; i++ {
cosqft = math.Max(cosqft, math.Abs(x[i]-y[i]))
x[i] = xh[i]
y[i] = xh[i]
}
cosqft *= cf
if !floats.EqualWithinAbsOrRel(cosqft, 0, tol, tol) {
t.Errorf("unexpected cosqft value for n=%d: got:%f want:0", test.n, cosqft)
}
// Check that Cosqb and Cosqf are inverses.
Cosqb(test.n, x, work, ifac)
Cosqf(test.n, x, work, ifac)
var cosqfb float64
for i := 0; i < test.n; i++ {
cosqfb = math.Max(cosqfb, math.Abs(cf*x[i]-y[i]))
}
if !floats.EqualWithinAbsOrRel(cosqfb, 0, tol, tol) {
t.Errorf("unexpected cosqfb value for n=%d: got:%f want:0", test.n, cosqfb)
}
}
}
func TestSinq(t *testing.T) {
const tol = 1e-12
for _, test := range sincosqTests {
// Compute the work and factor slices and compare to known values.
work := make([]float64, 3*test.n)
ifac := make([]int, 15)
Sinqi(test.n, work, ifac)
var failed bool
if !floats.EqualApprox(work, test.wantiwork, 1e-6) {
failed = true
t.Errorf("unexpected work after call to sinqi for n=%d", test.n)
t.Logf("\n%v\n%v", work, test.wantiwork)
}
if !reflect.DeepEqual(ifac, test.wantiifac) {
failed = true
t.Errorf("unexpected ifac after call to sinqi for n=%d", test.n)
}
if failed {
continue
}
// Construct a sequence with known a frequency spectrum and compare
// the computed spectrum.
fn := float64(test.n)
x := make([]float64, test.n)
y, _, xh := series(test.n)
dt := math.Pi / (2 * fn)
for i := 0; i < test.n; i++ {
arg := float64(i+1) * dt
for k := 0; k < test.n; k++ {
x[i] += y[k] * math.Sin(float64(2*k+1)*arg)
}
x[i] *= 4
}
Sinqb(test.n, y, work, ifac)
cf := 0.25 / fn
var sinqbt float64
for i := 0; i < test.n; i++ {
sinqbt = math.Max(sinqbt, math.Abs(x[i]-y[i]))
x[i] = xh[i]
}
sinqbt *= cf
if !floats.EqualWithinAbsOrRel(sinqbt, 0, tol, tol) {
t.Errorf("unexpected sinqbt value for n=%d: got:%f want:0", test.n, sinqbt)
}
// Construct a frequency spectrum and compare the computed sequence.
for i := 0; i < test.n; i++ {
arg := float64(2*i+1) * dt
y[i] = 0.5 * math.Pow(-1, float64(i)) * x[test.n-1]
for k := 0; k < test.n-1; k++ {
y[i] += x[k] * math.Sin(float64(k+1)*arg)
}
y[i] *= 2
}
Sinqf(test.n, x, work, ifac)
var sinqft float64
for i := 0; i < test.n; i++ {
sinqft = math.Max(sinqft, math.Abs(x[i]-y[i]))
x[i] = xh[i]
y[i] = xh[i]
}
sinqft *= cf
if !floats.EqualWithinAbsOrRel(sinqft, 0, tol, tol) {
t.Errorf("unexpected sinqft value for n=%d: got:%f want:0", test.n, sinqft)
}
// Check that Sinqb and Sinqf are inverses.
Sinqb(test.n, x, work, ifac)
Sinqf(test.n, x, work, ifac)
var sinqfb float64
for i := 0; i < test.n; i++ {
sinqfb = math.Max(sinqfb, math.Abs(cf*x[i]-y[i]))
}
if !floats.EqualWithinAbsOrRel(sinqfb, 0, tol, tol) {
t.Errorf("unexpected sinqfb value for n=%d: got:%f want:0", test.n, sinqfb)
}
}
}
var sincosqTests = []struct {
n int
// The following two fields are added as there is no unit testing in
// FFTPACK for SINTI.
//
// wantiwork is obtained from the FFTPACK test.f with modification.
// The W array is zeroed at each iteration and the first 3n elements
// of W are printed after the call to RFFTI.
wantiwork []float64
// wantiifac is obtained from the FFTPACK sint.f with modification.
// The IFAC array is zeroed at each iteration of test.f and the 15 elements
// of IFAC are printed before RFFTI returns.
wantiifac []int
}{
{
n: 120,
wantiwork: []float64{
0.9999143, 0.9996573, 0.9992290, 0.9986295, 0.9978589, 0.9969173, 0.9958049, 0.9945219,
0.9930685, 0.9914449, 0.9896514, 0.9876884, 0.9855561, 0.9832549, 0.9807853, 0.9781476,
0.9753423, 0.9723699, 0.9692309, 0.9659258, 0.9624552, 0.9588197, 0.9550200, 0.9510565,
0.9469301, 0.9426415, 0.9381914, 0.9335804, 0.9288096, 0.9238795, 0.9187912, 0.9135454,
0.9081432, 0.9025853, 0.8968728, 0.8910065, 0.8849877, 0.8788171, 0.8724960, 0.8660254,
0.8594064, 0.8526402, 0.8457278, 0.8386706, 0.8314696, 0.8241262, 0.8166415, 0.8090170,
0.8012538, 0.7933533, 0.7853169, 0.7771459, 0.7688418, 0.7604060, 0.7518398, 0.7431448,
0.7343225, 0.7253744, 0.7163019, 0.7071068, 0.6977904, 0.6883546, 0.6788007, 0.6691306,
0.6593458, 0.6494480, 0.6394390, 0.6293204, 0.6190940, 0.6087614, 0.5983246, 0.5877852,
0.5771452, 0.5664062, 0.5555702, 0.5446390, 0.5336145, 0.5224985, 0.5112931, 0.5000000,
0.4886212, 0.4771588, 0.4656145, 0.4539905, 0.4422887, 0.4305110, 0.4186597, 0.4067366,
0.3947438, 0.3826834, 0.3705574, 0.3583679, 0.3461170, 0.3338068, 0.3214395, 0.3090170,
0.2965415, 0.2840153, 0.2714404, 0.2588191, 0.2461533, 0.2334453, 0.2206974, 0.2079117,
0.1950902, 0.1822355, 0.1693494, 0.1564344, 0.1434926, 0.1305261, 0.1175374, 0.1045284,
0.9150153E-01, 0.7845908E-01, 0.6540307E-01, 0.5233597E-01, 0.3925979E-01, 0.2617688E-01, 0.1308960E-01, -0.4371139E-07,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.9986295, 0.5233596E-01, 0.9945219, 0.1045285, 0.9876884, 0.1564345, 0.9781476, 0.2079117,
0.9659258, 0.2588190, 0.9510565, 0.3090170, 0.9335804, 0.3583679, 0.9135454, 0.4067366,
0.8910065, 0.4539905, 0.8660254, 0.5000000, 0.8386706, 0.5446391, 0.8090170, 0.5877852,
0.7771459, 0.6293204, 0.7431448, 0.6691306, 0.7071068, 0.7071068, 0.6691306, 0.7431449,
0.6293204, 0.7771460, 0.5877852, 0.8090170, 0.5446390, 0.8386706, 0.5000000, 0.8660254,
0.4539905, 0.8910065, 0.4067366, 0.9135455, 0.3583679, 0.9335805, 0.3090170, 0.9510565,
0.2588191, 0.9659258, 0.2079117, 0.9781476, 0.1564344, 0.9876884, 0.1045284, 0.9945219,
0.5233597E-01, 0.9986295, 0.000000, 0.000000, 0.9945219, 0.1045285, 0.9781476, 0.2079117,
0.9510565, 0.3090170, 0.9135454, 0.4067366, 0.8660254, 0.5000000, 0.8090170, 0.5877852,
0.7431448, 0.6691306, 0.000000, 0.9781476, 0.2079117, 0.9135454, 0.4067366, 0.8090170,
0.5877852, 0.6691306, 0.7431449, 0.5000000, 0.8660254, 0.3090170, 0.9510565, 0.1045284,
0.9945219, 0.000000, 0.9510565, 0.3090170, 0.8090170, 0.5877852, 0.5877852, 0.8090170,
0.3090170, 0.9510565, -0.4371139E-07, 1.000000, -0.3090170, 0.9510565, -0.5877852, 0.8090170,
0.000000, 0.9135454, 0.4067366, 0.6691306, 0.7431449, 0.000000, 0.6691306, 0.7431449,
-0.1045285, 0.9945219, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{120, 4, 2, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 54,
wantiwork: []float64{
0.9995769, 0.9983082, 0.9961947, 0.9932383, 0.9894416, 0.9848077, 0.9793406, 0.9730449,
0.9659258, 0.9579895, 0.9492427, 0.9396926, 0.9293475, 0.9182161, 0.9063078, 0.8936327,
0.8802014, 0.8660254, 0.8511167, 0.8354878, 0.8191521, 0.8021232, 0.7844157, 0.7660444,
0.7470251, 0.7273737, 0.7071068, 0.6862416, 0.6647958, 0.6427876, 0.6202354, 0.5971586,
0.5735765, 0.5495090, 0.5249766, 0.5000000, 0.4746003, 0.4487992, 0.4226182, 0.3960797,
0.3692062, 0.3420202, 0.3145447, 0.2868032, 0.2588191, 0.2306159, 0.2022175, 0.1736482,
0.1449319, 0.1160929, 0.8715568E-01, 0.5814485E-01, 0.2908471E-01, -0.4371139E-07, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.9932383, 0.1160929, 0.9730449, 0.2306159,
0.9396926, 0.3420201, 0.8936327, 0.4487992, 0.8354878, 0.5495090, 0.7660444, 0.6427876,
0.6862416, 0.7273737, 0.5971586, 0.8021232, 0.5000000, 0.8660254, 0.3960797, 0.9182161,
0.2868032, 0.9579895, 0.1736482, 0.9848077, 0.5814485E-01, 0.9983082, 0.000000, 0.9730449,
0.2306159, 0.8936327, 0.4487992, 0.7660444, 0.6427876, 0.5971586, 0.8021232, 0.000000,
0.8936327, 0.4487992, 0.5971586, 0.8021232, 0.1736482, 0.9848077, -0.2868032, 0.9579895,
0.000000, 0.7660444, 0.6427876, 0.000000, 0.1736482, 0.9848077, 0.000000, 0.000000,
0.000000, 0.000000,
},
wantiifac: []int{54, 4, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 49,
wantiwork: []float64{
0.9994862, 0.9979454, 0.9953791, 0.9917900, 0.9871818, 0.9815592, 0.9749279, 0.9672949,
0.9586679, 0.9490557, 0.9384684, 0.9269168, 0.9144126, 0.9009688, 0.8865993, 0.8713187,
0.8551428, 0.8380881, 0.8201723, 0.8014136, 0.7818314, 0.7614459, 0.7402779, 0.7183493,
0.6956825, 0.6723009, 0.6482283, 0.6234898, 0.5981105, 0.5721166, 0.5455348, 0.5183925,
0.4907175, 0.4625383, 0.4338836, 0.4047833, 0.3752669, 0.3453650, 0.3151082, 0.2845275,
0.2536545, 0.2225209, 0.1911586, 0.1595999, 0.1278771, 0.9602292E-01, 0.6407014E-01, 0.3205151E-01,
-0.4371139E-07, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.9917900, 0.1278772, 0.9672949, 0.2536546, 0.9269168, 0.3752670,
0.000000, 0.9672949, 0.2536546, 0.8713187, 0.4907176, 0.7183493, 0.6956826, 0.000000,
0.9269168, 0.3752670, 0.7183493, 0.6956826, 0.4047833, 0.9144127, 0.000000, 0.8713187,
0.4907176, 0.5183925, 0.8551428, 0.3205151E-01, 0.9994862, 0.000000, 0.8014136, 0.5981106,
0.2845275, 0.9586679, -0.3453652, 0.9384683, 0.000000, 0.7183493, 0.6956826, 0.3205151E-01,
0.9994862, -0.6723010, 0.7402779, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000,
},
wantiifac: []int{49, 2, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 32,
wantiwork: []float64{
0.9987954, 0.9951847, 0.9891765, 0.9807853, 0.9700313, 0.9569404, 0.9415441, 0.9238795,
0.9039893, 0.8819212, 0.8577286, 0.8314696, 0.8032075, 0.7730104, 0.7409511, 0.7071068,
0.6715589, 0.6343933, 0.5956993, 0.5555702, 0.5141027, 0.4713967, 0.4275551, 0.3826834,
0.3368898, 0.2902846, 0.2429801, 0.1950902, 0.1467305, 0.9801713E-01, 0.4906765E-01, -0.4371139E-07,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.9807853, 0.1950903, 0.9238795, 0.3826835, 0.8314696, 0.5555702, 0.7071068, 0.7071068,
0.5555702, 0.8314697, 0.3826834, 0.9238795, 0.1950902, 0.9807853, 0.000000, 0.000000,
0.9238795, 0.3826835, 0.000000, 0.000000, 0.7071068, 0.7071068, 0.000000, 0.000000,
0.3826834, 0.9238795, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{32, 3, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 25,
wantiwork: []float64{
0.9980267, 0.9921147, 0.9822872, 0.9685832, 0.9510565, 0.9297765, 0.9048271, 0.8763067,
0.8443279, 0.8090170, 0.7705132, 0.7289686, 0.6845471, 0.6374239, 0.5877852, 0.5358267,
0.4817536, 0.4257792, 0.3681245, 0.3090170, 0.2486898, 0.1873812, 0.1253331, 0.6279038E-01,
-0.4371139E-07, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.9685832, 0.2486899, 0.8763067, 0.4817537, 0.000000, 0.8763067,
0.4817537, 0.5358267, 0.8443279, 0.000000, 0.7289686, 0.6845471, 0.6279038E-01, 0.9980267,
0.000000, 0.5358267, 0.8443279, -0.4257794, 0.9048270, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000,
},
wantiifac: []int{25, 2, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 4,
wantiwork: []float64{
0.9238795, 0.7071068, 0.3826834, -0.4371139E-07, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{4, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 3,
wantiwork: []float64{
0.8660254, 0.5000000, -0.4371139E-07, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
0.000000,
},
wantiifac: []int{3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
{
n: 2,
wantiwork: []float64{
0.7071068, -0.4371139E-07, 0.000000, 0.000000, 0.000000, 0.000000,
},
wantiifac: []int{2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
// series returns three copies of a sinusoidal sequence n samples long.
func series(n int) (x, y, xh []float64) {
x = make([]float64, n)
y = make([]float64, n)
xh = make([]float64, n)
for i := 0; i < n; i++ {
x[i] = math.Sin(float64(i+1) * math.Sqrt2)
y[i] = x[i]
xh[i] = x[i]
}
return x, y, xh
}