@@ -73,6 +73,7 @@ def __init__(
7373 self .errors_final = None
7474 self .adj_matrix = None
7575 self .community_dictionary = None
76+ self .cov = None
7677
7778 def _check_and_initialize_args (self , periods ):
7879 """Checks input arguments to constructor of CausalGraph object."""
@@ -222,6 +223,9 @@ def optimize_present_to_future(
222223 compute_error = False ,
223224 ratio_rows_columns = 1 ,
224225 discard_close_ind = None ,
226+ langevin_steps = 0 ,
227+ early_stopping = 0 ,
228+ return_covariance = False
225229 ):
226230 """Iteratively optimizes the DII from the full space in the present to a target space in the future.
227231
@@ -292,6 +296,9 @@ def optimize_present_to_future(
292296 with stride discard_close_ind + 1. If compute_error is False, distances between each point i and points
293297 within the time window [i-discard_close_ind, i+discard_close_ind] are discarded. Default is 0, for which
294298 no distances between points close in the time are discarded.
299+ langevin_steps (int): number of Langevin steps to perform after minimization.
300+ early_stopping (float): the threshold for the early stopping criterion. Default is 0, which means that no early stopping is performed.
301+ return_covariance (bool): whether to return the covariance matrix of the weights, obtained after Langevin dynamics
295302
296303 Returns:
297304 weights_final (np.array(float)): array of shape (n_target_variables, n_time_lags, D) containing the
@@ -361,9 +368,18 @@ def optimize_present_to_future(
361368 target_variables = np .arange (self .num_variables )
362369
363370 # initialize output variables
364- imbs_training = np .zeros (
371+ imbs_temp = np .zeros (
365372 (len (target_variables ), len (time_lags ), num_epochs + 1 )
366373 )
374+ imbs_training = np .zeros (
375+ (len (target_variables ), len (time_lags ), num_epochs + langevin_steps + 1 )
376+ )
377+ if return_covariance :
378+ covariance_matrix = np .zeros (
379+ (len (target_variables ), len (time_lags ), self .num_variables * embedding_dim_present , self .num_variables * embedding_dim_present )
380+ )
381+
382+
367383 if embedding_dim_present == 1 :
368384 weights_final = np .zeros (
369385 (len (target_variables ), len (time_lags ), self .num_variables )
@@ -373,7 +389,7 @@ def optimize_present_to_future(
373389 (
374390 len (target_variables ),
375391 len (time_lags ),
376- num_epochs + 1 ,
392+ num_epochs + langevin_steps + 1 ,
377393 self .num_variables ,
378394 )
379395 )
@@ -391,7 +407,7 @@ def optimize_present_to_future(
391407 (
392408 len (target_variables ),
393409 len (time_lags ),
394- num_epochs + 1 ,
410+ num_epochs + langevin_steps + 1 ,
395411 self .num_variables ,
396412 embedding_dim_present ,
397413 )
@@ -443,8 +459,9 @@ def optimize_present_to_future(
443459 learning_rate = learning_rate ,
444460 learning_rate_decay = learning_rate_decay ,
445461 num_points_rows = num_points_rows ,
462+ early_stopping = early_stopping
446463 )
447- weights_temp , imbs_training [i_var , j_tau ] = dii .train (
464+ weights_temp , imbs_temp [i_var , j_tau ] = dii .train (
448465 bar_label = f"target_var={ target_var } , tau={ tau } "
449466 )
450467
@@ -460,20 +477,27 @@ def optimize_present_to_future(
460477 if compute_error :
461478 errors_final [i_var , j_tau ] = dii .error_final
462479
480+ if langevin_steps != 0 :
481+ weights_langevin , imbs_langevin = dii .langevin (weights_temp [- 1 ], n_epochs = langevin_steps , batch_size = int (len (coords_present )/ batches_per_epoch ), noise = np .mean (weights_temp [- 1 ])* 1e-1 )
482+ weights_temp = np .concatenate ([weights_temp , weights_langevin [1 :]], axis = 0 )
483+ imbs_training [i_var , j_tau ] = np .concatenate ([imbs_temp [i_var , j_tau ], imbs_langevin [1 :]])
484+ if return_covariance :
485+ covariance_matrix [i_var , j_tau ] = np .cov (weights_langevin [::10 ] ,rowvar = False )/ len (weights_langevin [::10 ])
486+
463487 # save weights
464488 if embedding_dim_present == 1 :
465- weights_final [i_var , j_tau ] = weights_temp [- 1 ]
489+ weights_final [i_var , j_tau ] = np . abs ( np . mean ( weights_temp [- langevin_steps - 1 :], axis = 0 ))
466490 if save_weights is True :
467491 weights_training [i_var , j_tau ] = weights_temp .reshape (
468- (num_epochs + 1 , self .num_variables )
492+ (num_epochs + 1 + langevin_steps , self .num_variables )
469493 )
470494 elif embedding_dim_present > 1 :
471- weights_final [i_var , j_tau ] = weights_temp [- 1 ] .reshape (
495+ weights_final [i_var , j_tau ] = np . abs ( np . mean ( weights_temp [- langevin_steps - 1 :], axis = 0 )) .reshape (
472496 (self .num_variables , embedding_dim_present )
473497 )
474498 if save_weights is True :
475499 weights_training [i_var , j_tau ] = weights_temp .reshape (
476- (num_epochs + 1 , self .num_variables , embedding_dim_present )
500+ (num_epochs + 1 + langevin_steps + langevin_steps , self .num_variables , embedding_dim_present )
477501 )
478502
479503 self .weights_final = weights_final
@@ -482,6 +506,10 @@ def optimize_present_to_future(
482506 self .weights_training = weights_training
483507 self .imbs_final = imbs_final
484508 self .errors_final = errors_final
509+
510+ if return_covariance == True :
511+ self .cov = covariance_matrix
512+ return weights_final , imbs_training , imbs_final , errors_final , covariance_matrix
485513 return weights_final , imbs_training , imbs_final , errors_final
486514
487515 def compute_adj_matrix (self , weights , threshold = 1e-1 ):
@@ -827,4 +855,4 @@ def community_graph_visualization(
827855 plt .show ()
828856
829857 # return networkx object
830- return G
858+ return G
0 commit comments