1659955626

Moonwalk.jl

This is meant to be a partial MATLAB to Julia compiler, just to ease the transition of libraries.

Run with `./run_moonwalk.jl matlab_file.m`

.

- Valid Matlab
- No empty switch statements

Run `./MoonwalkTest.jl`

to run the test suite, or input specific numbers to run specific test cases (in the samples folder).

Author: Diogo149

Source Code: https://github.com/diogo149/Moonwalk.jl

1659955626

Moonwalk.jl

This is meant to be a partial MATLAB to Julia compiler, just to ease the transition of libraries.

Run with `./run_moonwalk.jl matlab_file.m`

.

- Valid Matlab
- No empty switch statements

Run `./MoonwalkTest.jl`

to run the test suite, or input specific numbers to run specific test cases (in the samples folder).

Author: Diogo149

Source Code: https://github.com/diogo149/Moonwalk.jl

1659948000

The `MATLAB.jl`

package provides an interface for using MATLAB® from Julia using the MATLAB C api. In other words, this package allows users to call MATLAB functions within Julia, thus making it easy to interoperate with MATLAB from the Julia language.

You cannot use `MATLAB.jl`

without having purchased and installed a copy of MATLAB® from MathWorks. This package is available free of charge and in no way replaces or alters any functionality of MathWorks's MATLAB product.

This package is composed of two aspects:

Creating and manipulating mxArrays (the data structure that MATLAB used to represent arrays and other kinds of data)

Communicating with MATLAB engine sessions

**Warning**:

MATLAB string arrays are not supported, and will throw an error exception. This also applies if they are nested within a MATLAB struct. This is a limitation of the MATLAB C api. The MATLAB function `convertContainedStringsToChars`

may be used to facilitate conversion to a compatible format for use with `MATLAB.jl`

.

Threading is also not supported within Julia when using the MATLAB.jl library.

**Important**: The procedure to setup this package consists of the following steps.

By default, `MATLAB.jl`

uses the MATLAB installation with the greatest version number. To specify that a specific MATLAB installation should be used, set the environment variable `MATLAB_ROOT`

.

For Matlab R2020a onwards, you should be able to go directly to step 2. If you encounter issues, run `matlab -batch "comserver('register')"`

in the command prompt. For earlier versions of Matlab, start a command prompt as an administrator and enter `matlab /regserver`

.

From Julia run: `Pkg.add("MATLAB")`

Make sure `matlab`

is in executable path.

Make sure `csh`

is installed. (Note: MATLAB for Linux relies on `csh`

to open an engine session.)

To install `csh`

in Debian/Ubuntu/Linux Mint, you may type in the following command in terminal:

`sudo apt-get install csh`

From Julia run: `Pkg.add("MATLAB")`

Ensure that MATLAB is installed in `/Applications`

(for example, if you are using MATLAB R2012b, you may add the following command to `.profile`

: `export MATLAB_HOME=/Applications/MATLAB_R2012b.app`

).

From Julia run: `Pkg.add("MATLAB")`

An instance of `MxArray`

encapsulates a MATLAB variable. This package provides a series of functions to manipulate such instances.

One can use the function `mxarray`

to create MATLAB variables (of type `MxArray`

), as follows

```
mxarray(Float64, n) # creates an n-by-1 MATLAB zero array of double valued type
mxarray(Int32, m, n) # creates an m-by-n MATLAB zero array of int32 valued type
mxarray(Bool, m, n) # creates a MATLAB logical array of size m-by-n
mxarray(Float64, (n1, n2, n3)) # creates a MATLAB array of size n1-by-n2-by-n3
mxcellarray(m, n) # creates a MATLAB cell array
mxstruct("a", "b", "c") # creates a MATLAB struct with given fields
```

You may also convert a Julia variable to MATLAB variable

```
a = rand(m, n)
x = mxarray(a) # converts a to a MATLAB array
x = mxarray(1.2) # converts a scalar 1.2 to a MATLAB variable
a = sprand(m, n, 0.1)
x = mxarray(a) # converts a sparse matrix to a MATLAB sparse matrix
x = mxarray("abc") # converts a string to a MATLAB char array
x = mxarray(["a", 1, 2.3]) # converts a Julia array to a MATLAB cell array
x = mxarray(Dict("a"=>1, "b"=>"string", "c"=>[1,2,3])) # converts a Julia dictionary to a MATLAB struct
```

