Partial Derivatives Computation via Autodiff#
In this notebook, we show how to use the autodiff feature of \(\partial\textrm{SGP4}\). Due to the fact that it is written in pytorch, it automatically supports automatic differentiation via torch.autograd.
In this notebook, we show how these partial derivatives can be constructed: for more advanced examples on how to use these gradients for practical applications, see the tutorials on state_transition_matrix_computation, covariance_propagation, graident_based_optimization, orbit_determination.
import dsgp4
import torch
We create a TLE object
#as always, first, we create a TLE object:
tle=[]
tle.append('0 COSMOS 2251 DEB')
tle.append('1 34454U 93036SX 22068.91971155 .00000319 00000-0 11812-3 0 9996')
tle.append('2 34454 74.0583 280.7094 0037596 327.9100 31.9764 14.35844873683320')
tle = dsgp4.tle.TLE(tle)
print(tle)
TLE(
0 COSMOS 2251 DEB
1 34454U 93036SX 22068.91971155 .00000319 00000-0 11812-3 0 9996
2 34454 74.0583 280.7094 0037596 327.9100 31.9764 14.35844873683320
)
Now, as shown in the tle_propagation tutorial, we can propagate the TLE. However, instead of using the standard API, we require torch.autograd to record the operations w.r.t. the time.
Partials with respect to time#
Let’s compute the partials of the \(\partial \textrm{SGP4}\) output w.r.t. the propagation times
Single TLEs#
Let’s first see the case of single TLEs, propagated at various future times:
#let's take a random tensor of 10 tsince elements, where we track the gradients:
tsince=torch.rand((10,),requires_grad=True)
#the state is then:
state_teme = dsgp4.propagate(tle,
tsinces=tsince,
initialized=False)
#now, we can see that the gradient is tracked:
print(state_teme)
tensor([[[ 1.4099e+03, -6.9830e+03, 3.0732e+02],
[ 1.9574e+00, 7.0351e-01, 7.1956e+00]],
[[ 1.3858e+03, -6.9911e+03, 2.1903e+02],
[ 1.9763e+00, 6.0916e-01, 7.1992e+00]],
[[ 1.3796e+03, -6.9929e+03, 1.9659e+02],
[ 1.9811e+00, 5.8516e-01, 7.1999e+00]],
[[ 1.4191e+03, -6.9796e+03, 3.4107e+02],
[ 1.9501e+00, 7.3956e-01, 7.1939e+00]],
[[ 1.3681e+03, -6.9962e+03, 1.5490e+02],
[ 1.9898e+00, 5.4058e-01, 7.2010e+00]],
[[ 1.4362e+03, -6.9728e+03, 4.0455e+02],
[ 1.9363e+00, 8.0734e-01, 7.1903e+00]],
[[ 1.4227e+03, -6.9782e+03, 3.5456e+02],
[ 1.9472e+00, 7.5396e-01, 7.1932e+00]],
[[ 1.3261e+03, -7.0058e+03, 4.0446e+00],
[ 2.0209e+00, 3.7912e-01, 7.2029e+00]],
[[ 1.4171e+03, -6.9804e+03, 3.3356e+02],
[ 1.9518e+00, 7.3154e-01, 7.1943e+00]],
[[ 1.3495e+03, -7.0009e+03, 8.7635e+01],
[ 2.0038e+00, 4.6861e-01, 7.2023e+00]]],
grad_fn=<TransposeBackward0>)
Let’s now retrieve the partial derivatives of the SGP4 output w.r.t. time.
Since the state is position and velocity (i.e., \([x,y,z,v_x,v_y,v_z]\)), these partials will be all the elements of type:
Note
One thing to be careful about is that \(\partial\textrm{SGP4}\), mirroring the original \(\textrm{SGP4}\), takes the time in minutes, and returns the state in km and km/s. Hence, the derivatives will have dimensions coherent to these, and to return to SI, conversions have to be made.
partial_derivatives = torch.zeros_like(state_teme)
for i in [0,1]:
for j in [0,1,2]:
tsince.grad=None
state_teme[:,i,j].backward(torch.ones_like(tsince),retain_graph=True)
partial_derivatives[:,i,j] = tsince.grad
#let's print to screen the partials:
print(partial_derivatives)
tensor([[[ 1.1745e+02, 4.2211e+01, 4.3174e+02],
[-9.3126e-02, 4.6123e-01, -2.0352e-02]],
[[ 1.1858e+02, 3.6550e+01, 4.3195e+02],
[-9.1537e-02, 4.6178e-01, -1.4506e-02]],
[[ 1.1886e+02, 3.5110e+01, 4.3200e+02],
[-9.1131e-02, 4.6191e-01, -1.3019e-02]],
[[ 1.1701e+02, 4.4374e+01, 4.3164e+02],
[-9.3730e-02, 4.6100e-01, -2.2586e-02]],
[[ 1.1939e+02, 3.2435e+01, 4.3206e+02],
[-9.0373e-02, 4.6214e-01, -1.0259e-02]],
[[ 1.1618e+02, 4.8441e+01, 4.3142e+02],
[-9.4859e-02, 4.6053e-01, -2.6789e-02]],
[[ 1.1683e+02, 4.5238e+01, 4.3159e+02],
[-9.3970e-02, 4.6090e-01, -2.3479e-02]],
[[ 1.2125e+02, 2.2748e+01, 4.3217e+02],
[-8.7605e-02, 4.6281e-01, -2.6820e-04]],
[[ 1.1711e+02, 4.3893e+01, 4.3166e+02],
[-9.3596e-02, 4.6105e-01, -2.2089e-02]],
[[ 1.2023e+02, 2.8117e+01, 4.3214e+02],
[-8.9144e-02, 4.6246e-01, -5.8043e-03]]])
Batch TLEs#
Let’s now see how it works for batch TLEs. The API is basically identical:
#we load 6 TLEs:
inp_file="""0 PSLV DEB
1 35350U 01049QJ 22068.76869562 .00000911 00000-0 24939-3 0 9998
2 35350 98.6033 64.7516 0074531 99.8340 261.1278 14.48029442457561
0 PSLV DEB *
1 35351U 01049QK 22066.70636923 .00002156 00000-0 63479-3 0 9999
2 35351 98.8179 29.5651 0005211 45.5944 314.5671 14.44732274457505
0 SL-18 DEB
1 35354U 93014BD 22068.76520028 .00021929 00000-0 20751-2 0 9995
2 35354 75.7302 100.7819 0059525 350.7978 9.2117 14.92216400847487
0 SL-18 DEB
1 35359U 93014BJ 22068.55187275 .00025514 00000-0 24908-2 0 9992
2 35359 75.7369 156.1582 0054843 50.5279 310.0745 14.91164684775759
0 SL-18 DEB
1 35360U 93014BK 22068.44021735 .00019061 00000-0 20292-2 0 9992
2 35360 75.7343 127.2487 0071107 32.5913 327.9635 14.86997880798827
0 METEOR 2-17 DEB
1 35364U 88005Y 22067.81503681 .00001147 00000-0 84240-3 0 9995
2 35364 82.5500 92.4124 0018834 303.2489 178.0638 13.94853833332534"""
lines=inp_file.splitlines()
#let's create the TLE objects
tles=[]
for i in range(0,len(lines),3):
data=[]
data.append(lines[i])
data.append(lines[i+1])
data.append(lines[i+2])
tles.append(dsgp4.tle.TLE(data))
#we also create 9 random times, tracking the gradients:
tsinces=torch.rand((6,),requires_grad=True)
#let's initialize the TLEs:
_,tle_batch=dsgp4.initialize_tle(tles)
#let's propagate the batch:
state_teme = dsgp4.propagate_batch(tle_batch,
tsinces=tsinces)
Now, let’s retrieve the partial of each TLE, at each propagated time, and store them into a Nx2x3 matrix:
#let's retrieve the partials w.r.t. time:
partial_derivatives = torch.zeros_like(state_teme)
for i in [0,1]:
for j in [0,1,2]:
tsinces.grad=None
state_teme[:,i,j].backward(torch.ones_like(tsinces),retain_graph=True)
partial_derivatives[:,i,j] = tsinces.grad
#let's print to screen the partials:
print(partial_derivatives)
tensor([[[ 4.9378e+01, -5.2357e+01, 4.4309e+02],
[-2.0451e-01, -4.2536e-01, -2.3469e-02]],
[[ 3.0530e+01, -6.1774e+01, 4.4376e+02],
[-4.1098e-01, -2.3253e-01, -3.4300e-03]],
[[-1.0960e+02, -2.5490e+01, 4.4238e+02],
[ 9.4451e-02, -4.8948e-01, -4.7981e-03]],
[[-2.9549e+01, -1.0943e+02, 4.4102e+02],
[ 4.5492e-01, -1.9669e-01, -1.5723e-02]],
[[-7.5259e+01, -8.6355e+01, 4.4148e+02],
[ 3.0473e-01, -3.9142e-01, -2.2319e-02]],
[[ 4.7723e+01, -3.6421e+02, -2.4758e+02],
[ 3.7271e-02, 2.5447e-01, -3.6735e-01]]])
Partials with respect to TLE parameters#
Let’s now tackle the case in which we are interested in the partials of the \(\partial\textrm{SGP4}\) output w.r.t. the TLE parameters.
Single TLEs#
We first tackle the case of single TLE, propagated at multiple times:
In this case, we want the Jacobian of the output state, w.r.t. the following TLE parameters \(\textrm{TLE}=[n,e,i,\Omega,\omega,M,B^*,\dot{n},\ddot{n}]\), where:
\(n\) is the mean motion (also known as
no_kozaiin the original implementation) [rad/minute];\(e\) is the eccentricity [-];
\(i\) is the inclination [rad];
\(\Omega\) is the right ascension of the ascending node [rad];
\(\omega\) is the argument of perigee [rad];
\(M\) is the mean anomaly [rad];
\(B^*\) is the Bstar parameter [1/earth radii]
\(\dot{n}\) mean motion first derivative [radians/\(\textrm{minute}^2\)]
\(\ddot{n}\) mean motion second derivative [radians/\(\textrm{minute}^2\)]
#as always, first, we create a TLE object:
tle=[]
tle.append('0 COSMOS 2251 DEB')
tle.append('1 34454U 93036SX 22068.91971155 .00000319 00000-0 11812-3 0 9996')
tle.append('2 34454 74.0583 280.7094 0037596 327.9100 31.9764 14.35844873683320')
tle = dsgp4.tle.TLE(tle)
print(tle)
tle_elements=dsgp4.initialize_tle(tle,with_grad=True)
TLE(
0 COSMOS 2251 DEB
1 34454U 93036SX 22068.91971155 .00000319 00000-0 11812-3 0 9996
2 34454 74.0583 280.7094 0037596 327.9100 31.9764 14.35844873683320
)
#let's select 10 random times:
tsince=torch.rand((10,))
#and let's propagate:
state_teme=dsgp4.propagate(tle,tsince)
#now we can build the partial derivatives matrix, of shape Nx6x9 (N is the number of tsince elements, 6 is the number of elements in the state vector, and 9 is the number of elements in the TLE):
partial_derivatives = torch.zeros((len(tsince),6,9))
for k in range(len(tsince)):
for i in range(6):
tle_elements.grad=None
state_teme[k].flatten()[i].backward(retain_graph=True)
partial_derivatives[k,i,:] = tle_elements.grad
#let's print them to screen:
print(partial_derivatives)
tensor([[[-1.0290e-04, 0.0000e+00, 0.0000e+00, 9.5529e+02, 1.8829e+03,
-2.0776e+02, 1.8976e+03, -1.3829e+04, 6.9917e+03],
[-4.9195e-04, 0.0000e+00, 0.0000e+00, 6.4722e+03, 5.8697e+02,
-4.2673e+01, 5.7592e+02, 7.4615e+04, 1.3836e+03],
[-6.7337e-04, 0.0000e+00, 0.0000e+00, 7.4916e+03, 6.8542e+03,
5.6159e+01, 6.8976e+03, 9.7497e+02, 0.0000e+00],
[-9.6779e-07, 0.0000e+00, 0.0000e+00, 8.2747e-01, -1.4509e+00,
-7.0706e+00, -1.4596e+00, 9.8044e+00, -6.0060e-01],
[-6.1046e-07, 0.0000e+00, 0.0000e+00, 4.6251e+00, 7.3534e+00,
-1.3396e+00, 7.3752e+00, 6.7150e+00, 1.9780e+00],
[-3.7201e-06, 0.0000e+00, 0.0000e+00, 5.8588e+00, -2.0740e-01,
2.0509e+00, -2.2316e-01, 3.8218e+01, 0.0000e+00]],
[[-4.2917e-05, 0.0000e+00, 0.0000e+00, 9.4150e+02, 1.9056e+03,
-9.5860e+01, 1.9204e+03, -1.3988e+04, 7.0003e+03],
[-2.2350e-04, 0.0000e+00, 0.0000e+00, 6.4006e+03, 4.7055e+02,
-2.1472e+01, 4.5915e+02, 7.4530e+04, 1.3521e+03],
[-2.9280e-04, 0.0000e+00, 0.0000e+00, 7.3977e+03, 6.8566e+03,
2.3700e+01, 6.9002e+03, 3.6936e+02, 0.0000e+00],
[-4.5080e-07, 0.0000e+00, 0.0000e+00, 9.0388e-01, -1.4178e+00,
-7.0733e+00, -1.4264e+00, 1.0323e+01, -4.7873e-01],
[-2.6064e-07, 0.0000e+00, 0.0000e+00, 4.4309e+00, 7.3623e+00,
-1.3400e+00, 7.3846e+00, 4.1229e+00, 2.0018e+00],
[-1.7174e-06, 0.0000e+00, 0.0000e+00, 5.9956e+00, -8.7662e-02,
2.0516e+00, -1.0267e-01, 3.8316e+01, 0.0000e+00]],
[[-9.7105e-05, 0.0000e+00, 0.0000e+00, 9.5410e+02, 1.8849e+03,
-1.9773e+02, 1.8996e+03, -1.3843e+04, 6.9926e+03],
[-4.6759e-04, 0.0000e+00, 0.0000e+00, 6.4657e+03, 5.7654e+02,
-4.0772e+01, 5.6546e+02, 7.4606e+04, 1.3808e+03],
[-6.3763e-04, 0.0000e+00, 0.0000e+00, 7.4832e+03, 6.8545e+03,
5.3249e+01, 6.8979e+03, 9.2073e+02, 0.0000e+00],
[-9.2198e-07, 0.0000e+00, 0.0000e+00, 8.3436e-01, -1.4479e+00,
-7.0709e+00, -1.4566e+00, 9.8517e+00, -5.8968e-01],
[-5.7718e-07, 0.0000e+00, 0.0000e+00, 4.6078e+00, 7.3543e+00,
-1.3397e+00, 7.3761e+00, 6.4828e+00, 1.9802e+00],
[-3.5412e-06, 0.0000e+00, 0.0000e+00, 5.8713e+00, -1.9667e-01,
2.0510e+00, -2.1236e-01, 3.8230e+01, 0.0000e+00]],
[[-1.8383e-04, 0.0000e+00, 0.0000e+00, 9.6956e+02, 1.8563e+03,
-3.3561e+02, 1.8708e+03, -1.3657e+04, 6.9796e+03],
[-8.0780e-04, 0.0000e+00, 0.0000e+00, 6.5579e+03, 7.1987e+02,
-6.6895e+01, 7.0920e+02, 7.4764e+04, 1.4191e+03],
[-1.1566e-03, 0.0000e+00, 0.0000e+00, 7.5961e+03, 6.8492e+03,
9.3243e+01, 6.8924e+03, 1.6645e+03, 0.0000e+00],
[-1.5418e-06, 0.0000e+00, 0.0000e+00, 7.3901e-01, -1.4882e+00,
-7.0652e+00, -1.4970e+00, 9.1872e+00, -7.3970e-01],
[-1.0669e-06, 0.0000e+00, 0.0000e+00, 4.8407e+00, 7.3408e+00,
-1.3387e+00, 7.3619e+00, 9.6687e+00, 1.9501e+00],
[-5.9879e-06, 0.0000e+00, 0.0000e+00, 5.6944e+00, -3.4420e-01,
2.0494e+00, -3.6078e-01, 3.8015e+01, 0.0000e+00]],
[[-9.7239e-05, 0.0000e+00, 0.0000e+00, 9.5413e+02, 1.8849e+03,
-1.9796e+02, 1.8996e+03, -1.3843e+04, 6.9926e+03],
[-4.6816e-04, 0.0000e+00, 0.0000e+00, 6.4658e+03, 5.7678e+02,
-4.0816e+01, 5.6570e+02, 7.4606e+04, 1.3809e+03],
[-6.3846e-04, 0.0000e+00, 0.0000e+00, 7.4834e+03, 6.8545e+03,
5.3317e+01, 6.8979e+03, 9.2199e+02, 0.0000e+00],
[-9.2304e-07, 0.0000e+00, 0.0000e+00, 8.3420e-01, -1.4480e+00,
-7.0709e+00, -1.4567e+00, 9.8506e+00, -5.8993e-01],
[-5.7795e-07, 0.0000e+00, 0.0000e+00, 4.6082e+00, 7.3543e+00,
-1.3397e+00, 7.3761e+00, 6.4882e+00, 1.9801e+00],
[-3.5453e-06, 0.0000e+00, 0.0000e+00, 5.8710e+00, -1.9692e-01,
2.0510e+00, -2.1261e-01, 3.8229e+01, 0.0000e+00]],
[[-4.1423e-05, 0.0000e+00, 0.0000e+00, 9.4110e+02, 1.9062e+03,
-9.2804e+01, 1.9210e+03, -1.3993e+04, 7.0005e+03],
[-2.1627e-04, 0.0000e+00, 0.0000e+00, 6.3987e+03, 4.6737e+02,
-2.0893e+01, 4.5596e+02, 7.4528e+04, 1.3512e+03],
[-2.8296e-04, 0.0000e+00, 0.0000e+00, 7.3951e+03, 6.8566e+03,
2.2813e+01, 6.9003e+03, 3.5281e+02, 0.0000e+00],
[-4.3649e-07, 0.0000e+00, 0.0000e+00, 9.0595e-01, -1.4169e+00,
-7.0733e+00, -1.4255e+00, 1.0337e+01, -4.7540e-01],
[-2.5174e-07, 0.0000e+00, 0.0000e+00, 4.4255e+00, 7.3625e+00,
-1.3400e+00, 7.3849e+00, 4.0520e+00, 2.0025e+00],
[-1.6625e-06, 0.0000e+00, 0.0000e+00, 5.9992e+00, -8.4392e-02,
2.0516e+00, -9.9383e-02, 3.8317e+01, 0.0000e+00]],
[[-2.0277e-04, 0.0000e+00, 0.0000e+00, 9.7239e+02, 1.8505e+03,
-3.6288e+02, 1.8650e+03, -1.3622e+04, 6.9767e+03],
[-8.7658e-04, 0.0000e+00, 0.0000e+00, 6.5767e+03, 7.4821e+02,
-7.2064e+01, 7.3762e+02, 7.4802e+04, 1.4266e+03],
[-1.2663e-03, 0.0000e+00, 0.0000e+00, 7.6181e+03, 6.8479e+03,
1.0116e+02, 6.8909e+03, 1.8112e+03, 0.0000e+00],
[-1.6620e-06, 0.0000e+00, 0.0000e+00, 7.1998e-01, -1.4961e+00,
-7.0637e+00, -1.5049e+00, 9.0521e+00, -7.6936e-01],
[-1.1721e-06, 0.0000e+00, 0.0000e+00, 4.8859e+00, 7.3377e+00,
-1.3385e+00, 7.3587e+00, 1.0298e+01, 1.9440e+00],
[-6.4689e-06, 0.0000e+00, 0.0000e+00, 5.6583e+00, -3.7339e-01,
2.0490e+00, -3.9015e-01, 3.7959e+01, 0.0000e+00]],
[[-1.2283e-04, 0.0000e+00, 0.0000e+00, 9.5918e+02, 1.8760e+03,
-2.4125e+02, 1.8906e+03, -1.3783e+04, 6.9888e+03],
[-5.7368e-04, 0.0000e+00, 0.0000e+00, 6.4943e+03, 6.2179e+02,
-4.9017e+01, 6.1084e+02, 7.4649e+04, 1.3930e+03],
[-7.9495e-04, 0.0000e+00, 0.0000e+00, 7.5192e+03, 6.8532e+03,
6.5872e+01, 6.8965e+03, 1.1559e+03, 0.0000e+00],
[-1.1199e-06, 0.0000e+00, 0.0000e+00, 8.0441e-01, -1.4607e+00,
-7.0694e+00, -1.4694e+00, 9.6453e+00, -6.3705e-01],
[-7.2421e-07, 0.0000e+00, 0.0000e+00, 4.6822e+00, 7.3503e+00,
-1.3394e+00, 7.3720e+00, 7.4894e+00, 1.9708e+00],
[-4.3162e-06, 0.0000e+00, 0.0000e+00, 5.8165e+00, -2.4323e-01,
2.0506e+00, -2.5921e-01, 3.8174e+01, 0.0000e+00]],
[[-2.1661e-04, 0.0000e+00, 0.0000e+00, 9.7437e+02, 1.8464e+03,
-3.8230e+02, 1.8609e+03, -1.3597e+04, 6.9746e+03],
[-9.2585e-04, 0.0000e+00, 0.0000e+00, 6.5902e+03, 7.6837e+02,
-7.5743e+01, 7.5785e+02, 7.4831e+04, 1.4320e+03],
[-1.3459e-03, 0.0000e+00, 0.0000e+00, 7.6336e+03, 6.8468e+03,
1.0679e+02, 6.8898e+03, 1.9155e+03, 0.0000e+00],
[-1.7470e-06, 0.0000e+00, 0.0000e+00, 7.0641e-01, -1.5017e+00,
-7.0625e+00, -1.5105e+00, 8.9552e+00, -7.9047e-01],
[-1.2485e-06, 0.0000e+00, 0.0000e+00, 4.9178e+00, 7.3355e+00,
-1.3383e+00, 7.3563e+00, 1.0745e+01, 1.9397e+00],
[-6.8106e-06, 0.0000e+00, 0.0000e+00, 5.6323e+00, -3.9416e-01,
2.0487e+00, -4.1104e-01, 3.7917e+01, 0.0000e+00]],
[[-1.9585e-04, 0.0000e+00, 0.0000e+00, 9.7138e+02, 1.8526e+03,
-3.5301e+02, 1.8671e+03, -1.3635e+04, 6.9778e+03],
[-8.5163e-04, 0.0000e+00, 0.0000e+00, 6.5699e+03, 7.3795e+02,
-7.0194e+01, 7.2734e+02, 7.4788e+04, 1.4239e+03],
[-1.2263e-03, 0.0000e+00, 0.0000e+00, 7.6102e+03, 6.8484e+03,
9.8293e+01, 6.8914e+03, 1.7582e+03, 0.0000e+00],
[-1.6186e-06, 0.0000e+00, 0.0000e+00, 7.2687e-01, -1.4932e+00,
-7.0642e+00, -1.5020e+00, 9.1011e+00, -7.5863e-01],
[-1.1337e-06, 0.0000e+00, 0.0000e+00, 4.8696e+00, 7.3388e+00,
-1.3386e+00, 7.3599e+00, 1.0070e+01, 1.9462e+00],
[-6.2950e-06, 0.0000e+00, 0.0000e+00, 5.6714e+00, -3.6283e-01,
2.0491e+00, -3.7952e-01, 3.7980e+01, 0.0000e+00]]])
Batch TLEs:#
As for the time derivatives, the API stays practically identical:
#we load 6 TLEs:
inp_file="""0 PSLV DEB
1 35350U 01049QJ 22068.76869562 .00000911 00000-0 24939-3 0 9998
2 35350 98.6033 64.7516 0074531 99.8340 261.1278 14.48029442457561
0 PSLV DEB *
1 35351U 01049QK 22066.70636923 .00002156 00000-0 63479-3 0 9999
2 35351 98.8179 29.5651 0005211 45.5944 314.5671 14.44732274457505
0 SL-18 DEB
1 35354U 93014BD 22068.76520028 .00021929 00000-0 20751-2 0 9995
2 35354 75.7302 100.7819 0059525 350.7978 9.2117 14.92216400847487
0 SL-18 DEB
1 35359U 93014BJ 22068.55187275 .00025514 00000-0 24908-2 0 9992
2 35359 75.7369 156.1582 0054843 50.5279 310.0745 14.91164684775759
0 SL-18 DEB
1 35360U 93014BK 22068.44021735 .00019061 00000-0 20292-2 0 9992
2 35360 75.7343 127.2487 0071107 32.5913 327.9635 14.86997880798827
0 METEOR 2-17 DEB
1 35364U 88005Y 22067.81503681 .00001147 00000-0 84240-3 0 9995
2 35364 82.5500 92.4124 0018834 303.2489 178.0638 13.94853833332534"""
lines=inp_file.splitlines()
#let's create the TLE objects
tles=[]
for i in range(0,len(lines),3):
data=[]
data.append(lines[i])
data.append(lines[i+1])
data.append(lines[i+2])
tles.append(dsgp4.tle.TLE(data))
#we also create 6 random times, tracking the gradients:
tsinces=torch.rand((6,))
#let's now initialize the TLEs, activating the gradient tracking for the TLE parameters:
tle_elements,tle_batch=dsgp4.initialize_tle(tles,with_grad=True)
#let's now propagate the batch of TLEs:
state_teme = dsgp4.propagate_batch(tle_batch,tsinces)
Finally, we can build the matrix that contains the partial of the SGP4 output w.r.t. the TLE parameters, for each TLE:
#now we can build the partial derivatives matrix, of shape Nx6x9 (N is the number of tsince elements, 6 is the number of elements in the state vector, and 9 is the number of elements in the TLE):
partial_derivatives = torch.zeros((len(tsinces),6,9))
for k in range(len(tsinces)):
for i in range(6):
tle_elements[k].grad=None
state_teme[k].flatten()[i].backward(retain_graph=True)
partial_derivatives[k,i,:] = tle_elements[k].grad
#let's print them to screen:
print(partial_derivatives)
tensor([[[-4.9020e-04, 0.0000e+00, 0.0000e+00, -1.2224e+03, 7.9342e+02,
3.4696e+02, 7.6931e+02, -3.1873e+04, -6.4040e+03],
[-2.3272e-03, 0.0000e+00, 0.0000e+00, 2.3475e+03, -8.1264e+02,
-1.6574e+02, -8.5869e+02, -6.8245e+04, 3.0844e+03],
[ 3.6289e-03, 0.0000e+00, 0.0000e+00, -1.3917e+04, 7.0296e+03,
-5.5760e+01, 7.0153e+03, 1.8675e+03, 0.0000e+00],
[-1.6420e-06, 0.0000e+00, 0.0000e+00, 3.1372e+00, -3.2516e+00,
6.6733e+00, -3.2429e+00, 1.4763e+00, 9.0310e-01],
[-1.4123e-06, 0.0000e+00, 0.0000e+00, 6.7931e+00, -6.7319e+00,
-3.1486e+00, -6.7330e+00, -1.0522e+01, 8.0830e-01],
[-5.8180e-06, 0.0000e+00, 0.0000e+00, -3.9592e-01, -4.6026e-01,
-1.1138e+00, -4.0520e-01, 3.8614e+01, 0.0000e+00]],
[[-5.0940e-04, 0.0000e+00, 0.0000e+00, -4.8206e+03, 1.4454e+02,
2.1509e+02, 1.4249e+02, -6.5542e+04, -3.4474e+03],
[-5.2013e-04, 0.0000e+00, 0.0000e+00, -1.0005e+03, -1.1717e+03,
-3.8313e+02, -1.1738e+03, -3.7564e+04, 6.2151e+03],
[ 1.2962e-03, 0.0000e+00, 0.0000e+00, -9.7170e+03, 7.0247e+03,
-6.5685e+01, 7.0300e+03, 2.1595e+03, 0.0000e+00],
[-1.1084e-06, 0.0000e+00, 0.0000e+00, 4.4855e+00, -6.5405e+00,
3.6389e+00, -6.5430e+00, -5.6289e+00, 1.2312e+00],
[ 7.1698e-07, 0.0000e+00, 0.0000e+00, 1.5103e+00, -3.6273e+00,
-6.4176e+00, -3.6291e+00, -1.0053e+01, 1.4889e-01],
[-7.5295e-06, 0.0000e+00, 0.0000e+00, 5.8031e+00, -4.6603e-01,
-1.1419e+00, -4.6364e-01, 3.8589e+01, 0.0000e+00]],
[[-1.3342e-03, 0.0000e+00, 0.0000e+00, 6.6165e+02, -1.5976e+03,
3.9582e+02, -1.6181e+03, 1.2836e+04, -6.7772e+03],
[ 7.6721e-03, 0.0000e+00, 0.0000e+00, -6.9725e+03, -7.3516e+02,
7.8571e+01, -7.3480e+02, -6.9994e+04, -1.3948e+03],
[-4.8653e-04, 0.0000e+00, 0.0000e+00, 2.5706e+03, 6.7066e+03,
9.8571e+01, 6.7856e+03, 1.9121e+03, 0.0000e+00],
[ 7.2034e-06, 0.0000e+00, 0.0000e+00, -1.3694e+00, 1.5306e+00,
7.2261e+00, 1.5418e+00, -7.5632e+00, 7.9648e-01],
[ 2.8074e-06, 0.0000e+00, 0.0000e+00, -2.4345e+00, -7.4481e+00,
1.3786e+00, -7.4908e+00, -1.0820e+01, -1.7526e+00],
[-2.9849e-05, 0.0000e+00, 0.0000e+00, 7.0843e+00, -4.3421e-01,
1.8666e+00, -4.4639e-01, 3.7297e+01, 0.0000e+00]],
[[-1.1024e-03, 0.0000e+00, 0.0000e+00, 5.0430e+03, -5.8754e+02,
3.9709e+01, -5.6511e+02, 6.5067e+04, -2.7848e+03],
[-2.0733e-04, 0.0000e+00, 0.0000e+00, 6.4662e+02, -1.6138e+03,
9.7394e+01, -1.6371e+03, -2.8862e+04, -6.3670e+03],
[ 2.4974e-03, 0.0000e+00, 0.0000e+00, -1.0338e+04, 6.7364e+03,
2.2848e+01, 6.7843e+03, 3.9016e+02, 0.0000e+00],
[ 1.8910e-06, 0.0000e+00, 0.0000e+00, -5.7155e+00, 6.9620e+00,
2.9690e+00, 6.9845e+00, -1.5475e+00, 1.7721e+00],
[ 9.7589e-07, 0.0000e+00, 0.0000e+00, 1.1707e+00, -3.0365e+00,
6.7235e+00, -3.0548e+00, -9.7481e+00, -6.1148e-01],
[-6.5077e-06, 0.0000e+00, 0.0000e+00, 4.8794e+00, -1.4488e-01,
1.8638e+00, -1.1469e-01, 3.7663e+01, 0.0000e+00]],
[[-8.6886e-04, 0.0000e+00, 0.0000e+00, 5.0009e+03, -1.3195e+03,
4.9386e+01, -1.3196e+03, 4.3133e+04, -5.5190e+03],
[ 6.3914e-04, 0.0000e+00, 0.0000e+00, -3.5490e+03, -1.0948e+03,
4.1352e+01, -1.1290e+03, -5.6802e+04, -4.2168e+03],
[ 1.1979e-03, 0.0000e+00, 0.0000e+00, -7.2029e+03, 6.7326e+03,
1.2500e+01, 6.8144e+03, 1.8176e+02, 0.0000e+00],
[ 1.2279e-06, 0.0000e+00, 0.0000e+00, -3.6705e+00, 4.6244e+00,
5.8589e+00, 4.6472e+00, -6.6819e+00, 1.2187e+00],
[ 1.3361e-07, 0.0000e+00, 0.0000e+00, 2.1827e+00, -6.0408e+00,
4.4576e+00, -6.0823e+00, -7.0567e+00, -1.4243e+00],
[-4.1569e-06, 0.0000e+00, 0.0000e+00, 6.2998e+00, -9.7282e-02,
1.8672e+00, -7.0124e-02, 3.7846e+01, 0.0000e+00]],
[[-1.3604e-05, 0.0000e+00, 0.0000e+00, -6.2679e+02, 7.8085e+02,
6.0208e+03, 7.7792e+02, 7.2725e+03, 4.0763e+03],
[ 6.8271e-05, 0.0000e+00, 0.0000e+00, -3.9915e+03, -6.0597e+03,
2.5291e+02, -6.0368e+03, 4.0629e+04, -6.1698e+02],
[ 7.7289e-05, 0.0000e+00, 0.0000e+00, 6.0699e+03, -4.0133e+03,
7.8828e+02, -3.9983e+03, -6.8689e+04, 0.0000e+00],
[-2.3562e-07, 0.0000e+00, 0.0000e+00, -7.9275e-01, 6.2432e-01,
-4.0474e+00, 6.2316e-01, 4.7137e+00, 6.1200e+00],
[ 1.8402e-06, 0.0000e+00, 0.0000e+00, 6.0967e+00, 4.1185e+00,
-1.6925e-01, 4.1107e+00, -3.0804e+01, 7.8798e-01],
[ 1.2056e-06, 0.0000e+00, 0.0000e+00, 4.0975e+00, -6.0994e+00,
-5.2787e-01, -6.0880e+00, -2.6185e+01, 0.0000e+00]]])