@@ -319,29 +319,62 @@ def _hashed_dataset_inputs_fitting_covmat(loaded_fit_covmat) -> Hashrray:
319319
320320
321321@functools .lru_cache
322- def _inv_covmat_prepared (_hashed_dataset_inputs_fitting_covmat ):
322+ def _inv_covmat_prepared (_hashed_dataset_inputs_fitting_covmat , output_path , diagonal_basis = True ):
323323 """Returns the inverse covmats for training, validation and total when diagonal_basis = False"""
324324 log .info (
325325 f"_inv_covmat_prepared called with covmat hash={ hash (_hashed_dataset_inputs_fitting_covmat )} "
326326 )
327327 covmat = _hashed_dataset_inputs_fitting_covmat .array
328+ diag_rot = None
329+ eig_vals = None
328330
329- diag_inv_sqrt_total = 1 / np .sqrt (np .diag (covmat ))
330- cormat_total = np .einsum ("i, ij, j -> ij" , diag_inv_sqrt_total , covmat , diag_inv_sqrt_total )
331- inv_total = (
332- np .diag (diag_inv_sqrt_total ) @ np .linalg .inv (cormat_total ) @ np .diag (diag_inv_sqrt_total )
333- )
331+ if diagonal_basis :
332+ diagonal_basis_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
333+ path_diagonal_basis = output_path / "tables" / diagonal_basis_saved
334+ eigensystem = pd .read_csv (
335+ path_diagonal_basis , index_col = [0 ], header = [0 ], sep = "\t |," , engine = "python"
336+ )
337+ diag_rot = eigensystem .iloc [:, 1 :].values
338+ eig_vals = eigensystem ["eig_val" ].values
339+ inv_total = np .diag (1 / eig_vals )
340+
341+ else :
342+ diag_inv_sqrt_total = 1 / np .sqrt (np .diag (covmat ))
343+ cormat_total = np .einsum ("i, ij, j -> ij" , diag_inv_sqrt_total , covmat , diag_inv_sqrt_total )
344+ inv_total = (
345+ np .diag (diag_inv_sqrt_total )
346+ @ np .linalg .inv (cormat_total )
347+ @ np .diag (diag_inv_sqrt_total )
348+ )
334349
335- return inv_total
350+ return covmat , inv_total , diag_rot , eig_vals
336351
337352
338- def _covmat_prepared (dataset_inputs_fitting_covmat , nnfit_theory_covmat , diagonal_basis = True ):
339- """Returns the covmats for training, validation and total
340- attending to the right masks and whether it is diagonal or not.
341- s
342- Since the masks and number of datapoints need to be treated for 1-point datasets
343- it also returns the right ndata and masks for training and validation:
353+ def _fiting_covmat (dataset_inputs_fitting_covmat , nnfit_theory_covmat , diagonal_basis = True ):
354+ """Prepare the fitting covariance matrix by optionally adding theory contributions
355+ and transforming to diagonal basis.
344356
357+ Parameters
358+ ----------
359+ dataset_inputs_fitting_covmat : np.ndarray
360+ The experimental covariance matrix from the datasets.
361+ nnfit_theory_covmat : np.ndarray or None
362+ The theory covariance matrix to add to the experimental covmat.
363+ If None, only the experimental covmat is used.
364+ diagonal_basis : bool, optional
365+ If True, transform the covariance matrix to diagonal basis by extracting
366+ eigenvalues and eigenvectors of the correlation matrix. Default is True.
367+
368+ Returns
369+ -------
370+ covmat : np.ndarray
371+ The prepared covariance matrix (sum of experimental and theory covmats).
372+ diagonal_rotation : np.ndarray or None
373+ The rotation matrix (transposed eigenvectors) to transform data to diagonal basis.
374+ Only returned if diagonal_basis=True, otherwise None.
375+ eig_vals : np.ndarray or None
376+ The eigenvalues of the correlation matrix in diagonal basis.
377+ Only returned if diagonal_basis=True, otherwise None.
345378 """
346379
347380 # TODO: JtH, note to self: inv_covmat_prepared can no longer be called during n3fit because nnfit_theory_covmat is in a different namespace
@@ -365,10 +398,6 @@ def _covmat_prepared(dataset_inputs_fitting_covmat, nnfit_theory_covmat, diagona
365398 uT = np .einsum ("i, ik -> ik" , diag_inv_sqrt , uT )
366399 diagonal_rotation = uT .T
367400
368- ndata = len (eig_vals )
369-
370- inv_total = np .diag (1 / eig_vals )
371-
372401 return covmat , diagonal_rotation , eig_vals
373402
374403
@@ -432,26 +461,7 @@ def fitting_data_dict(
432461 fittable_datasets = fittable_datasets_masked
433462
434463 # load covmat stored at the time of vp-setupfit
435- if diagonal_basis :
436- diagonal_basis_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
437- path_diagonal_basis = output_path / "tables" / diagonal_basis_saved
438- eigensystem = pd .read_csv (
439- path_diagonal_basis , index_col = [0 ], header = [0 ], sep = "\t |," , engine = "python"
440- )
441- diag_rot = eigensystem .iloc [:, 1 :].values
442- eig_vals = eigensystem ["eig_val" ].values
443- inv_true = np .diag (1 / eig_vals )
444- covmat = np .diag (eig_vals )
445- else :
446- covmat_saved = "datacuts_theory_theorycovmatconfig_fitting_covmat_table.csv"
447- path_covmat = output_path / "tables" / covmat_saved
448- # TODO: check if it is save to convert to numpy already at this stage, is the indexing consistent?
449- covmat = pd .read_csv (
450- path_covmat , index_col = [0 , 1 , 2 ], header = [0 , 1 , 2 ], sep = "\t |," , engine = "python"
451- ).values
452- diag_rot = None
453- eig_vals = None
454- inv_true = _inv_covmat_prepared
464+ covmat , inv_true , diag_rot , eig_vals = _inv_covmat_prepared
455465
456466 # get the masks - different for each replica so fine to call here
457467 tr_mask , vl_mask = masks .tr_masks [0 ], masks .vl_masks [0 ]
@@ -579,12 +589,12 @@ def fitting_data_dict(
579589
580590
581591@table
582- def fitting_covmat_table (output_path , _covmat_prepared , diagonal_basis = True ):
592+ def fitting_covmat_table (output_path , _fiting_covmat , diagonal_basis = True ):
583593 """
584594 Stores the fitting covariance matrix if diagonal_basis is False, else store the rotation matrix and eigenvalues
585595 """
586596 # TODO: JtH, check if this includes the theory covmat
587- covmat , diagonal_rotation , eig_vals = _covmat_prepared
597+ covmat , diagonal_rotation , eig_vals = _fiting_covmat
588598
589599 if not diagonal_basis :
590600 log .info ("Saving fitting covmat" )
0 commit comments