使用从 python 最小化时 Julia 中的函数和 Lambda 表达式
Function and Lambda expression in Julia when using minimize from python
我在 Julia 中有一段代码,我在其中使用了 python 中的最小化函数。在这里,我放了一个简化的例子,它的工作原理是 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)
谁的结果是正确的
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
现在,使用 lambda 表达式会非常有用,所以我按以下方式编写代码
using PyCall
@pyimport scipy.optimize as so
fidelity2 = (x1,x2) -> x1*x1+3*x2*x2
x0 = [1 1]
res = so.minimize(fidelity2,x0)
然而,在这种情况下我得到
(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
我不明白为什么第二个代码不起作用
scipy.optimize.minimize
期望 objective 函数(在您的例子中 fidelity2
)将大小为 (n,)
的数组作为其第一个参数,该参数保存 n
自变量。在迁移到使用 lambda 表达式的第二种格式时,请注意您还更改了签名:fidelity2
期望自变量在不同的函数参数中而不是在数组中,但那是 not scipy.optimize.minimize
如何运作。
如果您只想使用 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)
请注意,您不必为 lambda 表达式命名。您可以在对 minimize
的调用中将其用作匿名函数。这意味着以下内容也有效:
using PyCall
@pyimport scipy.optimize as so
x0 = [1 1]
res = so.minimize(x -> x[1]*x[1]+3*x[2]*x[2], x0)
我在 Julia 中有一段代码,我在其中使用了 python 中的最小化函数。在这里,我放了一个简化的例子,它的工作原理是 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)
谁的结果是正确的
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
现在,使用 lambda 表达式会非常有用,所以我按以下方式编写代码
using PyCall
@pyimport scipy.optimize as so
fidelity2 = (x1,x2) -> x1*x1+3*x2*x2
x0 = [1 1]
res = so.minimize(fidelity2,x0)
然而,在这种情况下我得到
(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
我不明白为什么第二个代码不起作用
scipy.optimize.minimize
期望 objective 函数(在您的例子中 fidelity2
)将大小为 (n,)
的数组作为其第一个参数,该参数保存 n
自变量。在迁移到使用 lambda 表达式的第二种格式时,请注意您还更改了签名:fidelity2
期望自变量在不同的函数参数中而不是在数组中,但那是 not scipy.optimize.minimize
如何运作。
如果您只想使用 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)
请注意,您不必为 lambda 表达式命名。您可以在对 minimize
的调用中将其用作匿名函数。这意味着以下内容也有效:
using PyCall
@pyimport scipy.optimize as so
x0 = [1 1]
res = so.minimize(x -> x[1]*x[1]+3*x[2]*x[2], x0)