Files
gonum/mathext/internal/amos/amos_fortran_test.go
Dan Kortschak ccc0da248a all: run make builds pass with go master
Run gofmt go1.17 adds the new //go:build comments
2021-04-19 15:00:56 +09:30

451 lines
13 KiB
Go

// Copyright ©2016 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.
//go:build fortran
// +build fortran
package amos
import (
"flag"
"runtime"
"testing"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext/internal/amos/amoslib"
)
// BUG(kortschak): Some tests here comparing the direct Go translation
// of the Fortran code fail. Do not delete these tests or this file until
// https://github.com/gonum/gonum/issues/1322 has been satisfactorily
// resolved.
var runFailing = flag.Bool("failing", false, "run known failing cases")
func TestAiryFortran(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zairytestFort(t, in.x, in.kode, in.id)
}
}
func TestZacaiFortran(t *testing.T) {
if !*runFailing {
t.Skip("fails")
}
switch runtime.GOARCH {
case "arm64":
t.Skipf("skipping on GOARCH=%s", runtime.GOARCH)
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zacaitestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode)
}
}
func TestZbknuFortran(t *testing.T) {
if !*runFailing {
t.Skip("fails")
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zbknutestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode)
}
}
func TestZasyiFortran(t *testing.T) {
if !*runFailing {
t.Skip("fails")
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zasyitestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode)
}
}
func TestZseriFortran(t *testing.T) {
switch runtime.GOARCH {
case "arm64":
t.Skipf("skipping on GOARCH=%s", runtime.GOARCH)
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zseritestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode)
}
}
func TestZmlriFortran(t *testing.T) {
if !*runFailing {
t.Skip("fails")
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zmlritestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode)
}
}
func TestZksclFortran(t *testing.T) {
if !*runFailing {
t.Skip("fails")
}
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zkscltestFort(t, in.x, in.is, in.tol, in.n, in.yr, in.yi)
}
}
func TestZuchkFortran(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zuchktestFort(t, in.x, in.is, in.tol)
}
}
func TestZs1s2Fortran(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
for i := 0; i < nInputs; i++ {
in := randInput(rnd)
zs1s2testFort(t, in.x, in.is)
}
}
func zs1s2testFort(t *testing.T, x []float64, is []int) {
const tol = 1e-11
type data struct {
ZRR, ZRI, S1R, S1I, S2R, S2I float64
NZ int
ASCLE, ALIM float64
IUF int
}
input := data{
x[0], x[1], x[2], x[3], x[4], x[5],
is[0],
x[6], x[7],
is[1],
}
impl := func(input data) data {
zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf :=
amoslib.Zs1s2Fort(input.ZRR, input.ZRI, input.S1R, input.S1I, input.S2R, input.S2I, input.NZ, input.ASCLE, input.ALIM, input.IUF)
return data{zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf}
}
comp := func(input data) data {
zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf :=
zs1s2Orig(input.ZRR, input.ZRI, input.S1R, input.S1I, input.S2R, input.S2I, input.NZ, input.ASCLE, input.ALIM, input.IUF)
return data{zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf}
}
oi := impl(input)
oc := comp(input)
sameF64Approx(t, "zs1s2 zrr", oc.ZRR, oi.ZRR, tol)
sameF64Approx(t, "zs1s2 zri", oc.ZRI, oi.ZRI, tol)
sameF64Approx(t, "zs1s2 s1r", oc.S1R, oi.S1R, tol)
sameF64Approx(t, "zs1s2 s1i", oc.S1I, oi.S1I, tol)
sameF64Approx(t, "zs1s2 s2r", oc.S2R, oi.S2R, tol)
sameF64Approx(t, "zs1s2 s2i", oc.S2I, oi.S2I, tol)
sameF64Approx(t, "zs1s2 ascle", oc.ASCLE, oi.ASCLE, tol)
sameF64Approx(t, "zs1s2 alim", oc.ALIM, oi.ALIM, tol)
sameInt(t, "iuf", oc.IUF, oi.IUF)
sameInt(t, "nz", oc.NZ, oi.NZ)
}
func zuchktestFort(t *testing.T, x []float64, is []int, tol float64) {
t.Helper()
YR := x[0]
YI := x[1]
NZ := is[0]
ASCLE := x[2]
TOL := tol
YRfort, YIfort, NZfort, ASCLEfort, TOLfort := zuchkOrig(YR, YI, NZ, ASCLE, TOL)
YRamoslib, YIamoslib, NZamoslib, ASCLEamoslib, TOLamoslib := amoslib.ZuchkFort(YR, YI, NZ, ASCLE, TOL)
sameF64(t, "zuchk yr", YRfort, YRamoslib)
sameF64(t, "zuchk yi", YIfort, YIamoslib)
sameInt(t, "zuchk nz", NZfort, NZamoslib)
sameF64(t, "zuchk ascle", ASCLEfort, ASCLEamoslib)
sameF64(t, "zuchk tol", TOLfort, TOLamoslib)
}
func zkscltestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64) {
t.Helper()
ZRR := x[0]
ZRI := x[1]
FNU := x[2]
NZ := is[1]
ELIM := x[3]
ASCLE := x[4]
RZR := x[6]
RZI := x[7]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRRfort, ZRIfort, FNUfort, Nfort, YRfort, YIfort, NZfort, RZRfort, RZIfort, ASCLEfort, TOLfort, ELIMfort :=
zksclOrig(ZRR, ZRI, FNU, n, yrfort, yifort, NZ, RZR, RZI, ASCLE, tol, ELIM)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
ZRRamoslib, ZRIamoslib, FNUamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, RZRamoslib, RZIamoslib, ASCLEamoslib, TOLamoslib, ELIMamoslib :=
amoslib.ZksclFort(ZRR, ZRI, FNU, n, yramos, yiamos, NZ, RZR, RZI, ASCLE, tol, ELIM)
sameF64(t, "zkscl zrr", ZRRfort, ZRRamoslib)
sameF64(t, "zkscl zri", ZRIfort, ZRIamoslib)
sameF64(t, "zkscl fnu", FNUfort, FNUamoslib)
sameInt(t, "zkscl n", Nfort, Namoslib)
sameInt(t, "zkscl nz", NZfort, NZamoslib)
sameF64(t, "zkscl rzr", RZRfort, RZRamoslib)
sameF64(t, "zkscl rzi", RZIfort, RZIamoslib)
sameF64(t, "zkscl ascle", ASCLEfort, ASCLEamoslib)
sameF64(t, "zkscl tol", TOLfort, TOLamoslib)
sameF64(t, "zkscl elim", ELIMfort, ELIMamoslib)
sameF64SApprox(t, "zkscl yr", YRfort, YRamoslib, 1e-14)
sameF64SApprox(t, "zkscl yi", YIfort, YIamoslib, 1e-14)
}
func zmlritestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) {
t.Helper()
ZR := x[0]
ZI := x[1]
FNU := x[2]
KODE := kode
NZ := is[1]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort :=
zmlriOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
ZRamoslib, ZIamoslib, FNUamoslib, KODEamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, TOLamoslib :=
amoslib.ZmlriFort(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, tol)
sameF64(t, "zmlri zr", ZRfort, ZRamoslib)
sameF64(t, "zmlri zi", ZIfort, ZIamoslib)
sameF64(t, "zmlri fnu", FNUfort, FNUamoslib)
sameInt(t, "zmlri kode", KODEfort, KODEamoslib)
sameInt(t, "zmlri n", Nfort, Namoslib)
sameInt(t, "zmlri nz", NZfort, NZamoslib)
sameF64(t, "zmlri tol", TOLfort, TOLamoslib)
sameF64S(t, "zmlri yr", YRfort, YRamoslib)
sameF64S(t, "zmlri yi", YIfort, YIamoslib)
}
func zseritestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) {
t.Helper()
ZR := x[0]
ZI := x[1]
FNU := x[2]
KODE := kode
NZ := is[1]
ELIM := x[3]
ALIM := x[4]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort, ELIMfort, ALIMfort :=
zseriOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol, ELIM, ALIM)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
y := make([]complex128, len(yramos))
for i, v := range yramos {
y[i] = complex(v, yiamos[i])
}
ZRamoslib, ZIamoslib, FNUamoslib, KODEamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, TOLamoslib, ELIMamoslib, ALIMamoslib :=
amoslib.ZseriFort(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol, ELIM, ALIM)
sameF64(t, "zseri zr", ZRfort, ZRamoslib)
sameF64(t, "zseri zi", ZIfort, ZIamoslib)
sameF64(t, "zseri fnu", FNUfort, FNUamoslib)
sameInt(t, "zseri kode", KODEfort, KODEamoslib)
sameInt(t, "zseri n", Nfort, Namoslib)
if *runFailing {
sameInt(t, "zseri nz", NZfort, NZamoslib)
}
sameF64(t, "zseri tol", TOLfort, TOLamoslib)
sameF64(t, "zseri elim", ELIMfort, ELIMamoslib)
sameF64(t, "zseri elim", ALIMfort, ALIMamoslib)
sameF64SApprox(t, "zseri yr", YRfort, YRamoslib, 1e-9)
sameF64SApprox(t, "zseri yi", YIfort, YIamoslib, 1e-10)
}
func zasyitestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) {
t.Helper()
ZR := x[0]
ZI := x[1]
FNU := x[2]
KODE := kode
NZ := is[1]
ELIM := x[3]
ALIM := x[4]
RL := x[5]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, RLfort, TOLfort, ELIMfort, ALIMfort :=
zasyiOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, RL, tol, ELIM, ALIM)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
ZRamoslib, ZIamoslib, FNUamoslib, KODEamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, RLamoslib, TOLamoslib, ELIMamoslib, ALIMamoslib :=
amoslib.ZasyiFort(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, RL, tol, ELIM, ALIM)
sameF64(t, "zasyi zr", ZRfort, ZRamoslib)
sameF64(t, "zasyi zr", ZIfort, ZIamoslib)
sameF64(t, "zasyi fnu", FNUfort, FNUamoslib)
sameInt(t, "zasyi kode", KODEfort, KODEamoslib)
sameInt(t, "zasyi n", Nfort, Namoslib)
sameInt(t, "zasyi nz", NZfort, NZamoslib)
sameF64(t, "zasyi rl", RLfort, RLamoslib)
sameF64(t, "zasyi tol", TOLfort, TOLamoslib)
sameF64(t, "zasyi elim", ELIMfort, ELIMamoslib)
sameF64(t, "zasyi alim", ALIMfort, ALIMamoslib)
sameF64SApprox(t, "zasyi yr", YRfort, YRamoslib, 1e-12)
sameF64SApprox(t, "zasyi yi", YIfort, YIamoslib, 1e-12)
}
func zbknutestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) {
t.Helper()
ZR := x[0]
ZI := x[1]
FNU := x[2]
KODE := kode
NZ := is[1]
ELIM := x[3]
ALIM := x[4]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort, ELIMfort, ALIMfort :=
zbknuOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol, ELIM, ALIM)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
ZRamoslib, ZIamoslib, FNUamoslib, KODEamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, TOLamoslib, ELIMamoslib, ALIMamoslib :=
amoslib.ZbknuFort(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, tol, ELIM, ALIM)
sameF64(t, "zbknu zr", ZRfort, ZRamoslib)
sameF64(t, "zbknu zr", ZIfort, ZIamoslib)
sameF64(t, "zbknu fnu", FNUfort, FNUamoslib)
sameInt(t, "zbknu kode", KODEfort, KODEamoslib)
sameInt(t, "zbknu n", Nfort, Namoslib)
sameInt(t, "zbknu nz", NZfort, NZamoslib)
sameF64(t, "zbknu tol", TOLfort, TOLamoslib)
sameF64(t, "zbknu elim", ELIMfort, ELIMamoslib)
sameF64(t, "zbknu alim", ALIMfort, ALIMamoslib)
sameF64SApprox(t, "zbknu yr", YRfort, YRamoslib, 1e-12)
sameF64SApprox(t, "zbknu yi", YIfort, YIamoslib, 1e-12)
}
func zairytestFort(t *testing.T, x []float64, kode, id int) {
const tol = 1e-8
t.Helper()
ZR := x[0]
ZI := x[1]
KODE := kode
ID := id
AIRfort, AIIfort, NZfort, IERRfort := zairyOrig(ZR, ZI, ID, KODE)
AIRamos, AIIamos, NZamos, IERRamos := amoslib.ZairyFort(ZR, ZI, ID, KODE)
sameF64Approx(t, "zairy air", AIRfort, AIRamos, tol)
sameF64Approx(t, "zairy aii", AIIfort, AIIamos, tol)
sameInt(t, "zairy nz", NZfort, NZamos)
sameInt(t, "zairy ierr", IERRfort, IERRamos)
}
func zacaitestFort(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) {
t.Helper()
ZR := x[0]
ZI := x[1]
FNU := x[2]
KODE := kode
NZ := is[1]
MR := is[2]
ELIM := x[3]
ALIM := x[4]
RL := x[5]
yrfort := make([]float64, len(yr))
copy(yrfort, yr)
yifort := make([]float64, len(yi))
copy(yifort, yi)
ZRfort, ZIfort, FNUfort, KODEfort, MRfort, Nfort, YRfort, YIfort, NZfort, RLfort, TOLfort, ELIMfort, ALIMfort :=
zacaiOrig(ZR, ZI, FNU, KODE, MR, n, yrfort, yifort, NZ, RL, tol, ELIM, ALIM)
yramos := make([]float64, len(yr))
copy(yramos, yr)
yiamos := make([]float64, len(yi))
copy(yiamos, yi)
ZRamoslib, ZIamoslib, FNUamoslib, KODEamoslib, MRamoslib, Namoslib, YRamoslib, YIamoslib, NZamoslib, RLamoslib, TOLamoslib, ELIMamoslib, ALIMamoslib :=
amoslib.ZacaiFort(ZR, ZI, FNU, KODE, MR, n, yramos, yiamos, NZ, RL, tol, ELIM, ALIM)
sameF64(t, "zacai zr", ZRfort, ZRamoslib)
sameF64(t, "zacai zi", ZIfort, ZIamoslib)
sameF64(t, "zacai fnu", FNUfort, FNUamoslib)
sameInt(t, "zacai kode", KODEfort, KODEamoslib)
sameInt(t, "zacai mr", MRfort, MRamoslib)
sameInt(t, "zacai n", Nfort, Namoslib)
sameInt(t, "zacai nz", NZfort, NZamoslib)
sameF64(t, "zacai rl", RLfort, RLamoslib)
sameF64(t, "zacai tol", TOLfort, TOLamoslib)
sameF64(t, "zacai elim", ELIMfort, ELIMamoslib)
sameF64(t, "zacai elim", ALIMfort, ALIMamoslib)
sameF64SApprox(t, "zacai yr", YRfort, YRamoslib, 1e-12)
sameF64SApprox(t, "zacai yi", YIfort, YIamoslib, 1e-12)
}