Chapter 8. Interaction with Other Languages

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:

  • A brief discussion on how Python can be used to run codes from Fortran, C/C++, and MATLAB/Octave
  • We will first see the basic functionality of the utility f2py to handle the inclusion of Fortran codes in Python via SciPy
  • A basic usage to include C/C++ code within Python code using the tools provided by the the scipy.weave module

The routines will be illustrated via simple examples that can be enriched by you modifying the IPython Notebook corresponding to this chapter.

Interaction with Fortran

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:

  • Removal of all allocations
  • Transformation of the whole program into a subroutine
  • If anything special needs to be passed to 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)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.69