Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New formula has overflow error #6

Closed
aadler opened this issue Jun 19, 2018 · 6 comments
Closed

New formula has overflow error #6

aadler opened this issue Jun 19, 2018 · 6 comments

Comments

@aadler
Copy link
Contributor

aadler commented Jun 19, 2018

Even after fixing the exponentiation, I get the following error in the test case:

F:\Elite\TD>trade.py run -vvv --progress --summary --avoid imperial,slaves --insurance 1.51m --pad L --ly 15.06 --cap 264 --no-planet --credits 24m --from "tollan/gord" --to "LHS 2094/Patt" --hops 3
* Hop   1: .........1 origins
NOTE: Pruned 23 origins too far from any end stations
* Hop   2: ........63 origins .. 33,528-382,536cr gain, 127-1,449cr/ton
[=====================    ] Traceback (most recent call last):
  File "F:\Elite\TD\trade.py", line 104, in <module>
    main(sys.argv)
  File "F:\Elite\TD\trade.py", line 77, in main
    results = cmdenv.run(tdb)
  File "F:\Elite\TD\commands\commandenv.py", line 81, in run
    return self._cmd.run(results, self, tdb)
  File "F:\Elite\TD\commands\run_cmd.py", line 1220, in run
    newRoutes = calc.getBestHops(routes, restrictTo=restrictTo)
  File "F:\Elite\TD\tradecalc.py", line 979, in getBestHops
    penalty = (-1 + 1 / (cruiseKls + 1) ** ((cruiseKls + 1) / 4)) / 2
OverflowError: (34, 'Result too large')

Possibly solved by going to logs. Will look into it if not fixed by this evening.

@eyeonus
Copy link
Owner

eyeonus commented Jun 19, 2018

That's odd, because that should always result in a number between 0 and -0.5.

Hmmm. Maybe it's the "x^(x/4)' bit that's overflowing?

I'll look into it.

@eyeonus
Copy link
Owner

eyeonus commented Jun 19, 2018

So, I did this:

                    try:
                        penalty = (-1 + 1 / (cruiseKls + 1) ** ((cruiseKls + 1) / 4)) / 2
                    except OverflowError as e:
                        print(str(e) + "cKls: " + str(cruiseKls))

and got this:

[                         ] (34, 'Result too large')cKls: 4218.0
[==                       ] (34, 'Result too large')cKls: 4218.0
[====                     ] (34, 'Result too large')cKls: 4218.0
[=============            ] (34, 'Result too large')cKls: 4218.0
[=========================] (34, 'Result too large')cKls: 514.4

First of all, what damned system has a station 4.2 MILLION ls away from the entry point?

Secondly, now I need to decide which of two options to use, those being:

  1. Use "sys.float_info.max" instead of "(cruiseKls + 1) ** ((cruiseKls + 1) / 4)" when an overflow occurs.
  2. Use the decimal module to do this math, which doesn't overflow until 9E+999999999999999999.
    (Which might still overflow if any stations are far enough away, but in that case I can easily get away with assuming "1/(cruiseKls + 1) ** ((cruiseKls + 1) / 4)" == 0.)

Thoughts?

@aadler
Copy link
Contributor Author

aadler commented Jun 19, 2018

4.2m ls, pshaw, that's nothing. Hutton Orbital in Proxima Centaurii is 6,784,404 ls! Over a 40 minute trip (I've yet to do it).

Converting the penalty into logs would look like:

penalty = (1 / exp(0.25 * (cruiseKls + 1) * log(cruiseKls + 1)) - 1) * 0.5

However, in this case, using logs doesn't really help, since log(Max(Double) is a hair over 709.78 and Hutton orbital would require exp(0.25 * 6201 * log(6201)) which becomes exp(13537.51) which overflows like mad. Actually, you have a form of Lambert W function here since you have a*Xe^X whew a is 0.25 and X is cruiseKls + 1. The largest Lambert W able to be calculated using double precision is a bit over 703.22. So, I'm not at home so I cannot try it, but perhaps the following will work:

cappeddist = min(0.25 * (cruiseKls + 1) * log(cruiseKls + 1), 709.78)
penalty = (1/exp(cappeddist) - 1) * 0.5

This should work and return the -0.5 for large numbers like Hutton Orbital without overflowing, If you haven't tried it by tonight, I will. Thanks!

@aadler
Copy link
Contributor Author

aadler commented Jun 19, 2018

Changed cap to 709.78 since we're not actually calculating Lambert W_0 but the exponentiation of capped dist. Not tghat it really matters, that's all going to be -0.5 anyway, we just need to make sure Python doesn't see a number it doesn't like.

if you wanted to use try, you'd probably want:

 try:
    penalty = (-1 + 1 / (cruiseKls + 1) ** ((cruiseKls + 1) / 4)) / 2
 except OverflowError:
    penalty = -0.5

Which is faster, try:except or the min?

@eyeonus
Copy link
Owner

eyeonus commented Jun 20, 2018

Your math is off.

https://goo.gl/nPgbth

(-1 + 1 / (x + 1) ** ((x + 1) / 4)) / 2 != (1 / exp(0.25 * (x + 1) * log(x + 1)) - 1) * 0.5

@aadler
Copy link
Contributor Author

aadler commented Jun 20, 2018

My math is correct when you take into account that the FooPlot website has an ln operator so log is base 10, where R and Python both assume log to be natural :)

http://bit.ly/2MpyRDt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants