pyjulia icon indicating copy to clipboard operation
pyjulia copied to clipboard

Conversion issue using Interpolations

Open mattborghi opened this issue 6 years ago • 1 comments

Hello, I have been trying to use Interpolations.jl from Python but I noticed an issue when pyjulia tries to convert the Julia objects back to Python.

I will show you a toy example with what I have been trying to implement:

i ) First I load Interpolations.jl and create the data to be interpolated.

from julia import Main

Main.using('Interpolations')

Main.h_x = [1, 2, 3, 4]
Main.h_f = [1, 2, 3, 4]

# string to be evaluated along with the extrapolation
interpolation = "interpolate( (h_x, ), h_f, Gridded(Linear()))"

ii) Then, there are two ways of running the same code, first like this, creating interpolation object inside the evaluated string:

Main.eval(f"h = extrapolate( {interpolation}, Flat())")

Main.eval("typeof(h)")
# <PyCall.jlwrap Interpolations.Extrapolation{Float64,1,Interpolations.GriddedInterpolation{Float64,1,Int64,Gridded{Linear},Tuple{Array{Int64,1}}},Gridded{Linear},Flat{Nothing}}>

type(Main.h)
#<class 'list'>

Main.eval("h(5)")
# 4.0 

iii) Or, like this, which which creates the object separately from the actual instruction:

Main.h2 = Main.eval(f"extrapolate({interpolation}, Flat())")

Main.eval("typeof(h2)")
# <PyCall.jlwrap Array{Float64,1}>

type(Main.h2)
# <class 'numpy.ndarray'>

Main.eval("h2(1.0)")
# Exception 'MethodError: objects of type Array{Float64,1} are not callable
# Use square brackets [] for indexing an Array.' occurred while calling julia code:
# h2(1.0)

Step ii works, whereas step iii doesn't. So my question is, if this behavior is some kind of bug in pyjulia, although the latter step is used in the pyjulia documentation.

As a corollary, I tried, without luck, to set a parameter to the eval("str to eval", get_results=[True|False]) method to avoid pyjulia from returning Python Objects. The idea behind this is to avoid surplus Jl/Py communications given that I need to run a set of commands in Jl but only use in Py the last result, i.e.,

Run a set of commands in Julia and set get_results=False

  • create an interpolation obj
  • make some calculations
  • make more evaluations

Finally the last command will return a useful value to be used again in Python (get_results=True)

  • Get a result and send it back to python

Do you have any suggestion?

mattborghi avatar Oct 28 '19 15:10 mattborghi

If you want to invoke a Julia callable, the safest way to do it is to just define a Julia function. Maybe something like this:

h = Main.eval(f"""
let h = extrapolate( {interpolation}, Flat())
    x -> h(x)
end
""")

h(5)

if this behavior is some kind of bug in pyjulia, although the latter step is used in the pyjulia documentation

I wouldn't call it a bug, but I agree it can be improved. The issue is tracked by https://github.com/JuliaPy/PyCall.jl/issues/617

tkf avatar Oct 28 '19 17:10 tkf