Precision loss in Hessian computation
Mantenedores costumam responder em até 1 dia
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 15/100
- Tipo de issue
- Bug
- Clareza
- Precisa de esclarecimento
- Status de atividade
- Ativa
- Domínio
- backend
Direção de pesquisa
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.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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.
- Linguagem predominante
- Julia
- Estrelas
- 506
- Forks
- 103
- Merge médio
- 1d 10min
- PRs com merge (30d)
- 12
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de jump-dev/MathOptInterface.jl
-
[Bridges] MultirowChange in set_map.jl drops zero coefficientsTalvez já em andamento @odow assumiu há 6 dias. Aberta
jump-dev/MathOptInterface.jl#3106 · 2 comentários · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
Layer instantiatorAberta
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 35/100
jump-dev/MathOptInterface.jl#2986 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 25/100
jump-dev/MathOptInterface.jl#2969 · 2 comentários · 1 reação ·
Mantenedores costumam responder em até 1 dia
-
Add Batched{S} setAbertaType: Set Request
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 35/100
jump-dev/MathOptInterface.jl#2904 · 15 comentários · 7 reações ·
Mantenedores costumam responder em até 1 dia
-
Performance problem with deeply nested nonlinear expressionsTalvez já em andamento @blegat assumiu há 457 dias. Aberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 45/100
jump-dev/MathOptInterface.jl#3065 · 11 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de jump-dev/MathOptInterface.jl
Issues semelhantes
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
OpenSourceAWE/SymbolicAWEModels.jl#431 ·
Mantenedores costumam responder em até 1 dia
-
Make PDAQP an optional extraAberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
EnzymeAD/Reactant.jl#3549 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 77/100
SciML/OrdinaryDiffEq.jl#4903 ·
Mantenedores costumam responder em até 4 dias