Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
50 views
in Technique[技术] by (71.8m points)

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

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

question from:https://stackoverflow.com/questions/65848985/function-and-lambda-expression-in-julia-when-using-minimize-from-python

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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. You may use it as an anonymous function inside your call to 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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...