Using Matlab functions in Python [duplicate] - python

Is it possible to run MATLAB functions from within Python?
I search the internet, I could only find PyMat. The bad thing is the compiled version only supports Python2.2 and I am using 2.6. So I tried to download the source code, so I can compile it for myself. But I cannot compile it, VC++ express seems not to have the necessary functionalities to compile it. Does anyone have the compile version for PC?
or any substitutes for PyMat?
Thanks

I know this is an old question and has been answered. But I was looking for the same thing (for the Mac) and found that there are quite a few options with different methods of interacting with matlab and different levels of maturity. Here's what I found:
pymat
A low level interface to Matlab using the matlab engine (libeng) for communication (basically a library that comes with matlab). The module has to be compiled and linked with libeng.
http://pymat.sourceforge.net
Last updated: 2003
pymat2
A somewhat short lived continuation of the pymat development. Seems to work on windows (including 64bit), linux and mac (with some changes).
https://code.google.com/p/pymat2/
Last updated: 2012
mlabwrap
A high level interface that also comes as a module which needs compilation and linking against libeng. It exposes Matlab functions to python so you can do fun stuff like
mlab.plot(x, y, 'o')
http://mlabwrap.sourceforge.net
Last updated: 2009
mlab
A repackaging effort of mlabwrap. Basically it replaces the c++ code that links against 'libeng' in mlabwrap with a python module (matlabpipe) that communicates with matlab through a pipe. The main advantage of this is that it doesn't need compilation of any kind.
Unfortunately the package currently has a couple of bugs and doesn't seem to work on the mac at all. I reported a few of them but gave up eventually. Also, be prepared for lots of trickery and a bunch of pretty ugly hacks if you have to go into the source code ;-) If this becomes more mature it could be one of the best options.
https://github.com/ewiger/mlab
last update: 2013
pymatlab
A newer package (2010) that also interacts with Matlab through libeng. Unlike the other packages this one loads the engine library through ctypes thus no compilation required. Its not without flaws but still being maintained and the (64bit Mac specific) issues I found should be easy enough to fix.
(edit 2014-05-20: it seems those issues have already been fixed in the source so things should be fine with 0.2.4)
http://pymatlab.sourceforge.net
last update: 2014
python-matlab-bridge
Also a newer package that is still actively maintained. Communicates with Matlab through some sort of socket. Unfortunately the exposed functions are a bit limited. I couldn't figure out how to invoke a function that takes structs as parameters. Requires zmq, pyzmq and IPython which are easy enough to install.
http://arokem.github.io/python-matlab-bridge
last update: 2014

Another option is Mlabwrap:
Mlabwrap is a high-level python to Matlab® bridge that lets Matlab look like a normal python library.
It works well with numpy arrays. An example from the home page:
>>> from mlabwrap import mlab; from numpy import *
>>> xx = arange(-2*pi, 2*pi, 0.2)
>>> mlab.surf(subtract.outer(sin(xx),cos(xx)))

PyMat looks like it's been abandoned.
I'm assuming you are on windows so you could always do the simplest approach and use Matlab's COM interface:
>>> import win32com.client
>>> h = win32com.client.Dispatch('matlab.application')
>>> h.Execute ("plot([0 18], [7 23])")
>>> h.Execute ("1+1")
u'\nans =\n\n 2\n\n'
More info here

There is a python-matlab bridge which is unique in the sense that Matlab runs in the background so you don't have the startup cost each time you call a Matlab function.
https://github.com/jaderberg/python-matlab-bridge
it's as easy as downloading and the following code:
from pymatbridge import Matlab
mlab = Matlab(matlab='/Applications/MATLAB_R2011a.app/bin/matlab')
mlab.start()
res = mlab.run('path/to/yourfunc.m', {'arg1': 3, 'arg2': 5})
print res['result']
where the contents of yourfunc.m would be something like this:
%% MATLAB
function lol = yourfunc(args)
arg1 = args.arg1;
arg2 = args.arg2;
lol = arg1 + arg2;
end

see this page: An Open-Source MATLAB®-to-Python® Compiler

I would like to add one more option to the excellent summary by Lukas:
matlab_wrapper
The advantage of matlab_wrapper is that it is pure Python library and you will not need to compile anything. Works in GNU/Linux, Windows and OSX.
https://github.com/mrkrd/matlab_wrapper
Disclaimer: I'm the author of matlab_wrapper

You can use the official matlab engine by installing Matlab, then building python engine from its extern files. You can check the guide website below:
---Thanks for the advice in the first comment of this answer ---
the essential step in brief are (On Windows platform, other can checked in the url below):
1. download and then install matlab, the version must be R2014 or later.
2. open a PowerShell window under admin, then:
cd "matlabroot\extern\engines\python"
3. use command-line below to install:
python setup.py install
The admin is essential, or you'll fail to build it.
For more information, you can click the official start sheet below:
http://cn.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html

newer versions of matlab seem to provide a module that allows you to call matlab functions from within python. see here and here.

2 more options for you to consider:
Follow the official MATLAB docs:
Create a Python Application with MATLAB Code. This will create a Python library that includes MATLAB runtime which you can call from within your Python code.
Run your MATLAB code in GNU Octave then call it from Python using Oct2Py

This is the solution from Mathworks.
In your current folder, create a MATLAB script in a file named triarea.m.
function a = triarea(b,h)
a = 0.5*(b.* h);
Meanwhile, you run the python code as follows,
import matlab.engine
eng = matlab.engine.start_matlab()
eng.addpath('your/code/folders/')
ret = eng.triarea(1.0,5.0)
print(ret)
>>> 2.5
Matlab already provides the python module of the engine, to install that you can do the following,
cd matlab_root_folder/extern/engines/python
python setup.py install
You are all done!
Tips: you need to be careful about the data type, the engine is not friendly with numpy. You need to convert the data first.
mat_array = matlab.double(list(my_numpy_array))
eng.my_matlabe_function(mat_array )

Related

Running .jl file from R or Python

