Precision loss in Hessian computation
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 15/100
- Issue-Typ
- Bug
- Klarheit
- Muss geklärt werden
- Aktivitätsstatus
- Aktiv
- Bereich
- backend
Rechercherichtung
Start by running the included MWE, which compares the sparse Hessian from MOI.eval_hessian_lagrangian on MOI.Nonlinear.SparseReverseMode() with ForwardDiff.hessian, and check the entry H[4, 3] (about 1.2e-11 versus 1.2e-11 with a larger absolute error). The cause is the coloring-based Hessian recovery, not the derivative formulas. The maintainers have not chosen a fix among the three options (document, Double64 intermediates, or SparseMatrixColorings star coloring), so decide on the approach with them before writing code.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
I'm not sure this is actionable, but it also seems worth doing something about: maybe just documentation, but there are a couple of other options I'll detail below.
This came up while analyzing (with Claude's help) a standard benchmark problem, the CUTEst problem nondquar at n = 5:
(x1 - x2)^2 + (x4 - x5)^2 + Σ_{i=1}^{3} (x_i + x_{i+1} + x_5)^4
Here's the MWE to demonstrate the precision loss:
import MathOptInterface as MOI
import ForwardDiff
# MOI implementation
n = 5
x = [1.0, -1.0, 1.0, -1.0, 1e-6]
v = MOI.VariableIndex.(1:n)
obj = Expr(:call, :+, :(($(v[1]) - $(v[2]))^2), :(($(v[n-1]) - $(v[n]))^2),
(:(($(v[i]) + $(v[i+1]) + $(v[n]))^4) for i in 1:n-2)...)
model = MOI.Nonlinear.Model()
MOI.Nonlinear.set_objective(model, obj)
ev = MOI.Nonlinear.Evaluator(model, MOI.Nonlinear.SparseReverseMode(), v)
MOI.initialize(ev, [:Hess, :HessVec])
st = MOI.hessian_lagrangian_structure(ev)
vals = zeros(length(st))
MOI.eval_hessian_lagrangian(ev, vals, x, 1.0, Float64[])
H = zeros(n, n)
for ((i, j), w) in zip(st, vals)
H[i, j] += w
i == j || (H[j, i] += w)
end
# ForwardDiff implementation
f(z) = (z[1] - z[2])^2 + (z[n-1] - z[n])^2 + sum((z[i] + z[i+1] + z[n])^4 for i in 1:n-2)
Hf = ForwardDiff.hessian(f, x)
Now compare the two Hessians:
julia> H - Hf
5×5 Matrix{Float64}:
0.0 0.0 0.0 0.0 0.0
0.0 4.44089e-16 -4.3416e-17 0.0 0.0
0.0 -4.3416e-17 0.0 4.3416e-17 0.0
0.0 0.0 4.3416e-17 0.0 0.0
0.0 0.0 0.0 0.0 4.44089e-16
You might think everything is fine: errors are ~eps. But they are against a baseline of 1e-11:
julia> H[4, 3]
1.2000043416036534e-11
julia> Hf[4, 3]
1.2e-11
And that's a very large error indeed. At x = [1, -1, 1, -1, 1e-6] every inner sum equals 1e-6 exactly in floating point, so the cross partial ∂²f/∂x3∂x4 = 12·(1e-6)² = 1.2e-11; ForwardDiff's answer is the correct one.
It seems pretty clear this comes from the coloring, and because your coloring is both good and important the paths to fix this are narrow. I currently see three possible options:
- don't fix, just document
- support
Double64, if the user requests it, for intermediate storage - support SparseMatrixColorings (xref #3806), which would allow one to use star coloring
Any thoughts on what you prefer? The documentation or Double64 might be something I could try; I'd probably defer to others for SparseMatrixColorings if they'd be willing to pitch in.
- Vorherrschende Sprache
- Julia
- Sterne
- 506
- Forks
- 103
- Ø Merge
- 1 T. 10 Min.
- Gemergte PRs (30 T.)
- 12
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus jump-dev/MathOptInterface.jl
-
[Bridges] MultirowChange in set_map.jl drops zero coefficientsEvtl. vergeben @odow hat das vor 4 Tagen übernommen. Offen
jump-dev/MathOptInterface.jl#3106 · 2 Kommentare · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
Layer instantiatorOffen
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
jump-dev/MathOptInterface.jl#2986 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 25/100
jump-dev/MathOptInterface.jl#2969 · 2 Kommentare · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
-
Add Batched{S} setOffenType: Set Request
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 35/100
jump-dev/MathOptInterface.jl#2904 · 15 Kommentare · 7 Reaktionen ·
Maintainer antworten meist innerhalb von 1 Tag
-
Performance problem with deeply nested nonlinear expressionsEvtl. vergeben @blegat hat das vor 456 Tagen übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 45/100
jump-dev/MathOptInterface.jl#3065 · 11 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in jump-dev/MathOptInterface.jl
Ähnliche Issues
-
View of a view is brokenEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 85/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 67/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
JuliaPy/pyjuliapkg#102 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
JuliaMath/Polynomials.jl#641 ·