Now that I have switched to TOP2013 for calculating Pluto's
position in the C# code, there is no need for the unit test
to handle errors for out-of-bound time coordinate.
Also corrected code generator to output term coefficients
in scientific notation. In the C code, it was dropping signficant
digits by outputting in fixed point notation.
The high-frequency wobble in the Pluto position function was bothering me.
Decreased the arcminute error threshold from 1.0 to 0.5, resulting
in a much larger model, but a lot less ripple:
547 [ 78 140 94 115 21 99]
The truncated TOP2013 series creates higher frequency
oscillations in the heliocentric distance of Pluto
that confused the apsides algorithm the same way Neptune did.
So I changed the special-case Neptune logic to work for both
Neptune and Pluto.
Now the C version of Astronomy Engine is using the TOP2013 model
of Pluto instead of resampled Chebyshev polynomials.
I added temporary hacks to ignore differences for Pluto between
C output and output from Python, JavaScript, and C#.
I will remove these after all four languages are using TOP2013.
See the variable ToleratePlutoErrors in ctest.c.
ctest.c DiffLine function now understands that longitude-like
angles (right ascension and azimuth) can wrap around, and to tolerate
very small angular differences that happen to straddle the wraparound
value. I should have done this a long time ago, but it never caused
problems before now.
C PlanetApsis has a serious problem with Pluto that I didn't expect.
I need to investigate and understand this before porting to other
languages. For now, I hack around it using ToleratePlutoErrors.
This is another way to explore possible solutions in a random order
so that we don't keep going in the same directions each time.
Found a better solution:
219 [ 27 63 61 58 6 4]
winner: 0.998305 arcmin : 228 [ 37 63 60 58 6 4]
This script keeps running the ray search followed by the nudge search.
If it finds a better solution that the existing one, it replaces it.
Found the above solution after about 30 minutes.
I realized that I still was telling the code to assume the
time coordinate never gets more than 0.2 millennia away from J2000.
But in fact, it is getting 0.5 millennia away. Fixed that, and
immediately found a smaller model that works.
OptimizeTop: 255 terms [ 41 62 71 68 9 4]
Relax apparent angular error threshold from 0.4 to 1.0 arcminutes.
No longer compare TOP2013 to NOVAS while optimizing.
Use worst-case distance between Earth and Pluto:
Pluto radius from Sun, minus Earth aphelion distance.
Sample 503 points intead of 293.
Measure 2 full orbits before J2000 and 2 full orbits after J2000.
Statistics for output/8.top :
OptimizeTop: 268 terms [ 34 57 72 90 9 6]
Created functions for generating random unit vectors in
6-dimensional space. Will use this for trying different
directions along which to do a binary search between
truncated TOP2013 models that have acceptable error
and those which have unacceptable error. Will home in on
the smallest model that is within tolerable error.
Instead of calculating amplitudes and truncating based on them,
I realized when it comes right down to it, all I want to do
is truncate fewer or more terms from each formula until I find
a good compromise between size and accuracy. A term is either
included or excluded. Therefore the degree of freedom is discrete,
not continuous. There is no need to calculate a continuous value
to adjust something with only discrete options available.
This change allows me to automatically initialize the pruning amplitudes
to the largest possible value that won't cause any pruning.
It establishes a lower bound for pruning each of the 6 elliptical formulas.
Generating an embryonic TOP2013 Pluto model, along with the old
Chebyshev resampling model of Pluto, into the Linux and Windows
build processes.
The TOP2013 Pluto model isn't used for anything, and it isn't
optimized properly yet, but at least this helps validate my code
automatically as I go forward.
The TopCloneModel function makes a deep copy of a model,
allocating separate term arrays for the copy.
TopSquash uses a contribution map and an array of 6 amplitude thresholds
to pack down an original model into a cloned model.
The contrib map is an array of 6 sortable lists, one for each
elliptical formula. Each list contains a tuple (m, s, t)
where m = the magnitude of the contribution of a term,
and (s, t) are the indices of the term in the formula.
I sort the tuples in ascending order of magnitude.
This should allow me to efficiently eliminate terms from
each formula.
I will have to add an "ignore" flag for each term, because
eliminated terms will not generally be at the end of the list.
Before saving, I will need to compact the lists.
The first step is measuring the error between TOP2013 and NOVAS
over a range of time values and finding the maximum error in
worst-case parallax arcminutes as seen from the Earth.
Next I will be able to automate pruning the model to make
it as small as possible without exceeding our error tolerance.
Reduced the size of the Windows batch file 'run.bat' by factoring
out the logic for downloading an external file into a subroutine.
I had already done this in the Linux bash script 'run'.
This makes me think there is something wrong with how
I am calling NovasBodyPos(). I don't understand why the errors
are tiny fractions of arcminutes here, but up to 0.11 arcmin
compared to NOVAS.
Ported the original FORTRAN code for converting elliptical
elements to ecliptic/equatorial rectangular coordinates.
Verified against the output of the original FORTRAN program.
The results include both position vectors and velocity vectors,
and all are identical to 10 places after the decimal.