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.3428e+03, -7.0024e+03, 6.3510e+01],
[ 2.0087e+00, 4.4279e-01, 7.2026e+00]],
[[ 1.3425e+03, -7.0025e+03, 6.2618e+01],
[ 2.0089e+00, 4.4183e-01, 7.2026e+00]],
[[ 1.3744e+03, -6.9945e+03, 1.7760e+02],
[ 1.9850e+00, 5.6485e-01, 7.2004e+00]],
[[ 1.4196e+03, -6.9794e+03, 3.4307e+02],
[ 1.9497e+00, 7.4169e-01, 7.1938e+00]],
[[ 1.4247e+03, -6.9775e+03, 3.6179e+02],
[ 1.9456e+00, 7.6169e-01, 7.1928e+00]],
[[ 1.3329e+03, -7.0045e+03, 2.8033e+01],
[ 2.0160e+00, 4.0481e-01, 7.2028e+00]],
[[ 1.3979e+03, -6.9872e+03, 2.6328e+02],
[ 1.9669e+00, 6.5645e-01, 7.1975e+00]],
[[ 1.4303e+03, -6.9753e+03, 3.8240e+02],
[ 1.9411e+00, 7.8370e-01, 7.1916e+00]],
[[ 1.3358e+03, -7.0039e+03, 3.8482e+01],
[ 2.0139e+00, 4.1600e-01, 7.2027e+00]],
[[ 1.4264e+03, -6.9768e+03, 3.6803e+02],
[ 1.9443e+00, 7.6835e-01, 7.1925e+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.2053e+02, 2.6568e+01, 4.3215e+02],
[-8.8701e-02, 4.6257e-01, -4.2065e-03]],
[[ 1.2054e+02, 2.6510e+01, 4.3215e+02],
[-8.8685e-02, 4.6257e-01, -4.1474e-03]],
[[ 1.1910e+02, 3.3891e+01, 4.3203e+02],
[-9.0786e-02, 4.6202e-01, -1.1762e-02]],
[[ 1.1698e+02, 4.4502e+01, 4.3163e+02],
[-9.3765e-02, 4.6098e-01, -2.2718e-02]],
[[ 1.1674e+02, 4.5702e+01, 4.3157e+02],
[-9.4099e-02, 4.6085e-01, -2.3958e-02]],
[[ 1.2096e+02, 2.4289e+01, 4.3217e+02],
[-8.8048e-02, 4.6272e-01, -1.8570e-03]],
[[ 1.1801e+02, 3.9387e+01, 4.3185e+02],
[-9.2335e-02, 4.6152e-01, -1.7435e-02]],
[[ 1.1647e+02, 4.7022e+01, 4.3150e+02],
[-9.4466e-02, 4.6070e-01, -2.5322e-02]],
[[ 1.2083e+02, 2.4960e+01, 4.3217e+02],
[-8.8241e-02, 4.6267e-01, -2.5490e-03]],
[[ 1.1666e+02, 4.6102e+01, 4.3155e+02],
[-9.4210e-02, 4.6080e-01, -2.4371e-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.2087e+01, -4.6708e+01, 4.4336e+02],
[-2.0369e-01, -4.2594e-01, -1.6938e-02]],
[[ 2.0800e+01, -6.7255e+01, 4.4354e+02],
[-4.1169e-01, -2.3086e-01, -1.5060e-02]],
[[-1.0761e+02, -3.5677e+01, 4.4216e+02],
[ 9.7162e-02, -4.8871e-01, -1.5870e-02]],
[[-1.7434e+01, -1.1462e+02, 4.4042e+02],
[ 4.5586e-01, -1.9323e-01, -2.9717e-02]],
[[-8.7815e+01, -7.0039e+01, 4.4195e+02],
[ 3.0051e-01, -3.9504e-01, -4.1868e-04]],
[[ 4.7116e+01, -3.6827e+02, -2.4161e+02],
[ 3.8052e-02, 2.4842e-01, -3.7138e-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.9182e-04, 0.0000e+00, 0.0000e+00, 9.7077e+02, 1.8538e+03,
-3.4722e+02, 1.8684e+03, -1.3642e+04, 6.9784e+03],
[-8.3701e-04, 0.0000e+00, 0.0000e+00, 6.5659e+03, 7.3193e+02,
-6.9095e+01, 7.2130e+02, 7.4780e+04, 1.4223e+03],
[-1.2030e-03, 0.0000e+00, 0.0000e+00, 7.6055e+03, 6.8487e+03,
9.6612e+01, 6.8918e+03, 1.7270e+03, 0.0000e+00],
[-1.5931e-06, 0.0000e+00, 0.0000e+00, 7.3092e-01, -1.4915e+00,
-7.0645e+00, -1.5003e+00, 9.1298e+00, -7.5233e-01],
[-1.1114e-06, 0.0000e+00, 0.0000e+00, 4.8600e+00, 7.3395e+00,
-1.3386e+00, 7.3605e+00, 9.9365e+00, 1.9475e+00],
[-6.1928e-06, 0.0000e+00, 0.0000e+00, 5.6791e+00, -3.5662e-01,
2.0492e+00, -3.7328e-01, 3.7992e+01, 0.0000e+00]],
[[-7.9182e-06, 0.0000e+00, 0.0000e+00, 9.3139e+02, 1.9207e+03,
-1.9478e+01, 1.9357e+03, -1.4102e+04, 7.0050e+03],
[-4.4047e-05, 0.0000e+00, 0.0000e+00, 6.3534e+03, 3.9102e+02,
-7.0015e+00, 3.7938e+02, 7.4495e+04, 1.3304e+03],
[-5.5855e-05, 0.0000e+00, 0.0000e+00, 7.3324e+03, 6.8571e+03,
1.5447e+00, 6.9009e+03, -4.4532e+01, 0.0000e+00],
[-9.0295e-08, 0.0000e+00, 0.0000e+00, 9.5546e-01, -1.3950e+00,
-7.0740e+00, -1.4035e+00, 1.0665e+01, -3.9548e-01],
[-4.9009e-08, 0.0000e+00, 0.0000e+00, 4.2955e+00, 7.3671e+00,
-1.3401e+00, 7.3899e+00, 2.3508e+00, 2.0178e+00],
[-3.4193e-07, 0.0000e+00, 0.0000e+00, 6.0851e+00, -5.9330e-03,
2.0517e+00, -2.0428e-02, 3.8340e+01, 0.0000e+00]],
[[-1.5783e-04, 0.0000e+00, 0.0000e+00, 9.6538e+02, 1.8644e+03,
-2.9671e+02, 1.8790e+03, -1.3708e+04, 6.9836e+03],
[-7.1060e-04, 0.0000e+00, 0.0000e+00, 6.5314e+03, 6.7945e+02,
-5.9526e+01, 6.6867e+02, 7.4713e+04, 1.4084e+03],
[-1.0041e-03, 0.0000e+00, 0.0000e+00, 7.5646e+03, 6.8510e+03,
8.1962e+01, 6.8942e+03, 1.4551e+03, 0.0000e+00],
[-1.3691e-06, 0.0000e+00, 0.0000e+00, 7.6604e-01, -1.4769e+00,
-7.0671e+00, -1.4856e+00, 9.3778e+00, -6.9740e-01],
[-9.2174e-07, 0.0000e+00, 0.0000e+00, 4.7758e+00, 7.3449e+00,
-1.3390e+00, 7.3662e+00, 8.7711e+00, 1.9587e+00],
[-5.3004e-06, 0.0000e+00, 0.0000e+00, 5.7453e+00, -3.0258e-01,
2.0499e+00, -3.1892e-01, 3.8087e+01, 0.0000e+00]],
[[-2.6336e-06, 0.0000e+00, 0.0000e+00, 9.2968e+02, 1.9232e+03,
-6.9240e+00, 1.9382e+03, -1.4121e+04, 7.0057e+03],
[-1.4820e-05, 0.0000e+00, 0.0000e+00, 6.3458e+03, 3.7795e+02,
-4.6233e+00, 3.6626e+02, 7.4491e+04, 1.3268e+03],
[-1.8688e-05, 0.0000e+00, 0.0000e+00, 7.3216e+03, 6.8571e+03,
-2.0966e+00, 6.9009e+03, -1.1257e+02, 0.0000e+00],
[-3.0459e-08, 0.0000e+00, 0.0000e+00, 9.6389e-01, -1.3912e+00,
-7.0740e+00, -1.3997e+00, 1.0720e+01, -3.8179e-01],
[-1.6356e-08, 0.0000e+00, 0.0000e+00, 4.2731e+00, 7.3679e+00,
-1.3401e+00, 7.3907e+00, 2.0593e+00, 2.0204e+00],
[-1.1523e-07, 0.0000e+00, 0.0000e+00, 6.0995e+00, 7.4995e-03,
2.0517e+00, -6.9094e-03, 3.8340e+01, 0.0000e+00]],
[[-1.0479e-04, 0.0000e+00, 0.0000e+00, 9.5567e+02, 1.8822e+03,
-2.1101e+02, 1.8969e+03, -1.3825e+04, 6.9915e+03],
[-4.9985e-04, 0.0000e+00, 0.0000e+00, 6.4744e+03, 5.9035e+02,
-4.3288e+01, 5.7931e+02, 7.4618e+04, 1.3845e+03],
[-6.8501e-04, 0.0000e+00, 0.0000e+00, 7.4942e+03, 6.8541e+03,
5.7102e+01, 6.8975e+03, 9.9253e+02, 0.0000e+00],
[-9.8259e-07, 0.0000e+00, 0.0000e+00, 8.2523e-01, -1.4518e+00,
-7.0705e+00, -1.4605e+00, 9.7891e+00, -6.0414e-01],
[-6.2131e-07, 0.0000e+00, 0.0000e+00, 4.6306e+00, 7.3531e+00,
-1.3396e+00, 7.3749e+00, 6.7901e+00, 1.9773e+00],
[-3.7780e-06, 0.0000e+00, 0.0000e+00, 5.8547e+00, -2.1088e-01,
2.0509e+00, -2.2666e-01, 3.8214e+01, 0.0000e+00]],
[[-4.4560e-05, 0.0000e+00, 0.0000e+00, 9.4193e+02, 1.9049e+03,
-9.9204e+01, 1.9197e+03, -1.3983e+04, 7.0001e+03],
[-2.3143e-04, 0.0000e+00, 0.0000e+00, 6.4027e+03, 4.7403e+02,
-2.2105e+01, 4.6264e+02, 7.4532e+04, 1.3531e+03],
[-3.0359e-04, 0.0000e+00, 0.0000e+00, 7.4005e+03, 6.8565e+03,
2.4670e+01, 6.9002e+03, 3.8748e+02, 0.0000e+00],
[-4.6644e-07, 0.0000e+00, 0.0000e+00, 9.0161e-01, -1.4188e+00,
-7.0732e+00, -1.4274e+00, 1.0308e+01, -4.8237e-01],
[-2.7041e-07, 0.0000e+00, 0.0000e+00, 4.4367e+00, 7.3620e+00,
-1.3400e+00, 7.3844e+00, 4.2004e+00, 2.0011e+00],
[-1.7775e-06, 0.0000e+00, 0.0000e+00, 5.9916e+00, -9.1240e-02,
2.0516e+00, -1.0627e-01, 3.8314e+01, 0.0000e+00]],
[[-1.2099e-04, 0.0000e+00, 0.0000e+00, 9.5883e+02, 1.8766e+03,
-2.3821e+02, 1.8913e+03, -1.3787e+04, 6.9891e+03],
[-5.6625e-04, 0.0000e+00, 0.0000e+00, 6.4923e+03, 6.1864e+02,
-4.8442e+01, 6.0768e+02, 7.4646e+04, 1.3921e+03],
[-7.8379e-04, 0.0000e+00, 0.0000e+00, 7.5167e+03, 6.8533e+03,
6.4992e+01, 6.8966e+03, 1.1395e+03, 0.0000e+00],
[-1.1061e-06, 0.0000e+00, 0.0000e+00, 8.0651e-01, -1.4598e+00,
-7.0695e+00, -1.4685e+00, 9.6598e+00, -6.3375e-01],
[-7.1374e-07, 0.0000e+00, 0.0000e+00, 4.6770e+00, 7.3506e+00,
-1.3395e+00, 7.3723e+00, 7.4193e+00, 1.9714e+00],
[-4.2623e-06, 0.0000e+00, 0.0000e+00, 5.8204e+00, -2.3999e-01,
2.0506e+00, -2.5594e-01, 3.8178e+01, 0.0000e+00]],
[[-6.9409e-05, 0.0000e+00, 0.0000e+00, 9.4803e+02, 1.8951e+03,
-1.4766e+02, 1.9099e+03, -1.3914e+04, 6.9966e+03],
[-3.4691e-04, 0.0000e+00, 0.0000e+00, 6.4334e+03, 5.2446e+02,
-3.1286e+01, 5.1322e+02, 7.4564e+04, 1.3667e+03],
[-4.6404e-04, 0.0000e+00, 0.0000e+00, 7.4414e+03, 6.8557e+03,
3.8726e+01, 6.8993e+03, 6.4987e+02, 0.0000e+00],
[-6.9179e-07, 0.0000e+00, 0.0000e+00, 8.6863e-01, -1.4331e+00,
-7.0723e+00, -1.4418e+00, 1.0085e+01, -5.3516e-01],
[-4.1674e-07, 0.0000e+00, 0.0000e+00, 4.5214e+00, 7.3584e+00,
-1.3399e+00, 7.3805e+00, 5.3235e+00, 1.9909e+00],
[-2.6464e-06, 0.0000e+00, 0.0000e+00, 5.9330e+00, -1.4309e-01,
2.0513e+00, -1.5845e-01, 3.8280e+01, 0.0000e+00]],
[[-2.2520e-04, 0.0000e+00, 0.0000e+00, 9.7556e+02, 1.8439e+03,
-3.9413e+02, 1.8584e+03, -1.3582e+04, 6.9732e+03],
[-9.5601e-04, 0.0000e+00, 0.0000e+00, 6.5984e+03, 7.8066e+02,
-7.7985e+01, 7.7017e+02, 7.4849e+04, 1.4352e+03],
[-1.3949e-03, 0.0000e+00, 0.0000e+00, 7.6430e+03, 6.8461e+03,
1.1022e+02, 6.8891e+03, 1.9790e+03, 0.0000e+00],
[-1.7987e-06, 0.0000e+00, 0.0000e+00, 6.9813e-01, -1.5051e+00,
-7.0618e+00, -1.5139e+00, 8.8958e+00, -8.0333e-01],
[-1.2958e-06, 0.0000e+00, 0.0000e+00, 4.9372e+00, 7.3341e+00,
-1.3381e+00, 7.3549e+00, 1.1018e+01, 1.9371e+00],
[-7.0185e-06, 0.0000e+00, 0.0000e+00, 5.6164e+00, -4.0683e-01,
2.0485e+00, -4.2378e-01, 3.7890e+01, 0.0000e+00]],
[[-1.5446e-04, 0.0000e+00, 0.0000e+00, 9.6482e+02, 1.8655e+03,
-2.9155e+02, 1.8801e+03, -1.3715e+04, 6.9841e+03],
[-6.9776e-04, 0.0000e+00, 0.0000e+00, 6.5279e+03, 6.7408e+02,
-5.8547e+01, 6.6329e+02, 7.4706e+04, 1.4069e+03],
[-9.8423e-04, 0.0000e+00, 0.0000e+00, 7.5604e+03, 6.8512e+03,
8.0463e+01, 6.8945e+03, 1.4273e+03, 0.0000e+00],
[-1.3460e-06, 0.0000e+00, 0.0000e+00, 7.6963e-01, -1.4754e+00,
-7.0673e+00, -1.4841e+00, 9.4029e+00, -6.9178e-01],
[-9.0286e-07, 0.0000e+00, 0.0000e+00, 4.7672e+00, 7.3454e+00,
-1.3391e+00, 7.3668e+00, 8.6518e+00, 1.9598e+00],
[-5.2089e-06, 0.0000e+00, 0.0000e+00, 5.7520e+00, -2.9706e-01,
2.0500e+00, -3.1336e-01, 3.8096e+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([[[-2.8298e-04, 0.0000e+00, 0.0000e+00, -1.2882e+03, 8.6201e+02,
2.0569e+02, 8.3770e+02, -3.1920e+04, -6.4215e+03],
[-1.3682e-03, 0.0000e+00, 0.0000e+00, 2.2038e+03, -6.7002e+02,
-9.9081e+01, -7.1606e+02, -6.8055e+04, 3.0665e+03],
[ 2.1645e-03, 0.0000e+00, 0.0000e+00, -1.3905e+04, 7.0376e+03,
-3.2181e+01, 7.0221e+03, 1.0474e+03, 0.0000e+00],
[-9.6069e-07, 0.0000e+00, 0.0000e+00, 3.0803e+00, -3.2320e+00,
6.6798e+00, -3.2223e+00, 3.0098e+00, 7.5301e-01],
[-8.3281e-07, 0.0000e+00, 0.0000e+00, 6.7890e+00, -6.7489e+00,
-3.1516e+00, -6.7477e+00, -7.3623e+00, 8.8029e-01],
[-3.3853e-06, 0.0000e+00, 0.0000e+00, -7.2515e-01, -2.9518e-01,
-1.1149e+00, -2.4032e-01, 3.8877e+01, 0.0000e+00]],
[[-2.6467e-05, 0.0000e+00, 0.0000e+00, -5.0877e+03, 5.1122e+02,
1.0546e+01, 5.0930e+02, -6.5455e+04, -3.5105e+03],
[-2.9936e-05, 0.0000e+00, 0.0000e+00, -1.0966e+03, -9.6614e+02,
-2.2407e+01, -9.6815e+02, -3.7126e+04, 6.1959e+03],
[ 8.3615e-05, 0.0000e+00, 0.0000e+00, -1.0027e+04, 7.0386e+03,
-1.5033e+00, 7.0437e+03, -2.6009e+01, 0.0000e+00],
[-6.9317e-08, 0.0000e+00, 0.0000e+00, 5.0141e+00, -6.5191e+00,
3.6462e+00, -6.5213e+00, 2.5306e+00, 1.0153e+00],
[ 3.4039e-08, 0.0000e+00, 0.0000e+00, 1.9140e+00, -3.6931e+00,
-6.4300e+00, -3.6948e+00, -5.5177e+00, 5.3404e-01],
[-4.1042e-07, 0.0000e+00, 0.0000e+00, 5.2203e+00, -2.8433e-02,
-1.1439e+00, -2.5702e-02, 3.9114e+01, 0.0000e+00]],
[[-2.0259e-04, 0.0000e+00, 0.0000e+00, 7.3139e+02, -1.6679e+03,
5.2936e+01, -1.6890e+03, 1.3234e+04, -6.8059e+03],
[ 1.0106e-03, 0.0000e+00, 0.0000e+00, -6.8747e+03, -3.8133e+02,
1.3165e+01, -3.7891e+02, -6.9668e+04, -1.3099e+03],
[ 3.9220e-05, 0.0000e+00, 0.0000e+00, 2.2300e+03, 6.7181e+03,
9.9977e+00, 6.7976e+03, 1.3062e+02, 0.0000e+00],
[ 9.9298e-07, 0.0000e+00, 0.0000e+00, -1.5574e+00, 1.4376e+00,
7.2390e+00, 1.4479e+00, -9.1841e+00, 4.1051e-01],
[ 1.9250e-07, 0.0000e+00, 0.0000e+00, -1.6849e+00, -7.4788e+00,
1.3807e+00, -7.5227e+00, -2.9285e+00, -1.8295e+00],
[-3.9718e-06, 0.0000e+00, 0.0000e+00, 7.2596e+00, -5.1657e-02,
1.8697e+00, -5.9375e-02, 3.7755e+01, 0.0000e+00]],
[[-3.6068e-03, 0.0000e+00, 0.0000e+00, 4.8540e+03, -3.5059e+02,
1.4055e+02, -3.2735e+02, 6.5104e+04, -2.7227e+03],
[-6.3332e-04, 0.0000e+00, 0.0000e+00, 6.8205e+02, -1.7159e+03,
3.2576e+02, -1.7398e+03, -2.9232e+04, -6.3834e+03],
[ 8.0104e-03, 0.0000e+00, 0.0000e+00, -1.0166e+04, 6.7268e+03,
8.6162e+01, 6.7757e+03, 1.6656e+03, 0.0000e+00],
[ 5.8620e-06, 0.0000e+00, 0.0000e+00, -5.4019e+00, 6.9817e+00,
2.9650e+00, 7.0064e+00, 3.7467e+00, 1.8834e+00],
[ 3.6655e-06, 0.0000e+00, 0.0000e+00, 9.2200e-01, -2.9695e+00,
6.7151e+00, -2.9882e+00, -1.1997e+01, -3.5380e-01],
[-2.2475e-05, 0.0000e+00, 0.0000e+00, 5.2764e+00, -4.1773e-01,
1.8616e+00, -3.8961e-01, 3.7335e+01, 0.0000e+00]],
[[-1.9270e-03, 0.0000e+00, 0.0000e+00, 4.9620e+03, -1.2700e+03,
1.1202e+02, -1.2699e+03, 4.3068e+04, -5.5056e+03],
[ 1.4319e-03, 0.0000e+00, 0.0000e+00, -3.5264e+03, -1.1593e+03,
8.9010e+01, -1.1939e+03, -5.6885e+04, -4.2318e+03],
[ 2.6229e-03, 0.0000e+00, 0.0000e+00, -7.1350e+03, 6.7311e+03,
3.2465e+01, 6.8132e+03, 5.8622e+02, 0.0000e+00],
[ 2.6987e-06, 0.0000e+00, 0.0000e+00, -3.5958e+00, 4.6410e+00,
5.8578e+00, 4.6645e+00, -5.5720e+00, 1.2890e+00],
[ 3.8490e-07, 0.0000e+00, 0.0000e+00, 2.0475e+00, -6.0267e+00,
4.4569e+00, -6.0685e+00, -8.4973e+00, -1.3705e+00],
[-9.3530e-06, 0.0000e+00, 0.0000e+00, 6.3880e+00, -1.8326e-01,
1.8670e+00, -1.5716e-01, 3.7801e+01, 0.0000e+00]],
[[-1.3825e-05, 0.0000e+00, 0.0000e+00, -6.2712e+02, 7.8111e+02,
6.0191e+03, 7.7818e+02, 7.2745e+03, 4.0789e+03],
[ 6.9583e-05, 0.0000e+00, 0.0000e+00, -3.9889e+03, -6.0579e+03,
2.5284e+02, -6.0351e+03, 4.0616e+04, -6.1665e+02],
[ 7.8502e-05, 0.0000e+00, 0.0000e+00, 6.0716e+03, -4.0159e+03,
7.8806e+02, -4.0009e+03, -6.8700e+04, 0.0000e+00],
[-2.3815e-07, 0.0000e+00, 0.0000e+00, -7.9327e-01, 6.2399e-01,
-4.0499e+00, 6.2282e-01, 4.7192e+00, 6.1182e+00],
[ 1.8592e-06, 0.0000e+00, 0.0000e+00, 6.0932e+00, 4.1211e+00,
-1.6936e-01, 4.1133e+00, -3.0764e+01, 7.8824e-01],
[ 1.2188e-06, 0.0000e+00, 0.0000e+00, 4.1026e+00, -6.0977e+00,
-5.2821e-01, -6.0863e+00, -2.6240e+01, 0.0000e+00]]])