简体   繁体   English

使用 python 中的最小化时 Julia 中的 Function 和 Lambda 表达式

[英]Function and Lambda expression in Julia when using minimize from python

I have a code in Julia where I use the function minimize from python.我在 Julia 中有一个代码,我使用 function 从 python 最小化。 Here I put a simplified example of it works the cose在这里,我放了一个简化的示例,它可以正常工作

using PyCall
@pyimport scipy.optimize as so

function fidelity1(x)
    f1 = x[1]*x[1]+3*x[2]*x[2]
    return f1
end

x0 = [1 1]
res = so.minimize(fidelity1,x0)

whose result is correctly谁的结果是正确的

Dict{Any,Any} with 10 entries:
  "hess_inv" => [0.5 3.0102e-12; 3.0102e-12 0.166667]
  "fun"      => 2.22049e-16
  "nfev"     => 18
  "status"   => 0
  "message"  => "Optimization terminated successfully."
  "success"  => true
  "x"        => [-7.45039e-9, -7.45073e-9]
  "jac"      => [3.73556e-13, -9.08177e-13]
  "nit"      => 4
  "njev"     => 6

Now, it would be very useful to use a lambda expression, so I write the code in the following way现在,使用 lambda 表达式将非常有用,因此我按以下方式编写代码

using PyCall
@pyimport scipy.optimize as so

fidelity2 = (x1,x2) ->  x1*x1+3*x2*x2

x0 = [1 1]
res = so.minimize(fidelity2,x0)

However, in this case I obtain但是,在这种情况下,我得到

(in a Julia function called from Python)
JULIA: MethodError: no method matching (::var"#3#4")(::Array{Float64,1})
Closest candidates are:
  #3(::Any, !Matched::Any) at In[2]:4
Stacktrace:
 [1] #invokelatest#1 at ./essentials.jl:712 [inlined]
 [2] invokelatest(::Any, ::Any) at ./essentials.jl:711
 [3] _pyjlwrap_call(::Function, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/callback.jl:28
 [4] pyjlwrap_call(::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/callback.jl:44
 [5] macro expansion at /home/candeloro/.julia/packages/PyCall/tqyST/src/exception.jl:95 [inlined]
 [6] #109 at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:43 [inlined]
 [7] disable_sigint at ./c.jl:446 [inlined]
 [8] __pycall! at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:42 [inlined]
 [9] _pycall!(::PyObject, ::PyObject, ::Tuple{var"#3#4",Array{Int64,2}}, ::Int64, ::Ptr{Nothing}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:29
 [10] _pycall!(::PyObject, ::PyObject, ::Tuple{var"#3#4",Array{Int64,2}}, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:11
 [11] (::PyObject)(::Function, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:86
 [12] (::PyObject)(::Function, ::Vararg{Any,N} where N) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:86
 [13] top-level scope at In[2]:7
 [14] eval at ./boot.jl:331 [inlined]
 [15] softscope_include_string(::Module, ::String, ::String) at /home/candeloro/.julia/packages/SoftGlobalScope/u4UzH/src/SoftGlobalScope.jl:217
 [16] execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/candeloro/.julia/packages/IJulia/IDNmS/src/execute_request.jl:67
 [17] #invokelatest#1 at ./essentials.jl:712 [inlined]
 [18] invokelatest at ./essentials.jl:711 [inlined]
 [19] eventloop(::ZMQ.Socket) at /home/candeloro/.julia/packages/IJulia/IDNmS/src/eventloop.jl:8
 [20] (::IJulia.var"#15#18")() at ./task.jl:358

Stacktrace:
 [1] pyerr_check at /home/candeloro/.julia/packages/PyCall/tqyST/src/exception.jl:62 [inlined]
 [2] pyerr_check at /home/candeloro/.julia/packages/PyCall/tqyST/src/exception.jl:66 [inlined]
 [3] _handle_error(::String) at /home/candeloro/.julia/packages/PyCall/tqyST/src/exception.jl:83
 [4] macro expansion at /home/candeloro/.julia/packages/PyCall/tqyST/src/exception.jl:97 [inlined]
 [5] #109 at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:43 [inlined]
 [6] disable_sigint at ./c.jl:446 [inlined]
 [7] __pycall! at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:42 [inlined]
 [8] _pycall!(::PyObject, ::PyObject, ::Tuple{var"#3#4",Array{Int64,2}}, ::Int64, ::Ptr{Nothing}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:29
 [9] _pycall!(::PyObject, ::PyObject, ::Tuple{var"#3#4",Array{Int64,2}}, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:11
 [10] (::PyObject)(::Function, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:86
 [11] (::PyObject)(::Function, ::Vararg{Any,N} where N) at /home/candeloro/.julia/packages/PyCall/tqyST/src/pyfncall.jl:86
 [12] top-level scope at In[2]:7

I can't figure out why the second code doesn't work我不知道为什么第二个代码不起作用

scipy.optimize.minimize expects the objective function, in your case fidelity2 , to take an array of size (n,) as its first argument that holds the values for n independent variables. scipy.optimize.minimize期望目标 function,在您的情况下为fidelity2 ,将大小为(n,)的数组作为其第一个参数,该参数保存n自变量的值。 While migrating to the second format where you use a lambda expression, observe that you also change the signature: fidelity2 expects the independent variables in different function parameters rather than in an array, but that is not how scipy.optimize.minimize operates. While migrating to the second format where you use a lambda expression, observe that you also change the signature: fidelity2 expects the independent variables in different function parameters rather than in an array, but that is not how scipy.optimize.minimize operates.

If all you want is to use lambda expressions, you may change fidelity2 to be more like in your first example如果您只想使用 lambda 表达式,您可以将fidelity2更改为更像您的第一个示例

using PyCall
@pyimport scipy.optimize as so

fidelity2 = x -> x[1]*x[1]+3*x[2]*x[2]

x0 = [1 1]
res = so.minimize(fidelity2, x0)

Note that you do not have to name your lambda expression.请注意,您不必命名 lambda 表达式。 You may use it as an anonymous function inside your call to minimize .您可以在调用中将其用作匿名 function 以minimize . That means the following also works:这意味着以下内容也有效:

using PyCall
@pyimport scipy.optimize as so

x0 = [1 1]
res = so.minimize(x -> x[1]*x[1]+3*x[2]*x[2], x0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM