1

我正在用 Julia 中的 JuMP 解决非线性优化问题,我的目标函数中有一个 erf() 调用。我的代码抛出一个错误,指出未定义 erf() 函数。

我调用了 Pkg.update(),加载了 SpecialFunction 包并在不同的求解器(NLopt、Itopt)之间切换,但它们都没有工作。

下面是我在 Julia 1.0.3 下测试的环境和最小化代码

julia> versioninfo()
Julia Version 1.0.3
Commit 099e826241 (2018-12-18 01:34 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, nehalem)
Environment:
  JULIA_EDITOR = "C:\Users\binha\AppData\Local\atom\app-1.34.0\atom.exe" -a
  JULIA_NUM_THREADS = 4

julia> Pkg.installed()
Dict{String,Union{Nothing, VersionNumber}} with 25 entries:
"Statistics"          => nothing
"GR"                  => v"0.37.0"
"Distributions"       => v"0.16.4"
"Random"              => nothing
"Atom"                => v"0.7.14"
"UUIDs"               => nothing
"FastGaussQuadrature" => v"0.3.2"
"JuMP"                => v"0.18.5"
"Juno"                => v"0.5.4"
"LinearAlgebra"       => nothing
"Ipopt"               => v"0.5.1"
"NLopt"               => v"0.5.1"
"PyCall"              => v"1.18.5"
"LaTeXStrings"        => v"1.0.3"
"SymPy"               => v"0.8.3"
"StatsBase"           => v"0.27.0"
"Plots"               => v"0.22.5"
"PyPlot"              => v"2.7.0"
"ProgressMeter"       => v"0.9.0"
"QuadGK"              => v"2.0.3"
"NLsolve"             => v"3.0.1"
"SpecialFunctions"    => v"0.7.2"
"ECOS"                => v"0.9.4"
"PoissonRandom"       => v"0.4.0"
"PlotlyJS"            => v"0.12.2"

julia> using JuMP
julia> using NLopt
julia> using SpecialFunctions

julia> erf(1)
0.8427007929497149

julia> m=Model(solver=NLoptSolver(algorithm=:LD_MMA))
Feasibility problem with:
 * 0 linear constraints
 * 0 variables
Solver is NLopt

julia> @variable(m,x,start=0.0)
x

julia> @NLobjective(m,Min,erf(x))
JuMP.NonlinearExprData(ReverseDiffSparse.NodeData[NodeData(CALLUNIVAR, 53, -1), NodeData(VARIABLE, 1, 1)], Float64[])

julia> solve(m)
ERROR: UndefVarError: erf not defined
Stacktrace:
 [1] #forward_eval#7(::ReverseDiffSparse.UserOperatorRegistry, ::Function, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{ReverseDiffSparse.NodeData,1}, ::SparseArrays.SparseMatrixCSC{Bool,Int64}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}) at C:\Users\binha\.julia\packages\ReverseDiffSparse\gvK2V\src\forward.jl:380
 [2] #forward_eval at .\none:0 [inlined]
 [3] forward_eval_all(::JuMP.NLPEvaluator, ::Array{Float64,1}) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\nlp.jl:445
 [4] eval_grad_f(::JuMP.NLPEvaluator, ::Array{Float64,1}, ::Array{Float64,1}) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\nlp.jl:496
 [5] initialize(::JuMP.NLPEvaluator, ::Array{Symbol,1}) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\nlp.jl:403
 [6] loadproblem!(::NLopt.NLoptMathProgModel, ::Int64, ::Int64, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Symbol, ::JuMP.NLPEvaluator) at C:\Users\binha\.julia\packages\NLopt\eqN9a\src\NLoptSolverInterface.jl:117
 [7] _buildInternalModel_nlp(::Model, ::JuMP.ProblemTraits) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\nlp.jl:1244
 [8] #build#123(::Bool, ::Bool, ::JuMP.ProblemTraits, ::Function, ::Model) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\solvers.jl:304
 [9] #build at .\none:0 [inlined]
 [10] #solve#120(::Bool, ::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Model) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\solvers.jl:168
 [11] solve(::Model) at C:\Users\binha\.julia\packages\JuMP\PbnIJ\src\solvers.jl:150
 [12] top-level scope at none:0

有没有办法用求解器在这里调用 erf() ?

4

1 回答 1

0

注册一个自定义函数应该在这里有所帮助:

julia> using JuMP, NLopt, SpecialFunctions

julia> f(x) = erf(x)
f (generic function with 1 method)

julia> m=Model(solver=NLoptSolver(algorithm=:LD_MMA))
Feasibility problem with:
 * 0 linear constraints
 * 0 variables
Solver is NLopt

julia> JuMP.register(m, :f, 1, f, autodiff=true)

julia> @variable(m,x,start=0.0)
x

julia> @NLobjective(m,Min,f(x))
JuMP.NonlinearExprData(ReverseDiffSparse.NodeData[NodeData(CALLUNIVAR, 73, -1), NodeData(VARIABLE, 1, 1)], Float64[])

julia> solve(m)
:Optimal

julia> getvalue(x)
-4.107514124511155
于 2019-01-22T23:28:57.347 回答