Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查用户定义的函数是否已在Julia/JuMP中注册_Julia_Mathematical Optimization_Julia Jump - Fatal编程技术网

如何检查用户定义的函数是否已在Julia/JuMP中注册

如何检查用户定义的函数是否已在Julia/JuMP中注册,julia,mathematical-optimization,julia-jump,Julia,Mathematical Optimization,Julia Jump,我想检查用户定义的函数是否已经在JuMP/julia中注册。下面是一个例子: function foo( f, f1, f2 ) if !function_is_registered(:f) # This is what I'm looking for JuMP.register(:f,1,f1,f2) end #### # Optimization problem here using f # Leads to some return statement

我想检查用户定义的函数是否已经在JuMP/julia中注册。下面是一个例子:

function foo( f, f1, f2 )

  if !function_is_registered(:f)  # This is what I'm looking for
    JuMP.register(:f,1,f1,f2)
  end
  ####
    # Optimization problem here using f
    # Leads to some return statement
  ####
end

f(x) = exp( A * x )
f1(x) = A * exp( A * x )
f2(x) = A * A * exp( A * x )
    # Function to register

A = 2
use1 = foo(f, f1, f2)
use2 = foo(f, f1, f2)
    # This second usage would fail without the check.  Can't re-register f.

从注释中可以明显看出,第二次使用需要检查。据我所知,跳转寄存器是全局级别的函数——一旦注册,它们就不能在本地重新定义(对吗?如果可以,这也解决了我的问题!)。

这里有一个基于塔索斯建议的扩展答案(谢谢塔索斯!)

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)
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

我不完全理解为什么,但似乎第一次在
set\u A\u sol
内设置
A
时,跳转注册会一次性修复
A
。考虑到这是我最终想要做的事情,我仍然被卡住了。欢迎您的建议

这将满足您的需求

using JuMP
using Ipopt
说明:

如果查看nlp.jl中定义的register函数,“注册”涉及将符号添加到字典中,该字典保存在reverseDiffSpaser中。 注册一个函数并手动检查这些字典,看看它们是什么样子


因此,“取消注册”只涉及从记录的所有位置删除:f及其衍生物的所有痕迹。

这还不受支持。请支持此功能请求。谢谢。第821期开始。请参阅此处以供将来参考:@mlubin使用简单的try/catch块检测注册非常简单。也许提供一个更通用的“取消注册”界面会更有用,类似于我在下面的回答中所做的。取消注册本质上是不安全的,可能会破坏现有的跳转模型,而不是我想让它变得容易。解决方案是使注册成为模型的本地注册,但这需要更多的工作。
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)
  catch e
    if e.msg == "Operator f has already been defined"
      ind = pop!( ReverseDiffSparse.univariate_operator_to_id, :f);
      deleteat!( ReverseDiffSparse.univariate_operators, ind);
      pop!( ReverseDiffSparse.user_univariate_operator_f, ind);
      pop!( ReverseDiffSparse.user_univariate_operator_fprime, ind);
      pop!( ReverseDiffSparse.user_univariate_operator_fprimeprime, ind);
      JuMP.register(:f, 1, f, f1, f2);
    end
  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
julia> ans1 = set_A_sol(0.5)
1.3862943611200509
julia> ans2 = set_A_sol(1.0)
0.0
julia> ans3 = set_A_sol(2.0)
-0.34657359027997264