I have some MATLAB script, for example:
function mat_foo(varargin)
params.x = 'aaa';
params = parse_input(params, varargin);
disp(params.x);
end
parse_input is a function I have which convert data from varargin and override the defaults at 'params' struct.
I compiled this function and I want to call it from python, I do it the following way:
subprocess.check_call(['$/mat_foo.app/Contents/MacOS/applauncher x bbb'], shell=True)
This sets params.x to 'bbb' and works well.
My problem is that each time I want to call a compiled MATLAB it initializes the MCR and takes about 8-10 seconds.
My question is if there is a way to initialize the MCR once and use it many times quickly?
I use MATLAB R2013a and python 2.7.5 on OSX
It is possible to compile your code in a shared library as described here. You can load this library in python with
mymatlab = cdll.LoadLibrary("mymatlab_library.so")
and initialize and load the MCR by calling a function
mymatlab.initializeMyLibrary()
that might do nothing or only prints a text to the console with matlab's disp function.
Subsequent function calls to your library should execute immediately.
See also this Mathworks discussion.
Related
I've written some code in Python using numpy, pandas, scikit-learn. Is it possible to call this Python code from a Julia Program?
I think you can think to three different way to call Python code from Julia, in order from the most low level to the highest level they are:
Use the Foreign Funcall Interface as suggested by #madbird. However you will almost surelly not want to do this, as a package that exploits it, PyCall.jl, already exists;
Use the abovementioned PyCall.jl package to call any python code and/or wrap a python library (well.. "most".. "any" is a dangerous word). Details of this below;
As wrapping a Python library using PyCall is very easy, the most important Python libraries have been already wrapped in Julia, like Pandas in Pandas.jl, Scikit-learn in ScikitLearn.jl, etc. If you need them, just use the corresponding Julia package.
How to use PyCall.jl to call Python code and libraries.
Note: The following is an excerpt from my "Julia Quick Syntax Reference" book (Apress, 2019)
Julia ⇄ Python
The "standard" way to call Python code in Julia is to use the PyCall package.
Some of its nice features are: (a) it can automatically download and install a local copy of Python, private to Julia, in order to avoid messing with version dependency from our "main" Python installation and provide a consistent environment in Linux, Windows and MacOS; (b) it provides automatic conversion between Julia and Python types; (c) it is very simple to use.
Concerning the first point, PyCall by default install the "private" Python environment in Windows and MacOS while it will use the system default Python environment in Linux. +
We can override such behaviour with (from the Julia prompt) ENV["PYTHON"]="blank or /path/to/python"; using Pkg; Pkg.build("PyCall"); where, if the environmental variable is empty, PyCall will install the "private" version of Python.
Given the vast amount of Python libraries, it is no wonder that PyCall is one of the most common Julia packages.
Embed Python code in a Julia program
Embedding Python code in a Julia program is similar to what we saw with C++, except that we don't need (for the most) to wonder about transforming data. We both define and call the Python functions with py"...", and in the function call we can use directly our Julia data:
using PyCall
py"""
def sumMyArgs (i, j):
return i+j
def getNElement (n):
a = [0,1,2,3,4,5,6,7,8,9]
return a[n]
"""
a = py"sumMyArgs"(3,4) # 7
b = py"sumMyArgs"([3,4],[5,6]) # [8,10]
typeof(b) # Array{Int64,1}
c = py"sumMyArgs"([3,4],5) # [8,9]
d = py"getNElement"(1) # 1
Note that we don't need to convert even for complex data like arrays, and the results are converted back to Julia types.
Type conversion is automatic for numeric, boolean, string, IO stream, date/period, and function types, along with tuples, arrays/lists, and dictionaries of these types. Other types are instead converted to the generic PyObject type.
Note from the last line of the previous example that PyCall doesn't attempt index conversion (Python arrays are 0-based while Julia ones are 1-based): calling the python getNElement() function with "1" as argument will retrieve what in Python is the element "1" of the array.
Use Python libraries
Using a Python library is straightforward as well, as shown in the below example that use the ezodf module to create an OpenDocument spreadsheet (a wrapper of ezodf for ODS documents - that internally use PyCall - already exists, OdsIO).
Before attempting to replicate the following code, please be sure that the ezodf module is available to the Python environment you are using in Julia. If this is an independent environment, just follow the Python way to install packages (e.g. with pip). If you are using the "private" Conda environment, you can use the Conda.jl package and type using Conda; Conda.add_channel("conda-forge"); Conda.add("ezodf").
const ez = pyimport("ezodf") # Equiv. of Python `import ezodf as ez`
destDoc = ez.newdoc(doctype="ods", filename="anOdsSheet.ods")
sheet = ez.Sheet("Sheet1", size=(10, 10))
destDoc.sheets.append(sheet)
dcell1 = get(sheet,(2,3)) # Equiv. of Python `dcell1 = sheet[(2,3)]`. This is cell "D3" !
dcell1.set_value("Hello")
get(sheet,"A9").set_value(10.5) # Equiv. of Python `sheet['A9'].set_value(10.5)`
destDoc.backup = false
destDoc.save()
The usage in Julia of the module follows the Python API with few syntax differences.
The module is imported and assigned to a shorter alias, ez.
We can then directly call its functions with the usual Python syntax module.function().
The doc object returned by newdoc is a generic PyObject type. We can then access its attributes and methods with myPyObject.attribute and myPyObject.method() respectively.
In the cases where we can't directly access some indicized values, like sheet[(2,3)] (where the index is a tuple) we can invoke instead the get(object,key) function. +
Finally, note again that index conversion is not automatically implemented: when asking for get(sheet,(2,3)) these are interpreted as Python-based indexes, and cell D3 of the spreadsheet is returned, not B2.
I guess Foreign Funcall Interface is what you're looking for. Here is the example for Julia. More info in PyCall.jl repository.
Can anyone give me an idea about how to call Matlab function from python script using pymatlab?
Matlab, pymatlab and python are already properly installed.
I tried to run some Matlab commands from here on python script and everything works fine. But I have no idea regarding calling Matlab function from python.
For example, I have a Matlab function which will receive a string as argument and will display it and return it, like below.
function [ name ] = print_Name(first_Name)
name=first_Name;
end
Thanks in advance for your kind suggestion.
You need to first initialize a MATLAB session
import pymatlab
session = pymatlab.session_factory()
Then you can use the run method to call any MATLAB function that you wish
session.run("print_Name('name')")
Or you could assign a value in the workspace and use that
name = 'My Name'
session.putValue('name', name)
session.run('print_Name(name)')
If you want to get a value back, you can always assign the output of print_Name to a variable and call session.getValue to get that back into Python
session.run('output = print_Name(name)')
result = session.getValue('output')
That being said, I would highly recommend using The Mathwork's own library for interacting with MATLAB from Python.
I have written a python code, which takes 3 inputs, and return one output val.
I try to write an excel function, which passes the three inputs to the python function and returns the output.
I have looked into XLwings, but there is so many issues (and the documentation is insanely poor/poorly written) thus it seems useless.
So: is there any other way to call a python function (which takes inputs) from excel?
[SOLVED (ish):]
I managed, after roughly 8 hours of trying, 4 youtube videos and the xlwings homepage, to make it work.
Video for installing: https://training.zoomeranalytics.com/courses/xlwings/lectures/4231276
Video for making a function which takes input and returns output: https://www.youtube.com/watch?v=qn8xGrDuRCg&t=16s
You could try xlOil (disclaimer: I wrote it). The docs are here, but to write a simple three input function, you would install xlOil using:
pip install xloil
xloil install
Then write:
import xloil
#xloil.func
def myfunc(x, y, z):
return x + y * z
Put this code either:
In a py file in the same directory as your spreadsheet, named SpreadsheetName.py
In a py file on your python module path, then edit %APPDATA%\xlOil\xlOil.ini to load it as described in the docs.
Start Excel, open your spreadsheet and the function will be available as myfunc.
You could also try xlSlim (disclaimer I wrote it). The docs are here.
Installation is as simple as downloading and running a Windows installer from here The process is described in the docs and there is a YouTube video https://youtu.be/Zl5QM8rGBC8 It is straightforward, just download and run the installer. The installer is digitally signed and virus scanned.
Then to create the same function as Steve's you would write your function in a Python module:
def myfunc(x,y,z):
return x + y + z
(Note how no changes were made for the function work with xlSlim - this is a defining feature of xlSlim, no decorators or additional Python packages are required.)
Then in Excel use the RegisterPyModule() function to register the module (assuming you saved the module as mymod.py)
=RegisterPyModule("C:\Users\russe\Documents\mymod.py")
The function is now available for use within Excel as myfunc. Any type hints and doc strings are also processed.
I want to pass a constant in a C preprocessor style but with a Python script.
This constant is already declared with AC_DEFINE in my configure.ac file and used in my C program, and now I need to pass it to a Python script too.
I tried with a custom target in my Makefile.am with a sed call to preprocess a specific symbol in my Python script, but it seems dirty-coding to me.
How can I achieve this?
Create a config.py.in with some contents like MYVAR = '''#MYVAR#''' and add it to AC_CONFIG_FILES in your configure.ac. You can then import config in your other Python scripts.
This fulfills much the same function as config.h does for C programs.
Please excuse what I know is an incredibly basic question that I have nevertheless been unable to resolve on my own.
I'm trying to switch over my data analysis from Matlab to Python, and I'm struggling with something very basic: in Matlab, I write a function in the editor, and to use that function I simply call it from the command line, or within other functions. The function that I compose in the matlab editor is given a name at the function definition line, and it's generally best for the function name to match the .m file name to avoid confusion.
I don't understand how functions differ in Python, because I have not been successful translating the same approach there.
For instance, if I write a function in the Python editor (I'm using Python 2.7 and Spyder), simply saving the .py file and calling it by its name from the Python terminal does not work. I get a "function not defined" error. However, if I execute the function within Spyder's editor (using the "run file" button), not only does the code execute properly, from that point on the function is also call-able directly from the terminal.
So...what am I doing wrong? I fully appreciate that using Python isn't going to be identical to Matlab in every way, but it seems that what I'm trying to do isn't unreasonable. I simply want to be able to write functions and call them from the python command line, without having to run each and every one through the editor first. I'm sure my mistake here must be very simple, yet doing quite a lot of reading online hasn't led me to an answer.
Thanks for any information!
If you want to use functions defined in a particular file in Python you need to "import" that file first. This is similar to running the code in that file. Matlab doesn't require you to do this because it searches for files with a matching name and automagically reads in the code for you.
For example,
myFunction.py is a file containing
def myAdd(a, b):
return a + b
In order to access this function from the Python command line or another file I would type
from myFunction import myAdd
And then during this session I can type
myAdd(1, 2)
There are a couple of ways of using import, see here.
You need to a check for __main__ to your python script
def myFunction():
pass
if __name__ == "__main__":
myFunction()
then you can run your script from terminal like this
python myscript.py
Also if your function is in another file you need to import it
from myFunctions import myFunction
myFunction()
Python doesn't have MATLAB's "one function per file" limitation. You can have as many functions as you want in a given file, and all of them can be accessed from the command line or from other functions.
Python also doesn't follow MATLAB's practice of always automatically making every function it can find usable all the time, which tends to lead to function name collisions (two functions with the same name).
Instead, Python uses the concept of a "module". A module is just a file (your .py file). That file can have zero or more functions, zero or more variables, and zero or more classes. When you want to use something from that file, you just import it.
So say you have a file 'mystuff.py':
X = 1
Y = 2
def myfunc1(a, b):
do_something
def myfunc2(c, d):
do_something
And you want to use it, you can just type import mystuff. You can then access any of the variables or functions in mystuff. To call myfunc2, you can just do mystuff.myfunc2(z, w).
What basically happens is that when you type import mystuff, it just executes the code in the file, and makes all the variables that result available from mystuff.<varname>, where <varname> is the name of the variable. Unlike in MATLAB, Python functions are treated like any other variable, so they can be accessed just like any other variable. The same is true with classes.
There are other ways to import, too, such as from mystuff import myfunc.
You run python programs by running them with
python program.py