これは、Tasos の提案に基づく拡張された回答です (Tasos に感謝します!)。
tl;dr既に登録されているものに対して try-catch ステートメントを使用できます。グローバル環境で目的関数のパラメーターを変更することもできますが、それらを関数にラップすることはできません。
以下は、関数の再定義のチェックを効果的に許可します。
function foo2( f, f1, f2 )
try
JuMP.register(:f,1,f1,f2)
end
####
# Optimization problem here using f
# Leads to some return statement
####
end
end
さらに優れているのは、目的関数のパラメーターを変更するために JuMP が探す単純な方法を実際に使用できることですf
(ただし、ユーザー定義の目的関数に を入れることはできないため、毎回モデルを再定義する必要があります@NLparameter
)。例えば:
using JuMP
using Ipopt
f = (x) -> exp( A * x ) - x
f1 = (x) -> A * exp( A * x ) - 1.0
f2 = (x) -> A * A * exp( A * x )
# Period objective function
JuMP.register(:f, 1, f, f1, f2)
A = 1.0
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
println("x = ", getvalue(x))
# Returns 0
A = 2.0
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
println("x = ", getvalue(x))
# Returns -0.34657 (correct)
f
まったく異なるものに再定義することもできますが、それでも機能します。ただし、これを関数でラップすることはできません。例えば:
function set_A_sol( A )
f = (x) -> exp( A * x ) - x
f1 = (x) -> A * exp( A * x ) - 1.0
f2 = (x) -> A * A * exp( A * x )
# Local redefinition of f
try
JuMP.register(:f, 1, f, f1, f2)
end
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
return getvalue(x)
end
ans1 = set_A_sol(0.5)
ans2 = set_A_sol(1.0)
ans3 = set_A_sol(2.0)
# All return 1.38629
理由はよくわかりませんが、最初にA
が内部に設定されるset_A_sol
と、JuMP の登録が完全に修正A
されるようです。これが私が最終的にできるようにしたいことであることを考えると、私はまだ立ち往生しています。提案を歓迎します!