11import numpy as np
22from numpy .linalg import eig
3- from nnpdf_data .filter_utils .utils import sort_eigenvalues
3+ from nnpdf_data .filter_utils .utils import covmat_to_artunc
44
55
66def upper_triangular_to_symmetric (ut , dim ):
@@ -20,73 +20,3 @@ def compute_covmat(corrmat: np.ndarray, unc: np.ndarray, ndata: int) -> list:
2020 # multiply by stat err
2121 cov_mat = np .einsum ("i,ij,j->ij" , unc , corrmat , unc )
2222 return covmat_to_artunc (ndata , cov_mat .flatten ().tolist ())
23-
24-
25- def covmat_to_artunc (ndata , covmat_list , no_of_norm_mat = 0 ):
26- r"""Convert the covariance matrix to a matrix of
27- artificial uncertainties.
28-
29- NOTE: This function has been taken from validphys.newcommondata_utils.
30- If those utils get merged in the future, we can replace this.
31-
32- Parameters
33- ----------
34- ndata : integer
35- Number of data points
36- covmat_list : list
37- A one dimensional list which contains the elements of
38- the covariance matrix row by row. Since experimental
39- datasets provide these matrices in a list form, this
40- simplifies the implementation for the user.
41- no_of_norm_mat : int
42- Normalized covariance matrices may have an eigenvalue
43- of 0 due to the last data point not being linearly
44- independent. To allow for this, the user should input
45- the number of normalized matrices that are being treated
46- in an instance. For example, if a single covariance matrix
47- of a normalized distribution is being processed, the input
48- would be 1. If a covariance matrix contains pertains to
49- 3 normalized datasets (i.e. cross covmat for 3
50- distributions), the input would be 3. The default value is
51- 0 for when the covariance matrix pertains to an absolute
52- distribution.
53-
54- Returns
55- -------
56- artunc : list
57- A two dimensional matrix (given as a list of lists)
58- which contains artificial uncertainties to be added
59- to the commondata. i^th row (or list) contains the
60- artificial uncertainties of the i^th data point.
61-
62- """
63- epsilon = - 0.0000000001
64- neg_eval_count = 0
65- psd_check = True
66- covmat = np .zeros ((ndata , ndata ))
67- artunc = np .zeros ((ndata , ndata ))
68- for i in range (len (covmat_list )):
69- a = i // ndata
70- b = i % ndata
71- covmat [a ][b ] = covmat_list [i ]
72- eigval , eigvec = eig (covmat )
73- eigval , eigvec = sort_eigenvalues (eigval , eigvec )
74- for j in range (len (eigval )):
75- if eigval [j ] < epsilon :
76- psd_check = False
77- elif eigval [j ] > epsilon and eigval [j ] <= 0 :
78- neg_eval_count = neg_eval_count + 1
79- if neg_eval_count == (no_of_norm_mat + 1 ):
80- psd_check = False
81- elif eigval [j ] > 0 :
82- continue
83- if psd_check == False :
84- raise ValueError ("The covariance matrix is not positive-semidefinite" )
85- else :
86- for i in range (ndata ):
87- for j in range (ndata ):
88- if eigval [j ] < 0 :
89- continue
90- else :
91- artunc [i ][j ] = eigvec [i ][j ] * np .sqrt (eigval [j ])
92- return artunc .tolist ()
0 commit comments