-
Notifications
You must be signed in to change notification settings - Fork 231
Open
Description
Code
import Pkg
Pkg.activate(temp=true, io=devnull)
Pkg.add(name="Optim", version="1.6.0", io=devnull)
Pkg.status()
const AV = AbstractVector{T} where T
using DelimitedFiles, Optim
normal_pdf(x::Real, μ::Real, var::Real) =
exp(-(x-μ)^2 / (2var)) / sqrt(2π * var)
function D(θ::AV{<:Real}, b::Real, r::AV{<:Real})
@assert length(θ) % 3 == 0
N = length(r)
K = length(θ) ÷ 3
α, μ, σ = θ[1:K], θ[K+1:2K], θ[2K+1:end]
var = σ .^2
sum(
α[k] * (
sum(
α[h] * normal_pdf(μ[k], μ[h], 2b + var[k] + var[h])
for h ∈ 1:K
)
- 2*sum(
1/N * normal_pdf(μ[k], r[j], 2b + var[k])
for j ∈ eachindex(r)
)
)
for k ∈ 1:K
)
end
data = open("sample_data.csv", "r") do io
DelimitedFiles.readdlm(io, ',')
end
data = data[:, 1]
result = let
θ0 = Float64[1/3,1/3,1/3, 0,0,0, 1,1,1]
obj(θ::AV{<:Real}) = D(θ, 1.0, data)
con_c!(c, θ::AV{<:Real}) = (c[1] = sum(θ[1:(length(θ)÷3)]) - 1; c)
con_jac!(J, θ::AV{<:Real}) = (J[1, 1:(length(θ)÷3)] .= 1; J)
con_h!(H, θ, λ) = H
lx = Float64[0,0,0, -Inf,-Inf,-Inf, 0, 0, 0]
ux = Float64[1,1,1, Inf, Inf, Inf, Inf,Inf,Inf]
lc = [0.0]; uc = [0.0]
dfc = TwiceDifferentiableConstraints(
con_c!, con_jac!, con_h!,
lx, ux, lc, uc
)
optimize(
obj, dfc, θ0, IPNewton(),
Optim.Options(store_trace=true, show_trace=true, show_every=1, iterations=10),
autodiff=:forward
)
end
@show Optim.minimizer(result)- The objective function is
obj(θ::AV{<:Real}) = D(θ, 1.0, data) - One affine constraint:
θ[1] + θ[2] + θ[3] - 1 == 0 - Inequality constraints:
θ[1]>=0 && θ[2]>=0 && θ[3]>=0θ[1]<=1 && θ[2]<=1 && θ[3]<=1θ[7]>=0 && θ[8]>=0 && θ[9]>=0
- Starting point:
θ0 = Float64[1/3,1/3,1/3, 0,0,0, 1,1,1]
100 data points: sample_data.csv
I'm not particularly sure about the specification of the Hessian in con_h!(H, θ, λ) = H. AFAIK, this function should add the Hessian of the constraints to H. Since the constraints are linear, I should be adding zero, which is equivalent to doing nothing and simply returning the original Hessian, right?
Problem
If I run this code multiple times (with the same starting point and the same settings!), I randomly get NaNs everywhere:
~/t/Optim $ julia-1.7 report.jl (base)
Status `/private/var/folders/ys/3h0gnqns4b98zb66_vl_m35m0000gn/T/jl_uNRF2Q/Project.toml`
[429524aa] Optim v1.6.0
Iter Lagrangian value Function value Gradient norm |==constr.| μ
0 -1.966311e-01 -1.966871e-01 1.096659e-03 0.000000e+00 1.24e-05
* time: 1.642772858940843e9
1 -1.967483e-01 -1.967538e-01 5.965825e-04 4.191989e-21 1.24e-06
* time: 1.642772860832457e9
2 -1.967599e-01 -1.967656e-01 1.449232e-03 0.000000e+00 1.24e-06
* time: 1.642772860833223e9
3 -1.967671e-01 -1.967714e-01 8.505952e-05 3.350116e-23 9.33e-07
* time: 1.642772860833715e9
4 -1.967796e-01 -1.967802e-01 4.338795e-04 1.761310e-22 1.30e-07
* time: 1.642772860834255e9
5 -1.967911e-01 -1.967917e-01 4.314652e-04 1.548437e-22 1.25e-07
* time: 1.642772860834772e9
6 -1.967975e-01 -1.967984e-01 6.682571e-05 2.934913e-22 1.63e-07
* time: 1.642772860835274e9
7 -1.968029e-01 -1.968034e-01 1.454685e-04 6.996569e-23 9.13e-08
* time: 1.64277286083576e9
8 -1.968043e-01 -1.968048e-01 1.681820e-04 3.166961e-22 8.18e-08
* time: 1.642772860836246e9
9 -1.968060e-01 -1.968065e-01 4.130831e-04 2.883045e-22 7.89e-08
* time: 1.642772860836716e9
10 -1.968087e-01 -1.968091e-01 6.875015e-04 1.149389e-22 7.09e-08
* time: 1.642772860837178e9
Optim.minimizer(result) = [0.12046220033401919, 0.21628965837338163, 0.6632481412925991, 0.3006553011305413, 0.36322704596103234, -0.15810174712000133, 1.3014704098568006, 0.561227621176915, 1.0813300576532012]
~/t/Optim $ julia-1.7 report.jl (base)
Status `/private/var/folders/ys/3h0gnqns4b98zb66_vl_m35m0000gn/T/jl_JcPxe4/Project.toml`
[429524aa] Optim v1.6.0
Iter Lagrangian value Function value Gradient norm |==constr.| μ
0 NaN -1.966871e-01 NaN NaN 1.00e+00
* time: 1.642772890437607e9
1 NaN NaN NaN NaN 1.00e-01
* time: 1.642772892260335e9
2 NaN NaN NaN NaN NaN
* time: 1.64277289226151e9
3 NaN NaN NaN NaN NaN
* time: 1.642772892262521e9
4 NaN NaN NaN NaN NaN
* time: 1.642772892263575e9
5 NaN NaN NaN NaN NaN
* time: 1.642772892264575e9
6 NaN NaN NaN NaN NaN
* time: 1.642772892265608e9
7 NaN NaN NaN NaN NaN
* time: 1.642772892266602e9
8 NaN NaN NaN NaN NaN
* time: 1.642772892267635e9
9 NaN NaN NaN NaN NaN
* time: 1.642772892268625e9
10 NaN NaN NaN NaN NaN
* time: 1.642772892269617e9
Optim.minimizer(result) = [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
~/t/Optim $
Looks like NaN first appears in Lagrangian value, and then everything becomes NaN.
Is this expected behavior? Am I maybe specifying constraints incorrectly?
Metadata
Metadata
Assignees
Labels
No labels