diff --git a/mNSF/training_multiSample.py b/mNSF/training_multiSample.py index ebb267c..05c95a1 100644 --- a/mNSF/training_multiSample.py +++ b/mNSF/training_multiSample.py @@ -114,76 +114,153 @@ def truncate_history(loss_history, epoch): # Class to check convergence of the model class ConvergenceChecker(object): - def __init__(self,span,dtp="float64"): - """ - Initialize the ConvergenceChecker with polynomial basis functions. + def __init__(self, span, dtp="float64"): + """ + Initialize the ConvergenceChecker with polynomial basis functions. - Args: - span: Number of recent observations to consider - dtp: Data type for computations - """ - x = np.arange(span,dtype=dtp) - x-= x.mean() - X = np.column_stack((np.ones(shape=x.shape),x,x**2,x**3)) - self.U = np.linalg.svd(X,full_matrices=False)[0] - - def smooth(self,y): - """Apply smoothing to the input vector.""" - return self.U@(self.U.T@y) - - def subset(self,y,idx=-1): - """Extract a subset of the input vector.""" - span = self.U.shape[0] - lo = idx-span+1 - if idx==-1: - return y[lo:] - else: - return y[lo:(idx+1)] - - def relative_change(self,y,idx=-1,smooth=True): - """Calculate the relative change in the input vector.""" - y = self.subset(y,idx=idx) - if smooth: - y = self.smooth(y) - prev=y[-2] - return (y[-1]-prev)/(0.1+abs(prev)) - - - - - def converged(self,y,tol=1e-4,**kwargs): - """Check if the relative change is below the tolerance.""" - return abs(self.relative_change(y,**kwargs)) < tol - - - def relative_chg_normalized(self, y, idx_current = -1, len_trace=50, smooth=True): - cc = self.relative_change_trace( y, idx_current = idx_current, len_trace=len_trace, smooth=smooth) - print(cc) - mean_cc = np.nanmean(cc) - sd_cc = np.std(cc) - return mean_cc/sd_cc - - - - def relative_change_trace(self, y, idx_current = -1, len_trace=50, smooth=True): - #n = len(y) - #span = self.U.shape[0] - #span = self.U.shape[0] - cc=self.relative_change_all(y,smooth=smooth) - return cc[(idx_current-len_trace):idx_current] - - - def relative_change_all(self,y,smooth=True): - n = len(y) - span = self.U.shape[0] - cc = np.tile([np.nan],n) - for i in range(span,n): - cc[i] = self.relative_change(y,idx=i,smooth=smooth) - return cc - - def converged_all(self,y,tol=1e-4,smooth=True): - cc = self.relative_change_all(y,smooth=smooth) - return np.abs(cc)