Scipy with PyCall in Julia

I have a moderately large system of non-linear equations that I want to solve using scipy.optimize in Julia. The problem is that I store the equations in a vector before passing them to the solver, and PyCall does not accept this. For example, these methods work:

using PyCall
@pyimport scipy.optimize as so

function F(x)
 f1=1- x[1] - x[2]
 f2=8 - x[1] - 3*x[2]
 return f1, f2
end

x0 = [1,1]
x = so.fsolve(F, x0)

function G(x)
 f=[1 - x[1] - x[2],
    8 - x[1] - 3*x[2]]
 return f
end

x0 = [1,1]
x = so.fsolve(G, x0)

      

However, it is not:

function H(x)
 f[1]=1 - x[1] - x[2]
 f[2]=8 - x[1] - 3*x[2]
 return f
end

x0 = [1,1]
x = so.fsolve(H, x0)

      

Also this:

function P(x)
 f[1]= 1 - x[1] - x[2]
 f[2]= 8 - x[1] - 3*x[2]
 return f[1], f[2]
end

x0 = [1,1]
x = so.fsolve(P, x0)

      

I don't think it is impossible to use a loop due to the nature of the problem. Is there a way to return the vector in such a way that fsolve can accept it?

+3


source to share


1 answer


The second two methods never create f

, which is a problem. First you need to create an array.

function H(x)
 f = similar(x)
 f[1]=1 - x[1] - x[2]
 f[2]=8 - x[1] - 3*x[2]
 return f
end

      

which will automatically match the size and type x

, or you can use the constructor:

function H(x)
 f = Vector{Float64}(2)
 f[1]=1 - x[1] - x[2]
 f[2]=8 - x[1] - 3*x[2]
 return f
end

      



However you want to do this, you need to make an array. P

has the same problem.

Also, you should check out NLSolve.jl. It allows you to pre-select a shape:

function H(x,f)
 f[1]=1 - x[1] - x[2]
 f[2]=8 - x[1] - 3*x[2]
 return nothing
end

      

which should allocate less and do better. Roots.jl is another good Julia option.

+6


source







All Articles