Skip to content

Function handle #221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
blegat opened this issue Jan 30, 2024 · 2 comments
Closed

Function handle #221

blegat opened this issue Jan 30, 2024 · 2 comments

Comments

@blegat
Copy link
Contributor

blegat commented Jan 30, 2024

Is it possible to create a function handle ? I tried the following but it doesn't seem to work

julia> a = MATLAB.mat"@(t, y) 2*t"
inary
Error using save
Unable to save variable 'ans' of class 'function_handle' to STDIO.
 
ERROR: MATLAB.MEngineError("failed to get variable ans from MATLAB session")
Stacktrace:
 [1] get_mvariable(session::MSession, name::Symbol)
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:164
 [2] get_mvariable
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:168 [inlined]
 [3] get_variable(name::Symbol)
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:170
 [4] top-level scope
   @ ~/.julia/dev/MATLAB/src/matstr.jl:169

However, the following works

julia> eval_string(MSession(), "ode45(@(t,y) 2*t, [0,5], 0)");

Ideally would need to create a function handle that is accessing a large Julia matrix. So while this seems to do the trick, I'm worried that it's just copying the content of the matrix in the string so that won't be so good with a large matrix

julia> x = [1, 2]
2-element Vector{Int64}:
 1
 2

julia> eval_string(MSession(), "ode45(@(t,y) sum($x)*t, [0,5], 0)");

This also does not work as it seems to not be able to represent the function handle in Julia

julia> MATLAB.mxcall(:ode45, MATLAB.mat"@(t, y) 2*t", [0, 5], 0)
Fontconfig warning: "/usr/share/fontconfig/conf.avail/05-reset-dirs-sample.conf", line 6: unknown element "reset-dirs"
Fontconfig warning: "/usr/share/fontconfig/conf.avail/05-reset-dirs-sample.conf", line 6: unknown element "reset-dirs"
Error using save
Unable to save variable 'ans' of class 'function_handle' to STDIO.
 
ERROR: MATLAB.MEngineError("failed to get variable ans from MATLAB session")
Stacktrace:
 [1] get_mvariable(session::MSession, name::Symbol)
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:164
 [2] get_mvariable
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:168 [inlined]
 [3] get_variable(name::Symbol)
   @ MATLAB ~/.julia/dev/MATLAB/src/engine.jl:170
 [4] top-level scope
   @ ~/.julia/dev/MATLAB/src/matstr.jl:169

Is there any way to call a MATLAB function that requires function handles and that would scale for large matrix.
For the context, this is the function I'd like to call https://github.com/alpyurtsever/SketchyCGAL/blob/master/solver/CGAL.m and Primitive1, Primitive2 and Primitive3 are the function handles

@tqml
Copy link
Collaborator

tqml commented Feb 21, 2025

Hey @blegat !
At the moment, MATLAB.jl uses the C-API from matlab engine, which as it seems, does not to support copying complex types (Classes, Function Handles) from MATLAB.

Ideally would need to create a function handle that is accessing a large Julia matrix. So while this seems to do the trick, I'm worried that it's just copying the content of the matrix in the string so that won't be so good with a large matrix

In your example this is correct, so you shouldn't do it that way. Instead the correct way to do this is to copy your Julia array to MATLAB using @mput or put_variable, executing the matlab code using eval_string and then get the result using mget.
This process is automated when using a mat"" string.

So ideally do something like:

mat"""
result = ode45(@(t,y) sum($x)*t, [0,5], 0)
$result_x = result.x
$result_y = result.y
"""

this will expand to the following julia code:

put_variable(<random_name>, x)
eval_string("result = ode45(@(t,y) sum(<random_name>)*t, [0,5], 0)")
eval_string("<random_name2> = result.x")
eval_string("<random_name3> = result.y")
result_x = get_variable("<random_name2>")
result_y = get_variable("<random_name3>")
eval_string("clear <random_name> <random_name2> <random_name3>")

Also note that there is a size limit of 2GB that can be transferred via the MATLAB engine API.
So if your matrices exceed that limit, you might need to break them into pieces, transfer individually and then concat them in MATLAB again (or write them to mat file, and read the file from MATLAB)

Hope this helps :)

@blegat
Copy link
Contributor Author

blegat commented Feb 24, 2025

Thanks a lot!

@blegat blegat closed this as completed Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants