Closed AndreaMalgarini closed 6 years ago
Thank you very much for reporting this ! The thorough investigation and proposed solution is very much appreciated! I believe this is related to what was reported in #22 too. I will have a closer look a bit later as I am on business trip until the end of the week.
If you have the time, a pull request would be great :) I don't have any particular preference for the method used, but if we can avoid depending in scipy, that would be nice. Not that scipy is a problem it itself, it's just adding a dependency to the package that troubles me.
This is the reference code for the brentq
method in Scipy.
We're gonna try to see if we can easily implement it exploiting numpy vectorization.
If performances are not satisfying, @mraspaud what is you opinion about Cython wrapping? I think that at that moment would be easier to add scipy
as dep.
PS: I work w/ @AndreaMalgarini :)
In my opinion, I'd rather depend on scipy than replicate the functionality of the brentq function inside it. That is, if there are no significant modifications to the algorithm.
@AndreaMalgarini and @rubendibattista thanks for your work on this. I've been encountering issues that I am pretty sure are related to this for months, but they've been rare enough and intermittent enough that they never bothered me enough to look for the root cause until now. If you would like me to test anything, let me know and I will put it through it's paces as well.
@kevincroissant Thanks for the kind words. @AndreaMalgarini already tested in several cases but having more tests is clearly appreciated.
Problem description and minimal code This issue is located in the secant function within
get_next_passes
. It is not properly an error in the sense that the solution of the zero finding functionget_root_secant
given the initial bounds (which are guessed) is not able to find the zero but instead diverges leading to an unfeasible solution. What should be done is either change method, going for a more robust (such as Scipy'sbrentq
as @rubendibattista suggested) or write checks for this case so to have an adaptive initial guess.This particular issue can be reproduced with the satellite
LEMUR-2-BROWNCOW [43125]
with the TLEs reported here:The coordinates for which passages are trying to be found are :
The day for which the problem happens is
2018-09-08
with atime of propagation
set to 72 hours and anhorizon
set to 5 degrees. The output is the following:What can be noticed is the date, which is 2108. What happens is that the method
get_root_secant
fails to arrive at a feasible zero, hence, it diverges and goes in a search region, in terms of time, where the satellite is crashed.The fact this was not noticed can be explained by its rarity. I discovered it performing a huge number of simulations; it happened once for a list of 30 satellites in 180 days propagation scenario. So it has a very low probability to happen. Still it should be better to fix it.
Possible solutions One of the proposed solution, a sort of adaptive secant method, can be formulated like this:
It is just an idea, quite raw, but I tested on different scenarios and it works.
A second possibility is to employ
brentq
like this:This solution is quite cleaner and definitely more robust On the benchmark note it showed to be slightly slower than the previous.
Versions of Python 2.7.15rc1, package at hand and relevant dependencies pyorbital v1.3.1.