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.3919e+03, -6.9892e+03, 2.4119e+02],
[ 1.9716e+00, 6.3285e-01, 7.1984e+00]],
[[ 1.3954e+03, -6.9880e+03, 2.5419e+02],
[ 1.9688e+00, 6.4673e-01, 7.1979e+00]],
[[ 1.4238e+03, -6.9778e+03, 3.5857e+02],
[ 1.9463e+00, 7.5825e-01, 7.1930e+00]],
[[ 1.3352e+03, -7.0040e+03, 3.6308e+01],
[ 2.0143e+00, 4.1367e-01, 7.2028e+00]],
[[ 1.4175e+03, -6.9802e+03, 3.3537e+02],
[ 1.9514e+00, 7.3347e-01, 7.1942e+00]],
[[ 1.3961e+03, -6.9878e+03, 2.5670e+02],
[ 1.9683e+00, 6.4942e-01, 7.1978e+00]],
[[ 1.3845e+03, -6.9915e+03, 2.1416e+02],
[ 1.9773e+00, 6.0394e-01, 7.1993e+00]],
[[ 1.3531e+03, -7.0000e+03, 1.0063e+02],
[ 2.0011e+00, 4.8252e-01, 7.2021e+00]],
[[ 1.4309e+03, -6.9750e+03, 3.8471e+02],
[ 1.9406e+00, 7.8616e-01, 7.1915e+00]],
[[ 1.3827e+03, -6.9920e+03, 2.0788e+02],
[ 1.9787e+00, 5.9724e-01, 7.1995e+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.1830e+02, 3.7971e+01, 4.3191e+02],
[-9.1937e-02, 4.6165e-01, -1.5973e-02]],
[[ 1.1813e+02, 3.8804e+01, 4.3188e+02],
[-9.2172e-02, 4.6157e-01, -1.6833e-02]],
[[ 1.1678e+02, 4.5495e+01, 4.3158e+02],
[-9.4042e-02, 4.6087e-01, -2.3745e-02]],
[[ 1.2086e+02, 2.4820e+01, 4.3217e+02],
[-8.8200e-02, 4.6268e-01, -2.4050e-03]],
[[ 1.1708e+02, 4.4009e+01, 4.3166e+02],
[-9.3628e-02, 4.6104e-01, -2.2209e-02]],
[[ 1.1810e+02, 3.8966e+01, 4.3187e+02],
[-9.2217e-02, 4.6156e-01, -1.7000e-02]],
[[ 1.1864e+02, 3.6237e+01, 4.3196e+02],
[-9.1449e-02, 4.6181e-01, -1.4183e-02]],
[[ 1.2007e+02, 2.8951e+01, 4.3213e+02],
[-8.9382e-02, 4.6241e-01, -6.6651e-03]],
[[ 1.1644e+02, 4.7170e+01, 4.3149e+02],
[-9.4507e-02, 4.6068e-01, -2.5475e-02]],
[[ 1.1872e+02, 3.5835e+01, 4.3197e+02],
[-9.1335e-02, 4.6185e-01, -1.3767e-02]]])
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([[[ 5.5717e+01, -3.9090e+01, 4.4358e+02],
[-2.0253e-01, -4.2658e-01, -8.1456e-03]],
[[ 2.9100e+01, -6.2583e+01, 4.4374e+02],
[-4.1110e-01, -2.3229e-01, -5.1401e-03]],
[[-1.0821e+02, -3.2632e+01, 4.4225e+02],
[ 9.6357e-02, -4.8897e-01, -1.2560e-02]],
[[-3.1063e+01, -1.0878e+02, 4.4107e+02],
[ 4.5478e-01, -1.9711e-01, -1.3972e-02]],
[[-7.3310e+01, -8.8854e+01, 4.4132e+02],
[ 3.0533e-01, -3.9079e-01, -2.5690e-02]],
[[ 4.7610e+01, -3.6498e+02, -2.4646e+02],
[ 3.7419e-02, 2.5334e-01, -3.6812e-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([[[-2.2113e-04, 0.0000e+00, 0.0000e+00, 9.7500e+02, 1.8451e+03,
-3.8854e+02, 1.8596e+03, -1.3589e+04, 6.9739e+03],
[-9.4176e-04, 0.0000e+00, 0.0000e+00, 6.5945e+03, 7.7486e+02,
-7.6927e+01, 7.6435e+02, 7.4841e+04, 1.4337e+03],
[-1.3717e-03, 0.0000e+00, 0.0000e+00, 7.6386e+03, 6.8464e+03,
1.0860e+02, 6.8894e+03, 1.9490e+03, 0.0000e+00],
[-1.7743e-06, 0.0000e+00, 0.0000e+00, 7.0204e-01, -1.5035e+00,
-7.0622e+00, -1.5123e+00, 8.9239e+00, -7.9726e-01],
[-1.2734e-06, 0.0000e+00, 0.0000e+00, 4.9281e+00, 7.3347e+00,
-1.3382e+00, 7.3556e+00, 1.0889e+01, 1.9383e+00],
[-6.9204e-06, 0.0000e+00, 0.0000e+00, 5.6239e+00, -4.0085e-01,
2.0486e+00, -4.1777e-01, 3.7903e+01, 0.0000e+00]],
[[-2.2166e-04, 0.0000e+00, 0.0000e+00, 9.7507e+02, 1.8449e+03,
-3.8927e+02, 1.8594e+03, -1.3588e+04, 6.9738e+03],
[-9.4362e-04, 0.0000e+00, 0.0000e+00, 6.5950e+03, 7.7561e+02,
-7.7064e+01, 7.6511e+02, 7.4842e+04, 1.4339e+03],
[-1.3747e-03, 0.0000e+00, 0.0000e+00, 7.6392e+03, 6.8464e+03,
1.0881e+02, 6.8894e+03, 1.9529e+03, 0.0000e+00],
[-1.7775e-06, 0.0000e+00, 0.0000e+00, 7.0153e-01, -1.5037e+00,
-7.0621e+00, -1.5125e+00, 8.9202e+00, -7.9805e-01],
[-1.2763e-06, 0.0000e+00, 0.0000e+00, 4.9293e+00, 7.3346e+00,
-1.3382e+00, 7.3555e+00, 1.0906e+01, 1.9382e+00],
[-6.9331e-06, 0.0000e+00, 0.0000e+00, 5.6230e+00, -4.0163e-01,
2.0486e+00, -4.1855e-01, 3.7901e+01, 0.0000e+00]],
[[-1.0232e-04, 0.0000e+00, 0.0000e+00, 9.5517e+02, 1.8831e+03,
-2.0676e+02, 1.8978e+03, -1.3830e+04, 6.9918e+03],
[-4.8951e-04, 0.0000e+00, 0.0000e+00, 6.4716e+03, 5.8593e+02,
-4.2482e+01, 5.7488e+02, 7.4614e+04, 1.3833e+03],
[-6.6978e-04, 0.0000e+00, 0.0000e+00, 7.4907e+03, 6.8543e+03,
5.5868e+01, 6.8977e+03, 9.6954e+02, 0.0000e+00],
[-9.6320e-07, 0.0000e+00, 0.0000e+00, 8.2816e-01, -1.4506e+00,
-7.0706e+00, -1.4593e+00, 9.8092e+00, -5.9951e-01],
[-6.0711e-07, 0.0000e+00, 0.0000e+00, 4.6233e+00, 7.3535e+00,
-1.3396e+00, 7.3753e+00, 6.6917e+00, 1.9782e+00],
[-3.7022e-06, 0.0000e+00, 0.0000e+00, 5.8600e+00, -2.0633e-01,
2.0509e+00, -2.2208e-01, 3.8219e+01, 0.0000e+00]],
[[-5.7190e-05, 0.0000e+00, 0.0000e+00, 9.4511e+02, 1.8998e+03,
-1.2430e+02, 1.9147e+03, -1.3947e+04, 6.9983e+03],
[-2.9109e-04, 0.0000e+00, 0.0000e+00, 6.4185e+03, 5.0015e+02,
-2.6860e+01, 4.8884e+02, 7.4548e+04, 1.3602e+03],
[-3.8577e-04, 0.0000e+00, 0.0000e+00, 7.4217e+03, 6.8561e+03,
3.1950e+01, 6.8997e+03, 5.2341e+02, 0.0000e+00],
[-5.8347e-07, 0.0000e+00, 0.0000e+00, 8.8455e-01, -1.4262e+00,
-7.0728e+00, -1.4349e+00, 1.0193e+01, -5.0972e-01],
[-3.4510e-07, 0.0000e+00, 0.0000e+00, 4.4807e+00, 7.3602e+00,
-1.3400e+00, 7.3824e+00, 4.7823e+00, 1.9958e+00],
[-2.2279e-06, 0.0000e+00, 0.0000e+00, 5.9614e+00, -1.1810e-01,
2.0515e+00, -1.3330e-01, 3.8298e+01, 0.0000e+00]],
[[-2.4484e-06, 0.0000e+00, 0.0000e+00, 9.2962e+02, 1.9233e+03,
-6.4782e+00, 1.9383e+03, -1.4121e+04, 7.0057e+03],
[-1.3783e-05, 0.0000e+00, 0.0000e+00, 6.3456e+03, 3.7748e+02,
-4.5389e+00, 3.6580e+02, 7.4491e+04, 1.3267e+03],
[-1.7377e-05, 0.0000e+00, 0.0000e+00, 7.3212e+03, 6.8571e+03,
-2.2259e+00, 6.9009e+03, -1.1499e+02, 0.0000e+00],
[-2.8331e-08, 0.0000e+00, 0.0000e+00, 9.6419e-01, -1.3911e+00,
-7.0740e+00, -1.3996e+00, 1.0722e+01, -3.8130e-01],
[-1.5208e-08, 0.0000e+00, 0.0000e+00, 4.2723e+00, 7.3679e+00,
-1.3401e+00, 7.3907e+00, 2.0490e+00, 2.0205e+00],
[-1.0717e-07, 0.0000e+00, 0.0000e+00, 6.1000e+00, 7.9765e-03,
2.0517e+00, -6.4294e-03, 3.8340e+01, 0.0000e+00]],
[[-2.0948e-04, 0.0000e+00, 0.0000e+00, 9.7336e+02, 1.8485e+03,
-3.7234e+02, 1.8630e+03, -1.3610e+04, 6.9757e+03],
[-9.0055e-04, 0.0000e+00, 0.0000e+00, 6.5832e+03, 7.5803e+02,
-7.3856e+01, 7.4747e+02, 7.4816e+04, 1.4292e+03],
[-1.3049e-03, 0.0000e+00, 0.0000e+00, 7.6257e+03, 6.8473e+03,
1.0390e+02, 6.8904e+03, 1.8620e+03, 0.0000e+00],
[-1.7035e-06, 0.0000e+00, 0.0000e+00, 7.1337e-01, -1.4988e+00,
-7.0631e+00, -1.5076e+00, 9.0050e+00, -7.7964e-01],
[-1.2091e-06, 0.0000e+00, 0.0000e+00, 4.9015e+00, 7.3366e+00,
-1.3384e+00, 7.3576e+00, 1.0516e+01, 1.9419e+00],
[-6.6354e-06, 0.0000e+00, 0.0000e+00, 5.6457e+00, -3.8351e-01,
2.0488e+00, -4.0033e-01, 3.7939e+01, 0.0000e+00]],
[[-1.9688e-04, 0.0000e+00, 0.0000e+00, 9.7153e+02, 1.8523e+03,
-3.5449e+02, 1.8668e+03, -1.3633e+04, 6.9776e+03],
[-8.5535e-04, 0.0000e+00, 0.0000e+00, 6.5709e+03, 7.3948e+02,
-7.0473e+01, 7.2887e+02, 7.4790e+04, 1.4243e+03],
[-1.2323e-03, 0.0000e+00, 0.0000e+00, 7.6113e+03, 6.8483e+03,
9.8720e+01, 6.8914e+03, 1.7661e+03, 0.0000e+00],
[-1.6251e-06, 0.0000e+00, 0.0000e+00, 7.2585e-01, -1.4936e+00,
-7.0641e+00, -1.5025e+00, 9.0938e+00, -7.6023e-01],
[-1.1394e-06, 0.0000e+00, 0.0000e+00, 4.8720e+00, 7.3387e+00,
-1.3385e+00, 7.3597e+00, 1.0104e+01, 1.9459e+00],
[-6.3209e-06, 0.0000e+00, 0.0000e+00, 5.6695e+00, -3.6440e-01,
2.0491e+00, -3.8111e-01, 3.7977e+01, 0.0000e+00]],
[[-9.2573e-05, 0.0000e+00, 0.0000e+00, 9.5315e+02, 1.8865e+03,
-1.8978e+02, 1.9013e+03, -1.3854e+04, 6.9932e+03],
[-4.4835e-04, 0.0000e+00, 0.0000e+00, 6.4605e+03, 5.6827e+02,
-3.9266e+01, 5.5717e+02, 7.4599e+04, 1.3786e+03],
[-6.0955e-04, 0.0000e+00, 0.0000e+00, 7.4766e+03, 6.8547e+03,
5.0944e+01, 6.8982e+03, 8.7776e+02, 0.0000e+00],
[-8.8563e-07, 0.0000e+00, 0.0000e+00, 8.3981e-01, -1.4456e+00,
-7.0712e+00, -1.4543e+00, 9.8891e+00, -5.8103e-01],
[-5.5110e-07, 0.0000e+00, 0.0000e+00, 4.5942e+00, 7.3550e+00,
-1.3397e+00, 7.3769e+00, 6.2989e+00, 1.9819e+00],
[-3.3994e-06, 0.0000e+00, 0.0000e+00, 5.8812e+00, -1.8816e-01,
2.0510e+00, -2.0380e-01, 3.8238e+01, 0.0000e+00]],
[[-1.4326e-05, 0.0000e+00, 0.0000e+00, 9.3340e+02, 1.9178e+03,
-3.4295e+01, 1.9327e+03, -1.4079e+04, 7.0042e+03],
[-7.8638e-05, 0.0000e+00, 0.0000e+00, 6.3625e+03, 4.0645e+02,
-9.8085e+00, 3.9486e+02, 7.4500e+04, 1.3346e+03],
[-1.0037e-04, 0.0000e+00, 0.0000e+00, 7.3451e+03, 6.8570e+03,
5.8425e+00, 6.9008e+03, 3.5774e+01, 0.0000e+00],
[-1.6071e-07, 0.0000e+00, 0.0000e+00, 9.4549e-01, -1.3994e+00,
-7.0739e+00, -1.4080e+00, 1.0599e+01, -4.1163e-01],
[-8.8325e-08, 0.0000e+00, 0.0000e+00, 4.3220e+00, 7.3663e+00,
-1.3401e+00, 7.3889e+00, 2.6947e+00, 2.0147e+00],
[-6.0928e-07, 0.0000e+00, 0.0000e+00, 6.0680e+00, -2.1788e-02,
2.0517e+00, -3.6383e-02, 3.8338e+01, 0.0000e+00]],
[[-1.0969e-05, 0.0000e+00, 0.0000e+00, 9.3236e+02, 1.9193e+03,
-2.6586e+01, 1.9343e+03, -1.4091e+04, 7.0046e+03],
[-6.0628e-05, 0.0000e+00, 0.0000e+00, 6.3578e+03, 3.9842e+02,
-8.3480e+00, 3.8680e+02, 7.4497e+04, 1.3324e+03],
[-7.7122e-05, 0.0000e+00, 0.0000e+00, 7.3385e+03, 6.8571e+03,
3.6064e+00, 6.9009e+03, -6.0073e+00, 0.0000e+00],
[-1.2410e-07, 0.0000e+00, 0.0000e+00, 9.5068e-01, -1.3971e+00,
-7.0740e+00, -1.4056e+00, 1.0634e+01, -4.0323e-01],
[-6.7765e-08, 0.0000e+00, 0.0000e+00, 4.3082e+00, 7.3667e+00,
-1.3401e+00, 7.3894e+00, 2.5158e+00, 2.0163e+00],
[-4.7021e-07, 0.0000e+00, 0.0000e+00, 6.0769e+00, -1.3539e-02,
2.0517e+00, -2.8082e-02, 3.8339e+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([[[-1.2178e-05, 0.0000e+00, 0.0000e+00, -1.3776e+03, 9.5683e+02,
8.7639e+00, 9.3222e+02, -3.2040e+04, -6.4406e+03],
[-6.0338e-05, 0.0000e+00, 0.0000e+00, 2.0040e+03, -4.7084e+02,
-6.1694e+00, -5.1697e+02, -6.7903e+04, 3.0391e+03],
[ 9.7244e-05, 0.0000e+00, 0.0000e+00, -1.3877e+04, 7.0429e+03,
6.8563e-01, 7.0258e+03, -1.0100e+02, 0.0000e+00],
[-4.1970e-08, 0.0000e+00, 0.0000e+00, 2.9910e+00, -3.2021e+00,
6.6834e+00, -3.1910e+00, 5.1174e+00, 5.4348e-01],
[-3.6635e-08, 0.0000e+00, 0.0000e+00, 6.7609e+00, -6.7668e+00,
-3.1532e+00, -6.7626e+00, -2.9423e+00, 9.7975e-01],
[-1.4717e-07, 0.0000e+00, 0.0000e+00, -1.1807e+00, -6.5192e-02,
-1.1154e+00, -1.0777e-02, 3.9016e+01, 0.0000e+00]],
[[-2.5691e-04, 0.0000e+00, 0.0000e+00, -4.9526e+03, 3.3106e+02,
1.1118e+02, 3.2907e+02, -6.5441e+04, -3.4810e+03],
[-2.7619e-04, 0.0000e+00, 0.0000e+00, -1.0465e+03, -1.0677e+03,
-1.9988e+02, -1.0697e+03, -3.7310e+04, 6.2081e+03],
[ 7.3120e-04, 0.0000e+00, 0.0000e+00, -9.8787e+03, 7.0348e+03,
-3.3079e+01, 7.0400e+03, 1.0524e+03, 0.0000e+00],
[-6.1533e-07, 0.0000e+00, 0.0000e+00, 4.7625e+00, -6.5325e+00,
3.6442e+00, -6.5349e+00, -1.4774e+00, 1.1220e+00],
[ 3.4540e-07, 0.0000e+00, 0.0000e+00, 1.7185e+00, -3.6623e+00,
-6.4267e+00, -3.6641e+00, -7.7667e+00, 3.4480e-01],
[-3.8853e-06, 0.0000e+00, 0.0000e+00, 5.5165e+00, -2.4371e-01,
-1.1434e+00, -2.4114e-01, 3.8975e+01, 0.0000e+00]],
[[-3.1632e-04, 0.0000e+00, 0.0000e+00, 7.2484e+02, -1.6619e+03,
8.3384e+01, -1.6829e+03, 1.3195e+04, -6.8041e+03],
[ 1.5967e-03, 0.0000e+00, 0.0000e+00, -6.8820e+03, -4.1278e+02,
1.8972e+01, -4.1055e+02, -6.9682e+04, -1.3176e+03],
[ 4.7428e-05, 0.0000e+00, 0.0000e+00, 2.2606e+03, 6.7178e+03,
1.7863e+01, 6.7973e+03, 2.8940e+02, 0.0000e+00],
[ 1.5634e-06, 0.0000e+00, 0.0000e+00, -1.5414e+00, 1.4460e+00,
7.2386e+00, 1.4564e+00, -9.0472e+00, 4.4482e-01],
[ 3.2935e-07, 0.0000e+00, 0.0000e+00, -1.7523e+00, -7.4769e+00,
1.3806e+00, -7.5207e+00, -3.6313e+00, -1.8228e+00],
[-6.2725e-06, 0.0000e+00, 0.0000e+00, 7.2472e+00, -8.5625e-02,
1.8696e+00, -9.3743e-02, 3.7743e+01, 0.0000e+00]],
[[-3.8078e-05, 0.0000e+00, 0.0000e+00, 5.1221e+03, -6.8279e+02,
-9.4419e-01, -6.6066e+02, 6.5102e+04, -2.8087e+03],
[-7.3104e-06, 0.0000e+00, 0.0000e+00, 6.2997e+02, -1.5721e+03,
5.3314e+00, -1.5951e+03, -2.8735e+04, -6.3579e+03],
[ 8.6792e-05, 0.0000e+00, 0.0000e+00, -1.0404e+04, 6.7376e+03,
-2.6736e+00, 6.7851e+03, -1.2578e+02, 0.0000e+00],
[ 6.6465e-08, 0.0000e+00, 0.0000e+00, -5.8329e+00, 6.9513e+00,
2.9694e+00, 6.9729e+00, -3.6720e+00, 1.7266e+00],
[ 3.1775e-08, 0.0000e+00, 0.0000e+00, 1.2691e+00, -3.0623e+00,
6.7242e+00, -3.0804e+00, -8.8173e+00, -7.1504e-01],
[-2.1966e-07, 0.0000e+00, 0.0000e+00, 4.7118e+00, -3.4923e-02,
1.8640e+00, -3.9473e-03, 3.7692e+01, 0.0000e+00]],
[[-1.4497e-03, 0.0000e+00, 0.0000e+00, 4.9795e+03, -1.2925e+03,
8.3605e+01, -1.2925e+03, 4.3096e+04, -5.5118e+03],
[ 1.0723e-03, 0.0000e+00, 0.0000e+00, -3.5365e+03, -1.1300e+03,
6.7387e+01, -1.1645e+03, -5.6845e+04, -4.2251e+03],
[ 1.9850e-03, 0.0000e+00, 0.0000e+00, -7.1660e+03, 6.7319e+03,
2.3407e+01, 6.8138e+03, 4.0276e+02, 0.0000e+00],
[ 2.0388e-06, 0.0000e+00, 0.0000e+00, -3.6300e+00, 4.6336e+00,
5.8584e+00, 4.6568e+00, -6.0765e+00, 1.2571e+00],
[ 2.5913e-07, 0.0000e+00, 0.0000e+00, 2.1090e+00, -6.0332e+00,
4.4573e+00, -6.0749e+00, -7.8444e+00, -1.3950e+00],
[-6.9909e-06, 0.0000e+00, 0.0000e+00, 6.3484e+00, -1.4425e-01,
1.8671e+00, -1.1767e-01, 3.7826e+01, 0.0000e+00]],
[[-7.4234e-06, 0.0000e+00, 0.0000e+00, -6.1633e+02, 7.7246e+02,
6.0741e+03, 7.6955e+02, 7.2109e+03, 3.9945e+03],
[ 3.2895e-05, 0.0000e+00, 0.0000e+00, -4.0735e+03, -6.1140e+03,
2.5514e+02, -6.0910e+03, 4.1047e+04, -6.2742e+02],
[ 4.3050e-05, 0.0000e+00, 0.0000e+00, 6.0164e+03, -3.9318e+03,
7.9523e+02, -3.9169e+03, -6.8352e+04, 0.0000e+00],
[-1.5551e-07, 0.0000e+00, 0.0000e+00, -7.7583e-01, 6.3487e-01,
-3.9650e+00, 6.3366e-01, 4.5343e+00, 6.1749e+00],
[ 1.2303e-06, 0.0000e+00, 0.0000e+00, 6.2065e+00, 4.0355e+00,
-1.6573e-01, 4.0280e+00, -3.2051e+01, 7.7951e-01],
[ 7.9069e-07, 0.0000e+00, 0.0000e+00, 3.9325e+00, -6.1534e+00,
-5.1717e-01, -6.1418e+00, -2.4406e+01, 0.0000e+00]]])