#acl AdminGroup:read,write,delete,revert EditorGroup:read,write,delete,revert All:read #format wiki #language en #pragma section-numbers off <> = Python as a glue = Python is often considered as a glue to combine different programming languages under one hood. Why should one combine different languages? There are some good reasons if there are existing libraries that should be combined or to increase the performance. Python is relatively fast if compared to Matlab or IDL but Fortran code can be much faster. However, before spending time in optimization one should think if it is [[http://www.acm.org/ubiquity/views/v7i24_fallacy.html|really necessary]]. The normal Python interpreter, or sometimes called cPython, is build in the C programming language. Python can be extended with C-routines and Python objects can be called from C. See http://docs.python.org/c-api/ for more information. The [[http://wiki.python.org/jython/|Jython]] interpreter is a Java version of Python which allows interactive and dynamic Java programming. = Using Fortran Subroutines in Python = The Fortran programming language is more than 50 years old. The first version was developed during the years 1954-1957. At this time it was a revolutionary product. Since then many new ideas have been introduced in programming languages such as the object oriented concept. Fortran has inherited some of these new concepts and allows also object orientation approaches in its newest version. However, not all compilers support such features and the standardization is not finished yet. Moreover, existing code with its origins based on Fortran 77 or Fortran 90 is not using these features. Thus, is difficult to maintain very complex applications in Fortran such as climate models. Therefore, Python can be used for refactoring some components, for example the [[http://code.google.com/p/pyccsm/| Community Climate System Model (CCSM) Coupler]]. There are different reasons why one should combine Python and Fortran * Fortran is fast, Python is relatively slow. Fortran subroutines can be used for speed optimization in Python * Python is preferable for advanced software design, interactivity, graphical user interfaces, protocols (XML) == F2PY: Fortran to Python interface generator == Calling Fortran code from python is easy! Create a file {{{hello.f}}}: {{{ C File hello.f subroutine foo (a) integer a print*, "Hello from Fortran!" print*, "a=",a end }}} Run {{{f2py -c -m hello hello.f}}} Now in IPython try: {{{ In [1]: import hello In [2]: hello.foo(4) Hello from Fortran! a= 4 }}} Example taken from * [[http://cens.ioc.ee/projects/f2py2e/|F2PY: Fortran to Python interface generator]] == More examples == === Scalar function === sub1.f95 {{{ REAL function sub1(x,y) REAL :: x,y sub1=0.5*(x+y) return end }}} sub1.py {{{#!python import os os.system('rm sub1.o') os.system('f2py --fcompiler=gnu95 -m sub1 -c ./sub1.f95') from sub1 import sub1 x,y,z=3.0,2.0,0.0 z=sub1(x,y) print x,y,z }}} {{{ run sub1 3.0 2.0 2.5 }}} The parameters {{{x,y}}} are not changed. The result ({{{sub1}}}) is returned. === In/Out === {{{ subroutine sub2(x,y) REAL, intent(in) :: x REAL, intent(out) :: y y=x+1 return end }}} {{{#!python import os os.system('rm sub2.o') os.system('f2py --fcompiler=gnu95 -m sub2 -c ./sub2.f95') from sub2 import sub2 x,y=1,0 y=sub2(x) print x,y }}} === Arrays === The following example shows how to pass an array of arbitrary size to a Fortran subroutine. {{{ subroutine sub6(x,n) IMPLICIT NONE INTEGER :: i INTEGER, intent(in) :: n REAL*8, intent(inout) :: x(0:n-1,0:1) do i=0,n-1 x(i,0)=REAL(i) x(i,1)=n-REAL(i) enddo return end }}} {{{#!python import os os.system('rm sub6.so') # Comment out for rebuilding Fortran module if not(os.path.exists('sub6.so')): os.system('f2py --fcompiler=gnu95 -m sub6 -c ./sub6.f95 ') from sub6 import sub6 from pylab import * n=10 x=zeros((n,2),dtype=float,order='Fortran') sub6(x,n) print x }}}