| // Copyright ©2017 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 mathext |
| |
| import ( |
| "math" |
| "testing" |
| |
| "golang.org/x/exp/rand" |
| ) |
| |
| // Testing EllipticF (and EllipticRF) using the addition theorems from http://dlmf.nist.gov/19.11.i |
| func TestEllipticF(t *testing.T) { |
| t.Parallel() |
| const tol = 1.0e-14 |
| rnd := rand.New(rand.NewSource(1)) |
| |
| // The following EllipticF(pi/3,m), m=0.1(0.1)0.9 was computed in Maxima 5.38.0 using Bigfloat arithmetic. |
| vF := [...]float64{ |
| 1.0631390181954904767742338285104637431858016483079, |
| 1.0803778062523490005579242592072579594037132891908, |
| 1.0991352230920430074586978843452269008747645822123, |
| 1.1196949183404746257742176145632376703505764745654, |
| 1.1424290580457772555013955266260457822322036529624, |
| 1.1678400583161860445148860686430780757517286094732, |
| 1.1966306515644649360767197589467723191317720122309, |
| 1.2298294422249382706933871574135731278765534034979, |
| 1.2690359140762658660446752406901433173504503955036, |
| } |
| phi := math.Pi / 3 |
| for m := 1; m <= 9; m++ { |
| mf := float64(m) / 10 |
| delta := math.Abs(EllipticF(phi, mf) - vF[m-1]) |
| if delta > tol { |
| t.Fatalf("EllipticF(pi/3,m) test fail for m=%v", mf) |
| } |
| } |
| |
| for test := 0; test < 100; test++ { |
| alpha := rnd.Float64() * math.Pi / 4 |
| beta := rnd.Float64() * math.Pi / 4 |
| for mi := 0; mi < 9999; mi++ { |
| m := float64(mi) / 10000 |
| Fa := EllipticF(alpha, m) |
| Fb := EllipticF(beta, m) |
| sina, cosa := math.Sincos(alpha) |
| sinb, cosb := math.Sincos(beta) |
| tan := (sina*math.Sqrt(1-m*sinb*sinb) + sinb*math.Sqrt(1-m*sina*sina)) / (cosa + cosb) |
| gamma := 2 * math.Atan(tan) |
| Fg := EllipticF(gamma, m) |
| delta := math.Abs(Fa + Fb - Fg) |
| if delta > tol { |
| t.Fatalf("EllipticF test fail for m=%v, alpha=%v, beta=%v", m, alpha, beta) |
| } |
| } |
| } |
| } |
| |
| // Testing EllipticE (and EllipticRF, EllipticRD) using the addition theorems from http://dlmf.nist.gov/19.11.i |
| func TestEllipticE(t *testing.T) { |
| t.Parallel() |
| const tol = 1.0e-14 |
| rnd := rand.New(rand.NewSource(1)) |
| |
| // The following EllipticE(pi/3,m), m=0.1(0.1)0.9 was computed in Maxima 5.38.0 using Bigfloat arithmetic. |
| vE := [...]float64{ |
| 1.0316510822817691068014397636905610074934300946730, |
| 1.0156973658341766636288643556414001451527597364432, |
| 9.9929636467826398814855428365155224243586391115108e-1, |
| 9.8240033979859736941287149003648737502960015189033e-1, |
| 9.6495145764299257550956863602992167490195750321518e-1, |
| 9.4687829659158090935158610908054896203271861698355e-1, |
| 9.2809053417715769009517654522979827392794124845027e-1, |
| 9.0847044378047233264777277954768245721857017157916e-1, |
| 8.8785835036531301307661603341327881634688308777383e-1, |
| } |
| phi := math.Pi / 3 |
| for m := 1; m <= 9; m++ { |
| mf := float64(m) / 10 |
| delta := math.Abs(EllipticE(phi, mf) - vE[m-1]) |
| if delta > tol { |
| t.Fatalf("EllipticE(pi/3,m) test fail for m=%v", mf) |
| } |
| } |
| |
| for test := 0; test < 100; test++ { |
| alpha := rnd.Float64() * math.Pi / 4 |
| beta := rnd.Float64() * math.Pi / 4 |
| for mi := 0; mi < 9999; mi++ { |
| m := float64(mi) / 10000 |
| Ea := EllipticE(alpha, m) |
| Eb := EllipticE(beta, m) |
| sina, cosa := math.Sincos(alpha) |
| sinb, cosb := math.Sincos(beta) |
| tan := (sina*math.Sqrt(1-m*sinb*sinb) + sinb*math.Sqrt(1-m*sina*sina)) / (cosa + cosb) |
| gamma := 2 * math.Atan(tan) |
| Eg := EllipticE(gamma, m) |
| delta := math.Abs(Ea + Eb - Eg - m*sina*sinb*math.Sin(gamma)) |
| if delta > tol { |
| t.Fatalf("EllipticE test fail for m=%v, alpha=%v, beta=%v", m, alpha, beta) |
| } |
| } |
| } |
| } |