Skip to content

Commit 3295599

Browse files
committed
replace the regularization computation
1 parent 742b306 commit 3295599

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

hera_filters/dspec.py

+20-14
Original file line numberDiff line numberDiff line change
@@ -2900,7 +2900,7 @@ def sparse_linear_fit_2D(
29002900
btol: float = 1e-10,
29012901
iter_lim: int = None,
29022902
precondition_solver: bool = False,
2903-
eig_scaling_factor: float = 1e-2,
2903+
eigenspec_threshold: float = 1e-3,
29042904
**kwargs
29052905
) -> np.ndarray:
29062906
"""
@@ -2936,15 +2936,15 @@ def sparse_linear_fit_2D(
29362936
the basis matrices are ill-conditioned due to large stretches of zeros.
29372937
The preconditioner is computed using the the inverse of the regularized Gramian
29382938
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.
29482948
**kwargs : dict
29492949
Additional keyword arguments passed to `scipy.sparse.linalg.lsqr`.
29502950
@@ -2998,16 +2998,22 @@ def sparse_linear_fit_2D(
29982998

29992999
# Compute the preconditioner for the first axis
30003000
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+
]
30033006
axis_1_pcond = np.linalg.pinv(
30043007
XTX_axis_1 + np.eye(XTX_axis_1.shape[0]) * axis_1_lambda
30053008
)
30063009

30073010
# Compute the preconditioner for the second axis
30083011
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+
]
30113017
axis_2_pcond = np.linalg.pinv(
30123018
XTX_axis_2 + np.eye(XTX_axis_2.shape[0]) * axis_2_lambda
30133019
)

0 commit comments

Comments
 (0)