d100e52076
Signed-off-by: David Rotermund <54365609+davrot@users.noreply.github.com>
216 lines
4.9 KiB
Markdown
216 lines
4.9 KiB
Markdown
# Running Python remotely from Matlab
|
|
{:.no_toc}
|
|
|
|
<nav markdown="1" class="toc-class">
|
|
* TOC
|
|
{:toc}
|
|
</nav>
|
|
|
|
## The goal
|
|
|
|
We want to integrate Python files and code into our Matlab workflow.
|
|
|
|
Questions to [David Rotermund](mailto:davrot@uni-bremen.de)
|
|
|
|
## Check if you are ready
|
|
|
|
[Versions of Python Compatible with MATLAB Products by Release](https://de.mathworks.com/support/requirements/python-compatibility.html)
|
|
|
|
You need to ask yourself or better Matlab if it is using the correct Python. You can check this via:
|
|
|
|
```matlab
|
|
>> pyenv
|
|
|
|
ans =
|
|
|
|
PythonEnvironment with properties:
|
|
|
|
Version: "3.11"
|
|
Executable: "/data_1/davrot/P3.11/bin/python3"
|
|
Library: "libpython3.11.so.1.0"
|
|
Home: "/data_1/davrot/P3.11"
|
|
Status: NotLoaded
|
|
ExecutionMode: InProcess
|
|
|
|
```
|
|
|
|
If this is wrong (which it isn't in my case) then you can change it (temporarily?) with
|
|
|
|
```matlab
|
|
>> pyenv('Version','/data_1/davrot/P3.11/bin/python3')
|
|
|
|
ans =
|
|
|
|
PythonEnvironment with properties:
|
|
|
|
Version: "3.11"
|
|
Executable: "/data_1/davrot/P3.11/bin/python3"
|
|
Library: "libpython3.11.so.1.0"
|
|
Home: "/data_1/davrot/P3.11"
|
|
Status: NotLoaded
|
|
ExecutionMode: InProcess
|
|
```
|
|
|
|
**Obviously you need to use your location for your Python installation.**
|
|
|
|
## Python help
|
|
|
|
```matlab
|
|
>> py.help('int')
|
|
Help on class int in module builtins:
|
|
|
|
class int(object)
|
|
| int([x]) -> integer
|
|
| int(x, base=10) -> integer
|
|
[...]
|
|
```
|
|
|
|
## Tuple and random number example
|
|
|
|
We can crate a python tuple like this:
|
|
|
|
```matlab
|
|
>> py_dim = py.tuple({py.int(10), py.int(100)})
|
|
|
|
py_dim =
|
|
|
|
Python tuple with values:
|
|
|
|
(10, 100)
|
|
|
|
Use string, double or cell function to convert to a MATLAB array.
|
|
```
|
|
|
|
Now we can use numpy to generate random numbers:
|
|
|
|
```matlab
|
|
>> py_dim = py.tuple({py.int(10), py.int(100)})
|
|
>> rng = py.numpy.random.default_rng();
|
|
>> a = rng.random(py_dim);
|
|
>> py.print(py.type(a))
|
|
<class 'numpy.ndarray'>
|
|
>> py.print(a.shape)
|
|
(10, 100)
|
|
>> py.print(a.dtype)
|
|
float64
|
|
>> whos
|
|
>> whos
|
|
Name Size Bytes Class Attributes
|
|
|
|
a 1x1 8 py.numpy.ndarray
|
|
ans 1x1 8 matlab.pyclient.PythonEnvironment
|
|
py_dim 1x2 8 py.tuple
|
|
rng 1x1 8 py.numpy.random._generator.Generator
|
|
```
|
|
|
|
Alternatively this is also possible:
|
|
|
|
```matlab
|
|
>> b = rng.random(cell({int32(10),int32(100)}));
|
|
```
|
|
|
|
## User defined Python modules
|
|
|
|
Our very own Python function in the file **mtest_1.py**:
|
|
|
|
```python
|
|
import numpy as np
|
|
|
|
def mysquared(input:np.ndarray) -> np.ndarray:
|
|
output = input**2
|
|
return output
|
|
```
|
|
|
|
Now Matlab allows us to do this:
|
|
|
|
```matlab
|
|
>> x = (1:1:10);
|
|
>> x_np = py.numpy.array(x);
|
|
>> y_np = py.mtest_1.mysquared(x_np);
|
|
>> y = double(x_np).^2;
|
|
>> sum(sum(abs(y-double(y_np))))
|
|
|
|
ans =
|
|
|
|
0
|
|
```
|
|
|
|
If you change the py file, then you need to clean it from the memory via
|
|
|
|
```matlab
|
|
>> clear classes
|
|
```
|
|
|
|
Future David here: Well, I had to do this for a file gauss_smear.py with a function gauss_smear:
|
|
```matlab
|
|
if ~exist('mod', 'var')
|
|
mod = py.importlib.import_module('gauss_smear');
|
|
end
|
|
|
|
py.importlib.reload(mod);
|
|
|
|
clearvars -except mod
|
|
mod.gauss_smear(2.0, 0.1)
|
|
```
|
|
|
|
|
|
## Save a numpy file with Matlab
|
|
|
|
In Matlab we save data into numpy file:
|
|
|
|
```matlab
|
|
>> a = rand(100,10);
|
|
>> a_np = py.numpy.array(a);
|
|
>> py.numpy.save("test_1.npy",a_np);
|
|
```
|
|
|
|
Now we can load it into Python:
|
|
|
|
```python
|
|
import numpy as np
|
|
|
|
a = np.load("test_1.npy")
|
|
|
|
print(type(a)) # --> <class 'numpy.ndarray'>
|
|
print(a.shape) # --> (100, 10)
|
|
print(a.dtype) # --> float64
|
|
```
|
|
|
|
## Loading a numpy file with Matlab
|
|
|
|
Under Python we generate a file:
|
|
|
|
```python
|
|
import numpy as np
|
|
|
|
myrng = np.random.default_rng()
|
|
|
|
a = myrng.random((100, 10))
|
|
np.save("test_2.npy", a)
|
|
```
|
|
|
|
And under Matlab we load it:
|
|
|
|
```matlab
|
|
>> a_np = py.numpy.load("test_2.npy");
|
|
>> a = double(a_np);
|
|
>> whos
|
|
Name Size Bytes Class Attributes
|
|
|
|
a 100x10 8000 double
|
|
a_np 1x1 8 py.numpy.ndarray
|
|
```
|
|
|
|
## References
|
|
* [Access Python Modules from MATLAB - Getting Started](https://de.mathworks.com/help/matlab/matlab_external/create-object-from-python-class.html)
|
|
* [Use Python str Variables in MATLAB](https://de.mathworks.com/help/matlab/matlab_external/pythonstrvariables.html)
|
|
* [Use Python list Variables in MATLAB](https://de.mathworks.com/help/matlab/matlab_external/pythonlistvariables.html)
|
|
* [Use Python tuple Variables in MATLAB](https://de.mathworks.com/help/matlab/matlab_external/pythontuplevariables.html)
|
|
* [Use Python dict Variables in MATLAB](https://de.mathworks.com/help/matlab/matlab_external/python-dict-variables.html)
|
|
* [Call User-Defined Python Module](https://de.mathworks.com/help/matlab/matlab_external/call-user-defined-custom-module.html)
|
|
|
|
|
|
|
|
|
|
|
|
|