bastibe / transplant

Transplant is an easy way of calling Matlab from Python
https://transplant.readthedocs.io
Other
108 stars 26 forks source link

Pass a python function to a matlab function? #89

Open disadone opened 4 years ago

disadone commented 4 years ago

I am a little bit confused about how to use transplant.Matlab I want to pass a python function and several other parameters to a matlab function, for example matlab.fminsearch. So I try

import transplant

matlab = transplant.Matlab()
def pyfunc(x):
    return x+1
func=transplant.MatlabFunction(matlab,pyfunc)

But func(1) returns

TypeError: can not serialize 'function' object

Many Thanks

bastibe commented 4 years ago

That is not possible at the moment, I'm afraid. But you can pass Matlab functions to Matlab:

func = matlab.eval("@(x) x+1")
disadone commented 4 years ago

Thank you!Bastibe. If one can pass a function, that will be really cool.

bastibe commented 4 years ago

It can be done, but I don't have the time to implement the functionality at the moment, sorry.

One would have to create a proxy function on the Matlab side that wraps a call back to Python. At the moment, there is no back channel for Matlab to ask things from Python, so this is not a trivial thing to do.

bigscientist commented 3 years ago

Perhaps data interface such as TCP/IP can works. If the datatype can be freely transported , the tool will be more awesome

bastibe commented 3 years ago

The data is not the (biggest) issue. Transplant already serializes all data through a TCP connection or a local socket. The problem is that you have to create a function inside Matlab that behaves just like the Python function.

This is easier when passing a Matlab function to Python: A new function object is created in Python's local scope that passes all its arguments to Matlab, computes the results there, then passes the result or error back to Python.

But the other way around is much more demanding: How would you handle keyword arguments? Is it safe to create a function in Matlab's global scope? How do you handle generators, or async functions, or callable objects? How would you handle a Python function that returns something that is not serializable to Matlab data? How would you handle Exceptions? The thing is, Python is a much more powerful language than Matlab. Representing Matlab functions and data in Python is possible because Matlab functions and data are simple things. Representing a Python callable in Matlab is much harder, because they can do so much more than Matlab's functions.

It can be done, but it is not a trivial thing to do. There will be plenty of corner cases.

(But you can already grab a Matlab function and pass it back to Matlab.)