Add underdetermined Levenberg-Marquardt support (minimum-norm mode)#859
Add underdetermined Levenberg-Marquardt support (minimum-norm mode)#859ChrisRackauckas-Claude wants to merge 1 commit into
Conversation
This implements support for underdetermined nonlinear least-squares problems (n > m, more unknowns than equations) in the Levenberg-Marquardt algorithm. ## Changes ### DampedNewtonDescent - Added new mode for underdetermined systems - New kwarg: (default), , - Auto-detects underdetermined systems when ### Algorithm (minimum_norm mode) Instead of the normal form (JᵀJ + λD)δ = -Jᵀf, we solve: 1. (JJᵀ + λI) z = -f(x) [m×m system, smaller when n > m] 2. δ = Jᵀz [minimum-norm step] This finds the minimum-norm step that solves the linearized equations, keeping the linear system small (m×m instead of n×n). ### Implementation Details - Added `dampen_jacobian_minimum_norm!!` for scalar damping extraction - Added caches: `JJᵀ_cache`, `z_cache`, `J_raw` for minimum_norm mode - Extracts mean of diagonal damping matrix as scalar λ ### Tests Added comprehensive tests for: - Linear underdetermined systems - Nonlinear underdetermined systems - In-place formulation - Overdetermined regression tests - Large underdetermined systems (efficiency test) Closes SciML#851 Reference: Chen et al. (2026), appendix B - Optica Express 34(4):5729
|
Thanks Chris, I didn't realize that you had worked on this. cc @aristeidis-karalis and @mochen4 |
|
Thanks! This looks great! |
|
A simple test case would be to put in a linear function |
|
@ChrisRackauckas-Claude, it's awesome you implemented this! Just a comment: The same holds for the minimum-norm solution, it's often preferable if it is independent from the scale of |
| # Helper to extract scalar damping from various damping representations | ||
| _extract_scalar_damping(D::Number) = D | ||
| function _extract_scalar_damping(D::Diagonal) | ||
| # Use the mean of diagonal elements as scalar λ | ||
| # This works well for L-M where DᵀD is typically uniform or slowly varying | ||
| return sum(D.diag) / length(D.diag) | ||
| end | ||
| function _extract_scalar_damping(D::AbstractMatrix) | ||
| # Extract diagonal and take mean | ||
| n = minimum(size(D)) | ||
| s = zero(eltype(D)) | ||
| for i in 1:n | ||
| s += D[i, i] | ||
| end | ||
| return s / n | ||
| end |
There was a problem hiding this comment.
Couldn't all three of these methods be replaced by
_extract_scalar_damping(D) = tr(D) / size(D,1)assuming D is always a square matrix as seems to be the case?
PR: Add underdetermined Levenberg-Marquardt support (minimum-norm mode)
Summary
This PR implements support for underdetermined nonlinear least-squares problems (n > m, more unknowns than equations) in the Levenberg-Marquardt algorithm, addressing issue #851.
Background
The current L-M implementation in
DampedNewtonDescentassumes overdetermined systems (m ≥ n) and formsJᵀJ + λD. For underdetermined systems (n > m), this is inefficient because:JᵀJis n×n (large)Algorithm
For underdetermined systems, instead of solving
(JᵀJ + λD)δ = -Jᵀf, we solve:(JJᵀ + λI) z = -f(x)— This is an m×m system (smaller when n > m)δ = Jᵀz— This gives the minimum-norm stepThis approach:
Changes
lib/NonlinearSolveBase/src/descent/damped_newton.jl:minimum_normtoDampedNewtonDescentCachemin_norm_modeinDampedNewtonDescent::auto(default): Auto-detect and use minimum-norm for underdetermined systems:minimum_norm: Force minimum-norm mode:disabled: Never use minimum-norm modelength(fu) < length(u)to detect underdetermined systemsJJᵀ_cache,z_cache,J_rawfor minimum_norm computationsdampen_jacobian_minimum_norm!!and_extract_scalar_dampinglib/NonlinearSolveFirstOrder/test/underdetermined_tests.jlNew test file with comprehensive tests:
Usage
References
Checklist
damped_newton.jl