@@ -181,7 +181,7 @@ def residuals(p, x, y):
181181 raise ValueError (f"Unknown cov_mode={ cov_mode !r} ." )
182182
183183 if return_metrics :
184- out_parts .append (np .array ([np .nan , np .nan ], dtype = np .float64 ))
184+ out_parts .append (np .array ([np .nan , np .nan , np . nan , np . nan ], dtype = np .float64 ))
185185
186186 return np .hstack (out_parts ) if len (out_parts ) > 1 else params
187187
@@ -199,6 +199,8 @@ def residuals(p, x, y):
199199
200200 # --- Metrics (default) appending ---
201201 if return_metrics :
202+ n = int (y_input .size )
203+ k = int (params .size )
202204 sse = float (np .sum (res .fun ** 2 ))
203205 rmse = float (np .sqrt (sse / y_input .size )) if y_input .size > 0 else np .nan
204206 y_mean = float (np .mean (y_input ))
@@ -208,7 +210,17 @@ def residuals(p, x, y):
208210 else :
209211 r2 = 1.0 - (sse / sst )
210212
211- out_parts .append (np .array ([r2 , rmse ], dtype = np .float64 ))
213+ # AIC/BIC (up to an additive constant)
214+ if n > 0 and sse > 0.0 :
215+ ll_term = n * np .log (sse / n )
216+ aic = float (ll_term + 2.0 * k )
217+ bic = float (ll_term + k * np .log (n ))
218+ else :
219+ aic = np .nan
220+ bic = np .nan
221+
222+ # Order: [r2, rmse, aic, bic]
223+ out_parts .append (np .array ([r2 , rmse , aic , bic ], dtype = np .float64 ))
212224
213225 # --- Covariance (optional) appending ---
214226 if cov_mode is not None :
@@ -504,7 +516,7 @@ def do_fit(self, guesses=None, use_kmeans=False, n_clusters=10,
504516 else :
505517 raise ValueError (f"Unknown cov_mode={ cov_mode !r} . Use None, 'full', 'diag', or 'stderr'." )
506518
507- metrics_size = 2 if return_metrics else 0
519+ metrics_size = 4 if return_metrics else 0
508520 out_dim = self .num_params + cov_size + metrics_size
509521
510522
@@ -627,19 +639,21 @@ def set_spatial_dims(dset):
627639
628640 # --- 2) Metrics dataset ---
629641 if return_metrics :
630- metrics_payload = fit_dask_array [..., cursor :cursor + 2 ]
642+ metrics_payload = fit_dask_array [..., cursor :cursor + 4 ]
643+ cursor += 4
631644
632645 sid_metrics = sid .Dataset .from_array (metrics_payload , title = f"{ self .dataset .title } _fit_metrics" )
633646 set_spatial_dims (sid_metrics )
634647 sid_metrics .set_dimension (
635648 len (self .spat_dims ),
636- sid .Dimension (np .arange (2 ), name = 'metrics' , quantity = 'index' , dimension_type = 'spectral' )
649+ sid .Dimension (np .arange (4 ), name = 'metrics' , quantity = 'index' , dimension_type = 'spectral' )
637650 )
638651 sid_metrics .metadata = dict (self .metadata ).copy ()
639- sid_metrics .metadata .setdefault ("fit_parameters" , {}).update ({"metrics" : ["r2" , "rmse" ]})
652+ sid_metrics .metadata .setdefault ("fit_parameters" , {}).update ({"metrics" : ["r2" , "rmse" , "aic" , "bic" ]})
640653 sid_metrics .provenance = {'sidpy' : {'generated_from' : self .dataset .title , 'parent_fit' : sid_params .title }}
641654 out .append (sid_metrics )
642655
656+
643657 # --- 3) Covariance dataset (optional) ---
644658 if cov_size > 0 :
645659 cov_payload = fit_dask_array [..., cursor :cursor + cov_size ]
0 commit comments