We often need to incorporate into our workflow some code written in different languages; mostly C/C++ or Fortran, and also from R, MATLAB, or Octave. Python excels at allowing code from all these other sources to run from within; care must be taken to convert different numerical types to something that Python understands, but this is pretty much the only issue we encounter.
If you are working with SciPy, it is because your Python ecosystem has available compilers for C and Fortran programs. Otherwise, SciPy could have not been installed on your system. Also, given its popularity, it is highly probably that your computer environment has MATLAB/Octave available. Accordingly, this has driven the selection of topics listed later in this chapter. We left to the interested reader to find out how interface with R and many other software is available out there for numerical computing. Two alternatives to do that with R are the packages PypeR (http://bioinfo.ihb.ac.cn/softwares/PypeR/) and rpy2 (http://rpy.sourceforge.net/). Additional alternatives can be found at http://stackoverflow.com/questions/11716923/python-interface-for-r-programming-language.
In this chapter, we will cover the following things:
f2py
to handle the inclusion of Fortran codes in Python via SciPyscipy.weav
e
moduleThe routines will be illustrated via simple examples that can be enriched by you modifying the IPython Notebook corresponding to this chapter.
SciPy provides a simple way of including Fortran code—f2py
. This is a utility shipped with the NumPy libraries, which is operative when distutils
from SciPy are available. This is always the case when we install SciPy.
The f2py
utility is supposed to run outside Python, and it is used to create from any Fortran file a Python module that can be easily called in our sessions. Under any *nix
system, we call it from the terminal. Under Windows, we recommend you run it in the native terminal, or even better, through a cygwin
session.
Before being compiled with f2py
, any Fortran code needs to undergo three basic changes, which are as follows:
f2py
, we must add it with the comment string "!f2py"
or "cf2py"
Let's illustrate the process with a simple example. The following naive subroutine, which we store in the primefactors.f90
file, performs a factorization in prime numbers for any given integer:
SUBROUTINE PRIMEFACTORS(num, factors, f) IMPLICIT NONE INTEGER, INTENT(IN) :: num !input number INTEGER,INTENT(OUT), DIMENSION((num/2))::factors INTEGER, INTENT(INOUT) :: f INTEGER :: i, n i = 2 f = 1 n = num DO IF (MOD(n,i) == 0) THEN factors(f) = i f = f+1 n = n/i ELSE i = i+1 END IF IF (n == 1) THEN f = f-1 EXIT END IF END DO
Since no allocation was made in the code, and we receive a subroutine directly, we may skip to the third step, but for the moment we will not tamper with f2py
commands, and are content with trying to create a python module from it. The fastest way to wrap this primefactors
subroutine is by issuing the following command (at the shell or terminal prompt indicated by %
):
% f2py –c primefactors.f90 –m primefactors
If everything is correct, an extension module with the name primefactors.so
is created. We can then access the primefactors
routine in Python from the primefactors
module:
>>> import primefactors >>> primefactors.primefactors(6,1)
The output is shown as follows:
array([2, 3, 0], dtype=int32)
18.223.206.69