-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanalysis.py
82 lines (63 loc) · 2.71 KB
/
analysis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""
Information theoretic analysis of the satellite network.
"""
import numpy as np
from sat.core import satellite
def fpost_sanity_check(f_post: np.ndarray, sat: satellite, verbose: bool, state_dim: int):
"""
Perform a sanity check on the Posterior FIM of the satellite. The FIM should be positive definite.\
Args:
f_post (np.ndarray): The Posterior FIM of the satellite.
sat (satellite): The satellite object.
verbose (bool): Whether to print the FIM and its properties.
state_dim (int): The dimension of the state vector.
Raises:
ValueError: If the FIM of the satellite is not positive definite.
"""
if np.linalg.matrix_rank(f_post) == state_dim:
if not np.all(np.linalg.eigvals(sat.cov_m - np.linalg.inv(f_post)) > 0):
raise ValueError(f"FIM of satellite {sat.id} is not positive definite")
# # Check if f_post is invertible
if np.linalg.matrix_rank(f_post) != state_dim:
if verbose:
print(f_post)
print(f"Satellite {sat.id} FIM is not invertible")
else:
eig_val, eig_vec = np.linalg.eig(f_post)
if verbose:
print(f"Eigenvalues of satellite {sat.id} FIM: ", eig_val)
print("Condition number of FIM: ", np.linalg.cond(f_post))
print("Eigenvectors of FIM: ", eig_vec)
def get_cov_trace(timesteps: int, cov_hist: np.ndarray, n_sats: int) -> np.ndarray:
"""
Calculate the trace of the covariance matrix over all time steps
and normalize it by the number of satellites.
Args:
timesteps (int): The number of time steps.
cov_hist (np.ndarray): The covariance matrix over all time steps.
n_sats (int): The number of satellites.
Returns:
np.ndarray: The satellite-normalized trace of the covariance matrix.
"""
cov_trace = np.zeros((timesteps))
for i in range(timesteps):
cov_trace[i] = np.trace(cov_hist[i, :, :]) / n_sats
# pos_error[i,:] = pos_error[i,:]/n_sats
return cov_trace
def get_crb_trace(timesteps: int, pfim: np.ndarray, n_sats: int) -> np.ndarray:
"""
Get the Cramer-Rao Bound (CRB) trace of the Posterior FIM over all time steps
and normalize it by the number of satellites.
Args:
timesteps (int): The number of time steps.
pfim (np.ndarray): The Posterior Fisher Information Matrix (PFIM).
n_sats (int): The number of satellites.
Returns:
np.ndarray: The satellite-normalized trace of the CRB.
"""
crb = np.zeros_like(pfim)
crb_trace = np.zeros((timesteps))
for i in range(timesteps):
crb[i, :, :] = np.linalg.inv(pfim[i, :, :])
crb_trace[i] = np.trace(crb[i, :, :]) / n_sats
return crb_trace