I am new to Julia. I developed a few lines of code to get the results I needed from packages I was not able to find in Python or R. Now, I am trying to get this file to be easily accessible, and wrap the code in Python or R. Has anyone done this before? I have tried a few methods and have not found anything that has helped.
The most simple way to do this would be just a few lines of code that calls the .jl file, runs it (which the code is then added to a .txt file from julia), and then alerts you when the code is done.
Any help would be greatly appreciated. R is the preferable method and at this point Python would be appreciated as well.
Please find below instructions for Python, R and just an external process (which of course is an executable command that can be run from any other process). I recommend putting your code in a package and loading it in one of those languages rather than executing this as an external process.
Python
Use Python Anaconda (not in-built system Python) and install Julia
Run Julia and install PyCall
using Pkg
ENV["PYTHON"]="/path/to/your/python/executable"
pkg"add PyCall"
pkg"build PyCall"
Put your code into a Julia package
using Pkg
Pkg.generate("MyPackage")
In the folder src you will find MyPackage.jl, edit it to look like this:
module MyPackage
function main(x,y)
#do very complex staff or place it in your_other_file.jl
2x.+y
end
include("your_other_file.jl")
export main, and_whatever_other_functio_you_defined
end
Install pyjulia
python -m pip install julia
(On Linux systems you might want to use python3 instead of python command)
For this step note that while an external Python can be used with Julia. However, for a convenience it might be worth
to consider using a Python that got installed together with Julia as PyCall.
In that case for installation use a command such this one:
%HOMEPATH%\.julia\conda\3\python -m pip install julia
or on Linux
~/.julia/conda/3/python -m pip install julia
Note that if you have JULIA_DEPOT_PATH variable defined you can replace %HOMEPATH%\.julia or ~/.julia/ with its value.
Run the appropiate Python and tell it to configure the Python-Julia integration:
import julia
julia.install()
Now you are ready to call your Julia code:
>>> from julia import Pkg
>>> Pkg.activate(".\\MyPackage") #use the correct path
Activating environment at `MyPackage\Project.toml`
>>> from julia import MyPackage
>>> MyPackage.main([1,2],5)
[7,9]
Gnu R
Configure your system PATH variable to point to your Julia location. Hence when you type julia in the console it should start Julia
Run the script below to install R-Julia integration
install.packages("JuliaCall")
library(JuliaCall)
julia <- julia_setup()
Follow the above instructions for Python (step 3 only) and create the package named MyPackage
Run the code
library(JuliaCall)
julia_eval("using Pkg;Pkg.activate(\"C:/temp/rrr/MyPackage\")")
julia_library("MyPackage")
julia_eval("MyPackage.main(3,5)")
Bash (or just any language)
Build the package following instructions for Python (step 3 only)
Configure the system PATH variable
Being in the package directory run the command (note string(:.) is a Julian trick that I use to avoid apostrophe escaping in bash commands):
julia -e "using Pkg;Pkg.activate(string(:.));Pkg.instantiate();using MyPackage;MyPackage.main(3,4)"
This will install all dependencies for your package. In order to skip the installation remove Pkg.instantiate() from the above command.
The answer from #przemyslaw-szufel is correct but maybe a bit overcomplicated. You don't necessarily need to wrap your code in a module or define a custom environment (yes it is good practice, but a step at the time...)
First create a file juliaScripts.jl with content:
function getAnElement(array,n)
return array[n]
end
To run functions defined in a .jl file in R
Then in R you just do:
> install.packages("JuliaCall")
> library(JuliaCall)
> julia_setup() # on every new R session !
> julia_source("juliaScript.jl")
> out <- julia_call("getAnElement",c(10,20,30),2)
> out
[1] 20
Note that the R vector has been automatically converted to a Julia Array.
To run functions defined in a .jl file in Python
In Python, it is even easier:
$ python3 -m pip install --user julia
>>> import julia
>>> julia.install() # only once, not every session
>>> jl=julia.Julia(compiled_modules=False)
>>> from julia import Main
>>> Main.include("juliaScript.jl")
>>> Main.getAnElement([1,2,3],2)
20
Also in Python arrays (native python lists as well Numpy arrays and other commonly used data structures) are automatically converted between Python and Julia.
Not to make advertising, but more details on interfacing R <-> Julia or Python <-> Julia are on my Apress(2019) book "Julia Quick Syntax reference" in Chapter 7 "Interfacing Julia with other languages" (I shouldn't say it, but you can easily find the pdf online in well-known sites...)
Using the JuliaConnectoR package:
library(JuliaConnectoR)
fun <- juliaCall("include", "/path/to/file.jl") # you may need to provide the full path
For more info on JuliaConnectoR, see the link above as well as this paper, which additionally compares it to alternative packages suck as JuliaCall and XRJulia.

J meter with Python : how to import the packages

Iam new bee to the jmeter
My code is working in the Python 2.7 with importing additional packages Dateutil, parser .
Problme : But when I am trying to run same code in the J Meter-JSR-223 PreProcessors , an error saying No module named dateutil in.
So , I have tried another approach to use Jython .
Installed the Jython ( downloaded the dateutil) and provide the packages reference under
import sys
sys.path.append('C:/Jython27/Lib/site-packages')
sys.path.append('C:/Jython27/Lib/site-packages/python_dateutil-2.4.2-py2.7/dateutil')
sys.path.append('C:/Jython27/Lib/site-packages/python_dateutil-2.4.2-py2.7/dateutil')
Now packages error is gone but string syntax error is present .
java.sql.Date' object has no attribute .
I believe dateutil package can be picked up from CPython as it doesn't require any extra wrappers for Java.
Install dateutil normally using pip like:
pip install python-dateutil
Add site-packages folder of Python (not Jython) installation to sys.path like:
sys.path.append("C:\Python27\Lib\site-packages")
That's it, now you should be able to use dateutil module functions from the JSR223 Test Elements:
Be aware that invoking Python scripts via Jython interpreter is not the best idea from performance perspective and if you're about to invoke your Python code only limited number of times and/or with a single thread - it might be better to go for the OS Process Sampler.
If you plan to use the Python code to create the main load - consider using Locust tool instead of JMeter. If you don't want to change JMeter a good approach would be rewriting your Python code in Groovy - it will be way better from the performance perspective.
hi please find follwing
import sys
sys.path.append('C:/Python27/Lib/site-packages')
sys.path.append('C:/Python27/Lib/site-packages/python_dateutil-2.4.2-py2.7/dateutil')
from dateutil.parser import *
sourceDateTimeOfEvent = ""
dateTimeOfEvent = ""
a=parse('2016-07-01 13:00:00')
sourceDateTimeOfEvent = a.isoformat()+"+05:30Z"
dateTimeOfEvent = a.isoformat()+ "Z"
vars.put("sourceDateTimeOfEvent", sourceDateTimeOfEvent)
vars.put("dateTimeOfEvent", dateTimeOfEvent)
This sourceDateTimeOfEvent and dateTimeOfEvent considered as two variables and passed it to the json file

matplotlib graphs in SPSS

Is it possible to use any other graphing library in SPSS that the built in? I just discovered the python extensions that makes SPSS great.
import matplotlib.pyplot as plt
from numpy.random import rand
fig, ax = plt.subplots()
for color in ['red', 'green', 'blue']:
n = 750
x, y = rand(2, n)
scale = 200.0 * rand(n)
ax.scatter(x, y, c=color, s=scale, label=color,
alpha=0.3, edgecolors='none')
ax.legend()
ax.grid(True)
plt.show()
This will create a simple scatter plot and it works fine in any IDE, but when trying to use that code in SPSS BEGIN PROGRAM END PROGRAM i get the following error:
RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X.
Please either reinstall Python as a framework, or try one of the other backends. If you are Working with Matplotlib in a virtual enviroment see 'Working with Matplotlib in Virtual environments' in the Matplotlib FAQ
Maybe I am asking too much out of the python extension in SPSS but it would be nice to use another graph library than the one they have built in.
Adding more information as another answer as the comment field is too limited.
I do not get the framework error on Windows, which is a different issue, I think. But running your code inside Statistics works - sort of. Instead of placing the image in the Viewer, it pops up in its own window (which may be buried behind another window).
So Statistics doesn't know about it and patiently waits for the program to complete, which doesn't happen until you dismiss that window (which does have a normal frame not shown in the graphic).
To make this work, you would need to direct the matplotlib code to write the image to a file somewhere and then use SpssClient apis to insert that image in the Viewer. See CreateImageChartItem Method (Python) in the Python programmability help. Alternatively, if you can direct matplotlib to write the image to the standard output stream, Statistics might be able to capture it directly in the Viewer.
I usually do programmability images with R code (even though Python is a way better language(!)), where this all works seamlessly. Or I use Python code to write Statistics graphics commands and GPL to have the Statistics engine, which is pretty powerful, do the charting.
Another thing you mind find helpful if you are into Python, is that you can run Python in external mode, where you start with Python code running from your IDE or a Python command line and then have it invoke Statistics by running
import spss
This has great advantages for developing and debugging Python code, but you can't use the SpssClient module methods directly. I ran your code from my IDE (Wing Professional), and the image window popped right up. And, of course, you can use the spss module and related apis in external mode to communicate with Statistics and control it.
You can use just about any Python code or library, but you need to do some configuring. When the Python support (Python Essentials) is installed, it installs a private, unregistered Python system in order not to conflict with any other Python that might be installed. So if you try to add other libraries, the installer doesn't know what to do or installs them somewhere that the Statistics installation won't know about.
The easiest way to get around this is to install another, standard Python installation (version 2.7 in recent versions or 3.4 with version 24 if you need Python 3). Then go to Edit > Options > Files and point to that distribution. You will need to restart Statistics for that to take effect. I use the Anaconda distribution, which includes a lot of other goodies.
I'm not a Mac user, but something like this should work.

pexpect: How to interact() over file object using newer version of pexpect library

pexpect has gone through big changes since the version provided by Ubuntu 15.04 (3.2). When installing newest version of pexpect using pip3, this minimal program that previously successfully gave terminal emulation over serial console does not work any more:
#!/usr/bin/python3
import serial
import pexpect.fdpexpect
ser = serial.Serial("/dev/ttyS0", baudrate=115200)
spawn = pexpect.fdpexpect.fdspawn(ser)
spawn.interact()
The newer API is missing interact() method in class pexpect.fdpexpect.fdspawn which used to be there.
Question: how is the newer version of pexpect (currently 4.2.1) supposed to be used to provide free manual interaction with file object (serial port in this case)?
Alternatively, question/work-around: I recognize I am using a bit heavy machinery for such a simple use case, any suggestions for other python libraries that can do the same as earlier version of pexpect could?
Code reading: Examples use pexpect.spawn(command_str) to get a spawn object which has interact() method; actually this pexpect.spawn() is the same as directly creating a pexpect.pty_spawn.spawn object which has this method. On the other hand, pexpect.fdpexpect.fdspawn() will construct a pexpect.fdpexpect.fdspawn class which is missing interact() method. Both of these spawn classes derive from pexpect.spawnbase.SpawnBase class. Based on my quick reading, this looks like regression that resulted from refactoring on the way to version 4.x.
Browsing the pexpect issues, found #351, #356, and the newly submitted #377. By my quick reading, it seems this is a regression that was brought by uncompleted refactoring along the way towards new major release version 4. There are three possible avenues:
Make sure to install older version:
$ pip3 install "pexpect<3"
(or make sure that the version installed by other system is 3.x).
Fix pexpect by yourself.
Use some other python library.
These avenues were all more or less hinted by github user #takluyver, apparently maintainer of pexpect in comment to issue #351:
#jquast any thoughts on what to do for this (and #356)? I feel bad that we've broken things people were doing with fdspawn, but I really don't want to make it inherit from the pty spawn class, and now that it works on Windows, I think it's important to preserve that too.
Maybe we should just say:
If you have legacy code that broke with Pexpect 4, downgrade to Pexpect 3.x (pip install pexpect<4)
If you're writing new code, use streamexpect instead of pexpect.

Python for .NET "unable to find assembly" error

I'm using CPython and I have a C# dll. I'm trying to use Python for .NET to make them talk. I can't use IronPython because I need to integrate this into an existing CPython system.
I'm completely new to Python for .NET, and I actually have very little experience with Python and no experience with C#. So please forgive me if my question seems very basic.
I'm using Python 2.7.3, and I downloaded
pythonnet-2.0-alpha2-clr2.0_131_py27_UCS2 and unzipped it into a folder named pyfornet_test, which also contains the dll I'm trying to use (called DotNet4Class.dll)
Then I run this:
import sys
import os
import clr
sys.path.append(r"C:\pyfornet_test")
clr.AddReference("DotNet4Class.dll")
Which gives me this error:
System.IO.FileNotFoundException: Unable to find assembly 'DotNet4Class.dll'.
at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PyShar
p\trunk\pythonnet\src\runtime\moduleobject.cs:line 375
Any advice would be much appreciated. Thank you!
One reason can be Windows was not enabling it to load from "external sources". To fix this:
Right-click on the .dll
"Properties"
Under "General", click "Unblock"
Try this (without extension .dll):
clr.AddReference(r"C:\pyfornet_test\DotNet4Class")
Is DotNet4Class.dll built against .NET 4? I assume so based on the naming of the dll.
Note the issue here: http://sourceforge.net/tracker/?func=detail&aid=3293169&group_id=162464&atid=823891
clr.AddReference fails when assembly is built with .NET 4.0 - ID: 3293169
I'd read the solution, but essentially, you need to rebuild and recompile the python for .NET project under .NET 4.
I'll also mention that projects like this, that aren't actively developed and used by lots of people, generally have subtle idiosyncrasies that make knowledge of the platform essential to work around problems such as this. It sounds like you're trying to hack this solution in without understanding much about python or .NET which is always going to be fraught with problems.
Did you try clr.FindAssembly?
import clr
import sys
assemblydir = r"C:\pyfornet_test"
assemblypath = r"C:\pyfornet_test\DotNet4Class.dll"
sys.path.append(assemblydir)
clr.FindAssembly(assemblypath)
I don't know why it works, but this code works on my computer (Python 2.7, .NET4)
I have code like this (I copied MyRightClickMenuService.dll to the same directory as my script.py). It is built against .Net 4.0.
# script.py
import clr
import os
import sys
sys.path.append(os.path.dirname(__file__))
clr.AddReference('MyRightClickMenuService')
clr.AddReference('System')
clr.AddReference('System.Security')
from MyRightClickMenuService import (
AclSecuredNamedPipeBinding,
MyMenuItem,
MyContextMenuService,
etc
)
Checklist
The folder(s) containing the DLL(s) is/are added to sys.path before loading. You may append, or sys.path.insert(0, dll_folder) to put it first on the list.
You call clr.AddReference('my_dll') without the dll extension (for my_dll.dll), after adding the folder to sys.path
The DLL Target Architecture is the same as the CPython version bitness. That is, if Architecture is x64, use 64-bit python, and if Architecture is x86, use 32-bit python. (instructions for this below)
How to check target Architecture for DLL?
I Used ILSpy (free and open source) -> Open DLL -> Check the output. Below example output.
What worked for me was to Unblock the dll file.
if u download the dll file or took it from different computer it might be blocked. So unblocked solved the issue for me.
To unblock right click on the properties if the dll file and check the Unblock box at the bottom

Categories