@@ -2900,7 +2900,7 @@ def sparse_linear_fit_2D(
2900
2900
btol : float = 1e-10 ,
2901
2901
iter_lim : int = None ,
2902
2902
precondition_solver : bool = False ,
2903
- eig_scaling_factor : float = 1e-2 ,
2903
+ eigenspec_threshold : float = 1e-3 ,
2904
2904
** kwargs
2905
2905
) -> np .ndarray :
2906
2906
"""
@@ -2936,15 +2936,15 @@ def sparse_linear_fit_2D(
2936
2936
the basis matrices are ill-conditioned due to large stretches of zeros.
2937
2937
The preconditioner is computed using the the inverse of the regularized Gramian
2938
2938
matrix (X^T W X) of the basis matrices. Prior to computing the inverse, the eigenvalues
2939
- of the Gramian matrix are regularized by adding a small value proportional to the largest
2940
- eigenvalue. This helps to stabilize the computation of the inverse. The regularization
2941
- factor is computed as the minimum eigenvalue of the Gramian matrix multiplied by the
2942
- `eig_scaling_factor` parameter .
2943
- eig_scaling_factor : float, optional, default 1e-1
2944
- Regularization factor for the eigenvalues of the Gramian matrix. The factor
2945
- is computed as the minimum eigenvalue of the Gramian matrix multiplied by
2946
- `eig_scaling_factor`. Reasonable values are typically in the range of 1e-1
2947
- to 1e-3 .
2939
+ of the Gramian matrix are regularized by adding a small value to the diagonal. This
2940
+ value is calculated by computing the cumulative sum of the eigenvalues and selecting
2941
+ the smallest value such that the cumulative sum of the largest eigenvalues is less than
2942
+ 1 - `eigenspec_threshold`. This helps to stabilize the computation of the inverse .
2943
+ eigenspec_threshold : float, optional, default 1e-3
2944
+ Regularization parameters for the eigenvalues of the Gramian matrix. This parameter
2945
+ is used to compute the smallest value to add to the diagonal of the Gramian matrix
2946
+ such that the cumulative sum of the largest eigenvalues is less than 1 - `eigenspec_threshold`.
2947
+ This effectively sets the threshold for the smallest eigenvalue to include in the inverse .
2948
2948
**kwargs : dict
2949
2949
Additional keyword arguments passed to `scipy.sparse.linalg.lsqr`.
2950
2950
@@ -2998,16 +2998,22 @@ def sparse_linear_fit_2D(
2998
2998
2999
2999
# Compute the preconditioner for the first axis
3000
3000
XTX_axis_1 = np .dot (axis_1_basis .T .conj () * axis_1_wgts , axis_1_basis )
3001
- eigenval = sparse .linalg .eigs (XTX_axis_1 , k = 1 , which = 'LM' , return_eigenvectors = False )
3002
- axis_1_lambda = np .abs (eigenval ) * eig_scaling_factor
3001
+ eigenvals , _ = np .linalg .eigh (XTX_axis_1 )
3002
+ eigenvals = eigenvals [np .argsort (eigenvals )[::- 1 ]]
3003
+ axis_1_lambda = eigenvals [
3004
+ np .max (np .where (np .cumsum (eigenvals ) / np .sum (eigenvals ) < (1 - eigenspec_threshold )))
3005
+ ]
3003
3006
axis_1_pcond = np .linalg .pinv (
3004
3007
XTX_axis_1 + np .eye (XTX_axis_1 .shape [0 ]) * axis_1_lambda
3005
3008
)
3006
3009
3007
3010
# Compute the preconditioner for the second axis
3008
3011
XTX_axis_2 = np .dot (axis_2_basis .T .conj () * axis_2_wgts , axis_2_basis )
3009
- eigenval = sparse .linalg .eigs (XTX_axis_2 , k = 1 , which = 'LM' , return_eigenvectors = False )
3010
- axis_2_lambda = np .abs (eigenval ) * eig_scaling_factor
3012
+ eigenvals , _ = np .linalg .eigh (XTX_axis_2 )
3013
+ eigenvals = eigenvals [np .argsort (eigenvals )[::- 1 ]]
3014
+ axis_2_lambda = eigenvals [
3015
+ np .max (np .where (np .cumsum (eigenvals ) / np .sum (eigenvals ) < (1 - eigenspec_threshold )))
3016
+ ]
3011
3017
axis_2_pcond = np .linalg .pinv (
3012
3018
XTX_axis_2 + np .eye (XTX_axis_2 .shape [0 ]) * axis_2_lambda
3013
3019
)
0 commit comments