129 lines
4.7 KiB
Go
129 lines
4.7 KiB
Go
|
|
package basic
|
||
|
|
|
||
|
|
import (
|
||
|
|
"math"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestBarycentricScaleDefinitions(t *testing.T) {
|
||
|
|
for _, jd := range []float64{JDCalc(-3000, 1, 1), barycentricT0JDE, JDCalc(2026, 1, 1), JDCalc(6000, 1, 1)} {
|
||
|
|
tcgOffset := TCGMinusTTSeconds(jd)
|
||
|
|
if diff := tcgOffset*(1-6.969290134e-10) - 6.969290134e-10*(jd-2443144.5003725)*86400; math.Abs(diff) > 1e-12 {
|
||
|
|
t.Errorf("jd=%v TCG defining relation residual=%g s", jd, diff)
|
||
|
|
}
|
||
|
|
tcbOffset := TCBMinusTTSeconds(jd)
|
||
|
|
if diff := tcbOffset*(1-1.550519768e-8) - 1.550519768e-8*(jd-2443144.5003725)*86400 - TDBMinusTTSeconds(jd) - 65.5e-6; math.Abs(diff) > 1e-12 {
|
||
|
|
t.Errorf("jd=%v TCB defining relation residual=%g s", jd, diff)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if got := TCGMinusTTSeconds(barycentricT0JDE); got != 0 {
|
||
|
|
t.Errorf("TCG-TT at T0=%v, want 0", got)
|
||
|
|
}
|
||
|
|
if got, want := TCB2TDB(barycentricT0JDE), barycentricT0JDE-65.5e-6/86400; got != want {
|
||
|
|
t.Errorf("TDB at TCB T0=%.12f, want %.12f", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBarycentricLinearConversionAnchors(t *testing.T) {
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name string
|
||
|
|
fn func(float64) float64
|
||
|
|
jd float64
|
||
|
|
want float64
|
||
|
|
}{
|
||
|
|
{"TCB2TDB", TCB2TDB, 2453750.5 + 0.893019599, 2453750.5 + 0.8928551362746343397},
|
||
|
|
{"TDB2TCB", TDB2TCB, 2453750.5 + 0.892855137, 2453750.5 + 0.8930195997253656716},
|
||
|
|
{"TCG2TT", TCG2TT, 2453750.5 + 0.892862531, 2453750.5 + 0.8928551387488816828},
|
||
|
|
{"TT2TCG", TT2TCG, 2453750.5 + 0.892482639, 2453750.5 + 0.8924900312508587113},
|
||
|
|
} {
|
||
|
|
ulp := math.Nextafter(tc.want, math.Inf(1)) - tc.want
|
||
|
|
if got := tc.fn(tc.jd); math.Abs(got-tc.want) > ulp {
|
||
|
|
t.Errorf("%s=%.12f, want %.12f", tc.name, got, tc.want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBarycentricPeriodicTermsMatchFullSeries(t *testing.T) {
|
||
|
|
for _, tc := range []struct {
|
||
|
|
jd float64
|
||
|
|
want float64
|
||
|
|
}{
|
||
|
|
{625307.5, 0.001558488628712037},
|
||
|
|
{766574.5, -0.000924800103328196},
|
||
|
|
{1721057.5, 0.0008624527814561311},
|
||
|
|
{2433282.5, -7.069829559472634e-05},
|
||
|
|
{2443144.5, -6.551401857064118e-05},
|
||
|
|
{2451544.5, -0.0001137630988927298},
|
||
|
|
{2461041.5, -8.20152430051247e-05},
|
||
|
|
{2461222.5, 0.0001186656922342686},
|
||
|
|
{2469807.5, -8.01882947792431e-05},
|
||
|
|
{3182029.5, -0.0009618304620565844},
|
||
|
|
{3912514.5, -0.00138271667055309},
|
||
|
|
} {
|
||
|
|
if got := TDBMinusTTSeconds(tc.jd); math.Abs(got-tc.want) > 2.1e-6 {
|
||
|
|
t.Errorf("jd=%v TDB-TT=%.9f us, want %.9f us", tc.jd, got*1e6, tc.want*1e6)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBarycentricScaleRoundTrips(t *testing.T) {
|
||
|
|
for _, jd := range []float64{
|
||
|
|
JDCalc(-3000, 1, 1), JDCalc(0, 1, 1), JDCalc(1900, 1, 1), JDCalc(1950, 6, 1),
|
||
|
|
barycentricT0JDE, JDCalc(2000, 1, 1), JDCalc(2026, 4, 1), JDCalc(2050, 7, 1),
|
||
|
|
JDCalc(2100, 1, 1), JDCalc(6000, 1, 1),
|
||
|
|
} {
|
||
|
|
ulp := math.Nextafter(jd, math.Inf(1)) - jd
|
||
|
|
for _, tc := range []struct {
|
||
|
|
name string
|
||
|
|
fwd func(float64) float64
|
||
|
|
back func(float64) float64
|
||
|
|
}{
|
||
|
|
{"TT-TCG", TT2TCG, TCG2TT},
|
||
|
|
{"TT-TCB", TT2TCB, TCB2TT},
|
||
|
|
{"TT-TDB", TT2TDB, TDB2TT},
|
||
|
|
{"TCB-TDB", TCB2TDB, TDB2TCB},
|
||
|
|
} {
|
||
|
|
if got := tc.back(tc.fwd(jd)); math.Abs(got-jd) > ulp {
|
||
|
|
t.Errorf("jd=%v %s round-trip error=%g s", jd, tc.name, (got-jd)*86400)
|
||
|
|
}
|
||
|
|
if got := tc.fwd(tc.back(jd)); math.Abs(got-jd) > ulp {
|
||
|
|
t.Errorf("jd=%v %s inverse round-trip error=%g s", jd, tc.name, (got-jd)*86400)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// 组合路径分别舍入,允许两次 JD 舍入误差。
|
||
|
|
if diff := TCB2TDB(TT2TCB(jd)) - TT2TDB(jd); math.Abs(diff) > 2*ulp {
|
||
|
|
t.Errorf("jd=%v TT-TCB-TDB differs from TT-TDB by %g s", jd, diff*86400)
|
||
|
|
}
|
||
|
|
if diff := (TT2TDB(jd)-jd)*86400 - TDBMinusTTSeconds(jd); math.Abs(diff) > ulp*86400 {
|
||
|
|
t.Errorf("jd=%v TDB seconds and JD conversions differ by %g s", jd, diff)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBarycentricScaleMagnitudes(t *testing.T) {
|
||
|
|
jd := JDCalc(2026, 1, 1)
|
||
|
|
if got := TCGMinusTTSeconds(jd); math.Abs(got-1.0777) > 5e-3 {
|
||
|
|
t.Errorf("TCG-TT=%v s, want about 1.078", got)
|
||
|
|
}
|
||
|
|
if got := TCBMinusTTSeconds(jd); math.Abs(got-23.9757) > 5e-3 {
|
||
|
|
t.Errorf("TCB-TT=%v s, want about 23.976", got)
|
||
|
|
}
|
||
|
|
if got := TCGMinusTTSeconds(barycentricT0JDE+365.25) - TCGMinusTTSeconds(barycentricT0JDE); math.Abs(got-0.02204) > 5e-5 {
|
||
|
|
t.Errorf("TCG-TT annual increase=%v s, want about 0.02204", got)
|
||
|
|
}
|
||
|
|
if got := TCBMinusTTSeconds(barycentricT0JDE+365.25) - TCBMinusTTSeconds(barycentricT0JDE); math.Abs(got-0.48934) > 5e-4 {
|
||
|
|
t.Errorf("TCB-TT annual increase=%v s, want about 0.48934", got)
|
||
|
|
}
|
||
|
|
if got := TDBMinusTTSeconds(JDCalc(2100, 1, 1)) - TDBMinusTTSeconds(JDCalc(2000, 1, 1)); math.Abs(got) > 2e-4 {
|
||
|
|
t.Errorf("TDB-TT century difference=%v s, want within 0.2 ms", got)
|
||
|
|
}
|
||
|
|
min, max := math.Inf(1), math.Inf(-1)
|
||
|
|
for month := 1; month <= 12; month++ {
|
||
|
|
value := TDBMinusTTSeconds(JDCalc(2026, month, 1))
|
||
|
|
min, max = math.Min(min, value), math.Max(max, value)
|
||
|
|
}
|
||
|
|
if amplitude := max - min; amplitude < 3.0e-3 || amplitude > 3.6e-3 {
|
||
|
|
t.Errorf("TDB-TT annual range=%v s, want 3.0-3.6 ms", amplitude)
|
||
|
|
}
|
||
|
|
}
|