The function `mxarray`

can also convert a compound type to a Julia struct:

```
struct S
x::Float64
y::Vector{Int32}
z::Bool
end
s = S(1.2, Int32[1, 2], false)
x = mxarray(s) # creates a MATLAB struct with three fields: x, y, z
xc = mxarray([s, s]) # creates a MATLAB cell array, each cell is a struct.
xs = mxstructarray([s, s]) # creates a MATLAB array of structs
```

**Note:** For safety, the conversation between MATLAB and Julia variables uses deep copy.

When you finish using a MATLAB variable, you may call `delete`

to free the memory. But this is optional, it will be deleted when reclaimed by the garbage collector.

```
delete(x)
```

*Note:* if you put a MATLAB variable `x`

to MATLAB engine session, then the MATLAB engine will take over the management of its life cylce, and you don't have to delete it explicitly.

You may access attributes and data of a MATLAB variable through the functions provided by this package.

```
# suppose x is of type MxArray
nrows(x) # returns number of rows in x
ncols(x) # returns number of columns in x
nelems(x) # returns number of elements in x
ndims(x) # returns number of dimensions in x
size(x) # returns the size of x as a tuple
size(x, d) # returns the size of x along a specific dimension
eltype(x) # returns element type of x (in Julia Type)
elsize(x) # return number of bytes per element
data_ptr(x) # returns pointer to data (in Ptr{T}), where T is eltype(x)
# suppose s is a MATLAB struct
mxnfields(s) # returns the number of fields in struct s
```

You may also make tests on a MATLAB variable.

```
is_double(x) # returns whether x is a double array
is_sparse(x) # returns whether x is sparse
is_complex(x) # returns whether x is complex
is_cell(x) # returns whether x is a cell array
is_struct(x) # returns whether x is a struct
is_empty(x) # returns whether x is empty
... # there are many more there
```

```
a = jarray(x) # converts x to a Julia array
a = jvector(x) # converts x to a Julia vector (1D array) when x is a vector
a = jscalar(x) # converts x to a Julia scalar
a = jmatrix(x) # converts x to a Julia matrix
a = jstring(x) # converts x to a Julia string
a = jdict(x) # converts a MATLAB struct to a Julia dictionary (using fieldnames as keys)
a = jvalue(x) # converts x to a Julia value in default manner
```

This package provides functions to manipulate MATLAB's mat files:

```
mf = MatFile(filename, mode) # opens a MAT file using a specific mode, and returns a handle
mf = MatFile(filename) # opens a MAT file for reading, equivalent to MatFile(filename, "r")
close(mf) # closes a MAT file.
get_mvariable(mf, name) # gets a variable and returns an mxArray
get_variable(mf, name) # gets a variable, but converts it to a Julia value using `jvalue`
put_variable(mf, name, v) # puts a variable v to the MAT file
# v can be either an MxArray instance or normal variable
# If v is not an MxArray, it will be converted using `mxarray`
put_variables(mf; name1=v1, name2=v2, ...) # put multiple variables using keyword arguments
variable_names(mf) # get a vector of all variable names in a MAT file
```

There are also convenient functions that can get/put all variables in one call:

```
read_matfile(filename) # returns a dictionary that maps each variable name
# to an MxArray instance
write_matfile(filename; name1=v1, name2=v2, ...) # writes all variables given in the
# keyword argument list to a MAT file
```

Both `read_matfile`

and `write_matfile`

will close the MAT file handle before returning.

**Examples:**

```
struct S
x::Float64
y::Bool
z::Vector{Float64}
end
write_matfile("test.mat";
a = Int32[1 2 3; 4 5 6],
b = [1.2, 3.4, 5.6, 7.8],
c = [[0.0, 1.0], [1.0, 2.0], [1.0, 2.0, 3.0]],
d = Dict("name"=>"MATLAB", "score"=>100.0),
s = "abcde",
ss = [S(1.0, true, [1., 2.]), S(2.0, false, [3., 4.])] )
```

This example will create a MAT file called `test.mat`

, which contains six MATLAB variables:

`a`

: a 2-by-3 int32 array`b`

: a 4-by-1 double array`c`

: a 3-by-1 cell array, each cell contains a double vector`d`

