-
-
Notifications
You must be signed in to change notification settings - Fork 92
Description
I'd like implement an additional API for "zipped" parallel computation with the SatrecArray. The current computation uses the "outer product" of the Satrecs and the julian dates, generating a total of len(satrec_array) * len(jds) state vectors. This is not efficient if when want each Satrec propagated to a different time, e.g., we want to compute
states = [satrec.sgp4(jd, fr) for satrec, jd, fr in zip(satrec_array.satrecs, jds, frs)]Our options for this use case are:
- Use a for loop in python as above. This means we loose the C++ accelerated parallelism.
- Use the C++ vectorized computation---this requires N^2 computations when we only need N.
The changes required to implement a new method are fairly minimal and I'd be happy to make a PR. Basically, I propose that we have a new API on SatrecArray. In the python version, it would look like this:
class SatrecArray:
# ...
def sgp4_zip(self, jds, frs):
"""Compute positions and velocities for the satellites in this array each at a different time.
Given NumPy scalars or arrays ``jd`` and ``fr`` supplying the
whole part and the fractional part of one or more Julian dates,
return a tuple ``(e, r, v)`` of three vectors that are each as
long as ``jd`` and ``fr``:
* ``e``: nonzero for any dates that produced errors, 0 otherwise.
* ``r``: (x,y,z) position vector in kilometers.
* ``v``: (dx,dy,dz) velocity vector in kilometers per second.
This method differs from ``SatrecArray.sgp4`` in that the input ``jd`` and ``fr``
must have the same number of elements as ``Satrec``s in the array, and each
output has ``len(jd)`` elements instead of ``len(jd) * len(satrecs)``.
"""
results = []
z = list(zip(self._satrecs, jd, fr))
for satrec in z:
results.append(satrec.sgp4(jd_i, fr_i))
elist, rlist, vlist = zip(*results)
e = self.array(elist)
r = self.array(rlist)
v = self.array(vlist)
jdlen = len(jd)
mylen = len(self._satrecs)
e.shape = (mylen)
r.shape = v.shape = (mylen, 3)
return e, r, vAs you can see, the code above is almost identical to the existing code in model.py. I believe it's similarly easy to add a method to wrapper.cpp to support this API.
Feedback requests
In light of this, I'd like feedback on the following:
- Would you welcome a pull request for this? And, assuming that the answer is affirmative,
- How do you feel about the name
sgp4_zip? I'm not super fond of it, but I'm having trouble thinking of a better one. Perhapssgp4_vectorized, but that's a little overloaded since both methods onSatrecArrayare vectorized. - I know that this would require an update to
sgp4/__init__.pyfor documentation,sgp4/model.pyfor python implementation,sgp4/tests.pyfor tests,sgp4/wrapper.pyfor delegation to the C-implementation, and finallyextension/wrapper.cppfor the C-implementation itself. Is there anything else to be done? - Anything I forgot?
Thanks in advance.