: a struct with two fields: name and score`s`

: a string (i.e. char array)`ss`

: an array of structs with two elements, and three fields: x, y, and z.

To evaluate expressions in MATLAB, one may open a MATLAB engine session and communicate with it. There are three ways to call MATLAB from Julia:

- The
`mat""`

custom string literal allows you to write MATLAB syntax inside Julia and use Julia variables directly from MATLAB via interpolation - The
`eval_string`

evaluate a string containing MATLAB expressions (typically used with the helper macros`@mget`

and`@mput`

- The
`mxcall`

function calls a given MATLAB function and returns the result

In general, the `mat""`

custom string literal is the preferred method to interact with the MATLAB engine.

*Note:* There can be multiple (reasonable) ways to convert a MATLAB variable to Julia array. For example, MATLAB represents a scalar using a 1-by-1 matrix. Here we have two choices in terms of converting such a matrix back to Julia: (1) convert to a scalar number, or (2) convert to a matrix of size 1-by-1.

The `mat""`

custom string literal

Text inside the `mat""`

custom string literal is in MATLAB syntax. Variables from Julia can be "interpolated" into MATLAB code by prefixing them with a dollar sign as you would interpolate them into an ordinary string.

```
using MATLAB
x = range(-10.0, stop=10.0, length=500)
mat"plot($x, sin($x))" # evaluate a MATLAB function
y = range(2.0, stop=3.0, length=500)
mat"""
$u = $x + $y
$v = $x - $y
"""
@show u v # u and v are accessible from Julia
```

As with ordinary string literals, you can also interpolate whole Julia expressions, e.g. `mat"$(x[1]) = $(x[2]) + $(binomial(5, 2))"`

.

`eval_string`

You may also use the `eval_string`

function to evaluate MATLAB code as follows

```
eval_string("a = sum([1,2,3])")
```

The `eval_string`

function also takes an optional argument that specifies which MATLAB session to evaluate the code in, e.g.

```
julia> s = MSession();
julia> eval_string(s, "a = sum([1,2,3])")
a =
6
```

`mxcall`

You may also directly call a MATLAB function on Julia variables using `mxcall`

:

```
x = -10.0:0.1:10.0
y = -10.0:0.1:10.0
xx, yy = mxcall(:meshgrid, 2, x, y)
```

*Note:* Since MATLAB functions behavior depends on the number of outputs, you have to specify the number of output arguments in `mxcall`

as the second argument.

`mxcall`

puts the input arguments to the MATLAB workspace (using mangled names), evaluates the function call in MATLAB, and retrieves the variable from the MATLAB session. This function is mainly provided for convenience. However, you should keep in mind that it may incur considerable overhead due to the communication between MATLAB and Julia domain.

`@mget`

and `@mput`

The macro `@mget`

can be used to extract the value of a MATLAB variable into Julia

```
julia> mat"a = 6"
julia> @mget a
6.0
```

The macro `@mput`

can be used to translate a Julia variable into MATLAB

```
julia> x = [1,2,3]
julia> @mput x
julia> eval_string("y = sum(x)")
julia> @mget y
6.0
julia> @show y
a = 63.0
```

If the MATLAB function is not in the current directory, we need to first add it to the MATLAB path before calling through Julia:

```
mat"addpath('/path/to/folder')"
val = mat"myfunction($arg1, $arg2)"
```

For example, if there is a MATLAB file located at `/path/to/folder`

with contents:

```
function [r,u] = test(x, y)
r = x + y;
u = x - y;
end
```

We can call this function as follows in Julia:

```
using MATLAB
x = range(-10.0, stop=10.0, length=500)
y = range(2.0, stop=3.0, length=500)
mat"addpath('/path/to/folder')"
r, u = mxcall(:test,2,x,y)
```

To open an interactive window for the MATLAB session, use the command `show_msession()`

and to hide the window, use `hide_msession()`

. *Warning: manually closing this window will result in an error or result in a segfault; it is advised that you only use the **hide_msession()** command to hide the interactive window.*

Note that this feature only works on Windows.

```
# default
show_msession() # open the default MATLAB session interactive window
get_msession_visiblity() # get the session's visibility state
hide_msession() # hide the default MATLAB session interactive window
# similarily
s = MSession()
show_msession(s)
get_msession_visiblity(a)
hide_msession(s)
```

This package provides a series of functions for users to control the communication with MATLAB sessions.

Here is an example:

```
s1 = MSession() # creates a MATLAB session
s2 = MSession(0) # creates a MATLAB session without recording output
x = rand(3, 4)
put_variable(s1, :x, x) # put x to session s1
y = rand(2, 3)
put_variable(s2, :y, y) # put y to session s2
eval_string(s1, "r = sin(x)") # evaluate sin(x) in session s1
eval_string(s2, "r = sin(y)") # evaluate sin(y) in session s2
r1_mx = get_mvariable(s1, :r) # get r from s1
r2_mx = get_mvariable(s2, :r) # get r from s2
r1 = jarray(r1_mx)
r2 = jarray(r2_mx)
# ... do other stuff on r1 and r2
close(s1) # close session s1
close(s2) # close session s2
```

Author: JuliaInterop

Source Code: https://github.com/JuliaInterop/MATLAB.jl

License: MIT license

1624471200

I am guessing that many of you use Java as your primary language in your day-to-day work. Have you ever thought about why **HotSpot** is even called **HotSpot** or what the **Tiered Compilation** is and how it relates to Java? I will answer these questions and a few others through the course of this article. I will begin this by explaining a few things about compilation itself and the theory behind it.

In general, we can differentiate two basic ways of translating human readable code to instructions that can be understood by our computers:

- After code is written, a compiler will take it and produce a binary executable file. This file will contain set of machine code instructions targeted for particular CPU architecture. Of course the same binary should be able to run on CPUs with similar set of instructions but in more complex cases your binary may fail to run and may require recompiling to meet server requirements. We lose the ability to run on multiple platforms for the benefit of faster execution on a dedicated platform.

- Already existing source code will be run and turned into binary code line by line by the interpreter while the exact line is being executed. Thanks to this feature, the application may run on every CPU that has the correct interpreter. On the other hand, it will make the execution slower than in the case of statically compiled languages. We benefit from the ability to run on multiple platforms but lose on execution time.

As you can see both types have their advantages and disadvantages and are dedicated to specific use cases and will probably fail if not used in the correct case. You may ask – if there are only two ways does it mean that Java is an interpreted or a statically compiled language?

#java #jvm #compiler #graalvm #hotspot #compilation #jit compiler #native image #aot #tiered compilation

1659767019

In this tutorial, we'll learn about MATDaemon.jl, calling Julia from MATLAB. Calling MATLAB code from Julia via the C API has been supported for many years via MATLAB.jl

Call Julia from MATLAB using a Julia daemon launched by `DaemonMode.jl`

.

Use the MATLAB function `jlcall.m`

to call Julia from MATLAB:

```
>> jlcall('sort', {rand(2,5)}, struct('dims', int64(2)))
ans =
0.1270 0.2785 0.6324 0.8147 0.9575
0.0975 0.5469 0.9058 0.9134 0.9649
```

The positional arguments passed to `jlcall.m`

are:

- The Julia function to call, given as a MATLAB
`char`

array. This can be any Julia expression which evaluates to a function. For example,`'a=2; b=3; x -> a*x+b'`

. For convenience, the empty string`''`

is interpreted as`'(args...; kwargs...) -> nothing'`

, returning`nothing`

for any inputs.**Note:**expressions are wrapped in a`let`

block and evaluated in the global scope - Positional arguments, given as a MATLAB
`cell`

array. For example,`args = {arg1, arg2, ...}`

- Keyword arguments, given as a MATLAB
`struct`

. For example,`kwargs = struct('key1', value1, 'key2', value2, ...)`

The first time `jlcall.m`

is invoked:

`MATDaemon.jl`

will be installed into a local Julia project, if one does not already exist. By default, a folder`.jlcall`

is created in the same folder as`jlcall.m`

- A Julia server will be started in the background using
`DaemonMode.jl`

All subsequent calls to Julia are run on the Julia server. The server will be automatically killed when MATLAB exits.

In the event that the Julia server reaches an undesired state, the server can be restarted by passing the `'restart'`

flag with value `true`

:

```
>> jlcall('', 'restart', true) % restarts the Julia server and returns nothing
```

Similarly, one can shutdown the Julia server without restarting it:

```
>> jlcall('', 'shutdown', true) % shuts down the Julia server and returns nothing
```

Before calling Julia functions, it may be necessary or convenient to first set up the Julia environment. For example, one may wish to activate a local project environment, run setup scripts, import modules for later use, or set the number of threads for running multithreaded code.

This setup can be conveniently executed at the start of your MATLAB script with a single call to `jlcall.m`

as follows:

```
>> jlcall('', ...
'project', '/path/to/MyProject', ... % activate a local Julia Project
'setup', '/path/to/setup.jl', ... % run a setup script to load some custom Julia code
'modules', {'MyProject', 'LinearAlgebra', 'Statistics'}, ... % load a custom module and some modules from Base Julia
'threads', 'auto', ... % use the default number of Julia threads
'restart', true ... % start a fresh Julia server environment
)
```

See the corresponding sections below for more details about these flags.

The number of threads used by the Julia server can be set using the `'threads'`

flag:

```
>> jlcall('() -> Threads.nthreads()', 'threads', 8, 'restart', true)
ans =
int64
8
```

The default value for `'threads'`

is `'auto'`

, deferring to Julia to choose the number of threads.

**Note:** Julia cannot change the number of threads at runtime. In order for the `'threads'`

flag to take effect, the server must be restarted.

Julia modules can be loaded and used:

```
>> jlcall('LinearAlgebra.norm', {[3.0; 4.0]}, 'modules', {'LinearAlgebra'})
ans =
5
```

**Note:** modules are loaded using `import`

, not `using`

. Module symbols must therefore be fully qualified, e.g. `LinearAlgebra.norm`

in the above example as opposed to `norm`

.

By default, previously loaded Julia code is available on subsequent calls to `jlcall.m`

. For example, following the above call to `LinearAlgebra.norm`

, the `LinearAlgebra.det`

function can be called without loading `LinearAlgebra`

again:

```
>> jlcall('LinearAlgebra.det', {[1.0 2.0; 3.0 4.0]})
ans =
-2
```

Set the `'shared'`

flag to `false`

in order to evaluate each Julia call in a separate namespace on the Julia server:

```
% Restart the server, setting 'shared' to false
>> jlcall('LinearAlgebra.norm', {[3.0; 4.0]}, 'modules', {'LinearAlgebra'}, 'restart', true, 'shared', false)
ans =
5
% This call now errors, despite the above command loading the LinearAlgebra module, as LinearAlgebra.norm is evaluated in a new namespace
>> jlcall('LinearAlgebra.norm', {[3.0; 4.0]}, 'shared', false)
ERROR: LoadError: UndefVarError: LinearAlgebra not defined
Stacktrace:
...
```

Instead of running Julia code on a persistent Julia server, unique Julia instances can be launched for each call to `jlcall.m`

by passing the `'server'`

flag with value `false`

.

**Note:** this may cause significant overhead when repeatedly calling `jlcall.m`

due to Julia package precompilation and loading:

```
>> tic; jlcall('x -> sum(abs2, x)', {1:5}, 'server', false); toc
Elapsed time is 4.181178 seconds. % call unique Julia instance
>> tic; jlcall('x -> sum(abs2, x)', {1:5}, 'restart', true); toc
Elapsed time is 5.046929 seconds. % re-initialize Julia server
>> tic; jlcall('x -> sum(abs2, x)', {1:5}); toc
Elapsed time is 0.267088 seconds. % call server; significantly faster
```

Code from a local Julia project can be loaded and called:

```
>> jlcall('MyProject.my_function', args, kwargs, ...
'project', '/path/to/MyProject', ...
'modules', {'MyProject'})
```

**Note:** the string passed via the `'project'`

flag is simply forwarded to `Pkg.activate`

; it is the user's responsibility to ensure that the project's dependencies have been installed.

Julia functions may require or return types which cannot be directly passed from or loaded into MATLAB. For example, suppose one would like to query `Base.VERSION`

. Naively calling `jlcall('() -> Base.VERSION')`

would fail, as `typeof(Base.VERSION)`

is not a `String`

but a `VersionNumber`

.

One possible remedy is to define a wrapper function in a Julia script:

```
# setup.jl
julia_version() = string(Base.VERSION)
```

Then, use the `'setup'`

flag to pass the above script to `jlcall.m`

:

```
>> jlcall('julia_version', 'setup', '/path/to/setup.jl')
ans =
'1.6.1'
```

In this case, `jlcall('() -> string(Base.VERSION)')`

would work just as well. In general, however, interfacing with complex Julia libraries using MATLAB types may be nontrivial, and the `'setup'`

flag allows for the execution of arbitrary setup code.

**Note:** the setup script is loaded into the global scope using `include`

; when using persistent environments, symbols defined in the setup script will be available on subsequent calls to `jlcall.m`

.

Output(s) from Julia are returned using the MATLAB `cell`

array `varargout`

, MATLAB's variable-length list of output arguments. A helper function `MATDaemon.matlabify`

is used to convert Julia values into MATLAB-compatible values. Specifically, the following rules are used to populate `varargout`

with the Julia output `y`

:

- If
`y::Nothing`

, then`varargout = {}`

and no outputs are returned to MATLAB - If
`y::Tuple`

, then`length(y)`

outputs are returned, with`varargout{i}`

given by`matlabify(y[i])`

- Otherwise, one output is returned with
`varargout{1}`

given by`matlabify(y)`

The following `matlabify`

methods are defined by default:

```
matlabify(x) = x # default fallback
matlabify(::Union{Nothing, Missing}) = zeros(0,0) # equivalent to MATLAB's []
matlabify(x::Symbol) = string(x)
matlabify(xs::Tuple) = Any[matlabify(x) for x in xs] # matlabify values
matlabify(xs::Union{<:AbstractDict, <:NamedTuple, <:Base.Iterators.Pairs}) = Dict{String, Any}(string(k) => matlabify(v) for (k, v) in pairs(xs)) # convert keys to strings and matlabify values
```

**Note:** MATLAB `cell`

and `struct`

types correspond to `Array{Any}`

and `Dict{String, Any}`

in Julia.

Conversion via `matlabify`

can easily be extended to additional types. Returning to the example from the above section, we can define a `matlabify`

method for `Base.VersionNumber`

:

```
# setup.jl
MATDaemon.matlabify(v::Base.VersionNumber) = string(v)
```

Now, the return type will be automatically converted:

```
>> jlcall('() -> Base.VERSION', 'setup', '/path/to/setup.jl')
ans =
'1.6.1'
```

MATLAB inputs and Julia ouputs are passed back and forth between MATLAB and the `DaemonMode.jl`

server by writing to temporary `.mat`

files. The location of these files can be configured with the `'infile'`

and `'outfile'`

flags, respectively. Pointing these files to a ram-backed file system is recommended when possible (for example, the `/tmp`

folder on Linux is usually ram-backed), as read/write speed will likely improve. This is now the default; `'infile'`

and `'outfile'`

are created via the MATLAB `tempname`

function (thanks to @mauro3 for this tip).

Nevertheless, this naturally leads to some overhead when calling Julia, particularly when the MATLAB inputs and/or Julia outputs have large memory footprints. It is therefore not recommended to use `jlcall.m`

in performance critical loops.

This package has been tested on a variety of MATLAB versions. However, for some versions of Julia and MATLAB, supported versions of external libraries may clash. For example, running `jlcall.m`

using Julia v1.6.1 and MATLAB R2015b gives the following error:

```
>> jlcall
ERROR: Unable to load dependent library ~/.local/julia-1.6.1/bin/../lib/julia/libjulia-internal.so.1
Message: /usr/local/MATLAB/R2015b/sys/os/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ~/.local/julia-1.6.1/bin/../lib/julia/libjulia-internal.so.1)
```

This error results due to a clash of supported `libstdc++`

versions, and does not occur when using e.g. Julia v1.5.4 with MATLAB R2015b, or Julia v1.6.1 with MATLAB R2020b.

If you encounter this issue, see the `Julia`

and `MATLAB`

documentation for information on mutually supported external libraries.

This repository contains utilities for parsing and running Julia code, passing MATLAB arguments to Julia, and retrieving Julia outputs from MATLAB.

The workhorse behind `MATDaemon.jl`

and `jlcall.m`

is `DaemonMode.jl`

which is used to start a persistent Julia server in the background.

**Download Details: **

Author: jondeuce

Source Code: https://github.com/jondeuce/MATDaemon.jl

License: MIT

#julia #matlab

1659767267

In this tutorial, we'll learn about Mex.jl, embedding Julia in the MATLAB process using MATLAB's C++ Mex interface. This allows Julia functions to be called from MATLAB. This also allows (embedded) Julia to call MATLAB functions.

*Embedding **Julia** in the **MATLAB** process*

**Mex.jl** embeds Julia into the MATLAB process using MATLAB's C++ Mex interface. This allows Julia functions to be called from MATLAB. This also allows (embedded) Julia to call MATLAB functions.

`Mex.jl`

requires MATLAB and Julia along with a C++ compiler configured to work with MATLAB's `mex`

command, the last is required for building the `mexjulia`

MEX function. You can check that a compiler is properly configured by executing:

```
>> mex -setup C++
```

from the MATLAB command prompt.

**NOTE:** This project currently only supports Julia 1.5. Support for Julia 1.6 and greater will be possible when the changes resulting from *https://github.com/JuliaLang/julia/issues/42411** are incorporated into the latest stable release of Julia.*

First ensure that the MATLAB.jl Julia package can be properly installed.

Then enter the package manager by typing `]`

and then run the following:

```
pkg> add Mex
```

The build process will:

- use
`julia`

to determine build options, - build the
`mexjulia`

MEX function from source, - add the
`mexjulia`

directory to your MATLAB path.

By default, `Mex.jl`

uses the MATLAB installation with the greatest version number. To specify that a specific MATLAB installation should be used, set the environment variable `MATLAB_ROOT`

.

Use `jl.eval`

to parse and evaluate MATLAB strings as Julia expressions:

```
>> jl.eval('2+2')
ans =
int64
4
```

You can evaluate multiple expressions in a single call:

```
>> [s, c] = jl.eval('sin(pi/3), cos(pi/3)')
s =
0.8660
c =
0.5000
```

Note that Julia's `STDOUT`

and `STDERR`

are not redirected to the MATLAB console. But if MATLAB is launched from the terminal they will appear there.

```
>> jl.eval('println("Hello, world!")');
>> jl.eval('@warn("Oh, no!")');
```

One can avoid the parentheses and string quotes using `jleval`

(a simple wrapper around `jl.eval`

) and MATLAB's command syntax:

```
>> jleval 1 + 1
ans =
int64
2
>> jleval println("Hello, world!")
Hello, world!
```

Use `jl.call`

to call a Julia function specified by its name as a string:

```
>> jl.call('factorial', int64(10))
ans =
3628800
```

Load new Julia code by calling `jl.include`

:

```
>> jl.include('my_own_julia_code.jl')
```

Exercise more control over how data is marshaled between MATLAB and Julia by defining a Julia function with a "MEX-like" signature and invoking it with `jl.mex`

:

```
>> jleval import MATLAB
>> jleval double_it(args::Vector{MATLAB.MxArray}) = [2*MATLAB.jvalue(arg) for arg in args]
>> a = rand(5,5)
a =
0.6443 0.9390 0.2077 0.1948 0.3111
0.3786 0.8759 0.3012 0.2259 0.9234
0.8116 0.5502 0.4709 0.1707 0.4302
0.5328 0.6225 0.2305 0.2277 0.1848
0.3507 0.5870 0.8443 0.4357 0.9049
>> jl.mex('double_it', a)
ans =
1.2886 1.8780 0.4155 0.3895 0.6222
0.7572 1.7519 0.6025 0.4518 1.8468
1.6232 1.1003 0.9418 0.3414 0.8604
1.0657 1.2450 0.4610 0.4553 0.3696
0.7015 1.1741 1.6886 0.8714 1.8098
```

The first argument to `jl.mex`

is the name of the function to be invoked. All remaining arguments are treated as function arguments.

`jl.mex`

expects the functions on which it is invoked to accept a single argument of type `Vector{MATLAB.MxArray}`

and to return an iterable collection of values on which `MATLAB.mxarray`

may be successfully invoked (*e.g.*, a value of type `Vector{MATLAB.MxArray}`

).

Additional usage examples may be found in the `examples`

folder.

To learn how to reduce the overhead associated with this package, see `performance.m`

in the example folder.

**Download Details: **

Author: byuflowlab

Source Code: https://github.com/byuflowlab/Mex.jl

License: MIT

#julia #matlab