[Numpy-discussion] f2py: generic,public/private procedure

David Froger david.froger@gmail....
Fri Sep 10 09:30:33 CDT 2010


Hy all,

As a test case before writing something bigger, I'm trying to write a little
Fortran module to compute the average of a array in these 4 cases:

avg2d_float, avg2d_double
avg3d_float, avg3d_double

I want this module to be callable from both Fortran and Python, using f2py.
4 Fortran functions have to be written, and a generic Fortran function 'avg'
overloads its.

The Fortran module 'stat.f90' (containing the functions), a Fortran program
'stat_example.f90' and a Python script 'stat_example.py' are at the end of
the email.

(everything works fine: the compilation, f2py, the execution in Python and
in Fortran.)

My questions are:

- Assumed shape array are not supported by f2py. However, it is much more
handy to write in Fortran 'avg(array)' than 'avg(array,n1,n2,n3)'. Would it
be possible to supported it by modifying the signature files?

- Is there a way to avoid to write by hand the 'avg' Python function (in
example_stat.py) ?

- Isn't there no way to declare private the functions: avg2d_float,
avg2d_double, avg3d_float,avg3d_double? It's embarassing its are visible
from stat_example.f90.

Uncommenting the lines in the top of the file stat.f90:
    !private
    !public:: avg

and running:
    f2py -m f90stat -c stat.f90

give the error:
    use stat, only : avg2d_float
    Error: Symbol 'avg2d_float' referenced at (1) not found in module 'stat'

Thanks for any suggestion,

David


* to create the Fortran executable:
gfortran -c stat.f90
gfortran -c stat_example.f90
gfortran -o stat_example.x stat.o stat_example.o

* to create the Python module:
f2py -m f90stat -c stat.f90

* The Fortran module is:

"""
!file stat.f90
module stat

implicit none
!private
!public:: avg

interface avg
    module procedure avg2d_float, avg2d_double, avg3d_float, avg3d_double
end interface

contains

function avg2d_float(array,n1,n2) result(average)

    implicit none

    real(kind=4):: average

    integer:: n1,n2
    real(kind=4),dimension(n1,n2),intent(in):: array

    average = sum(array)

    average = average / n1
    average = average / n2
end function avg2d_float

function avg2d_double(array,n1,n2) result(average)

    implicit none

    real(kind=8):: average

    integer:: n1,n2
    real(kind=8),dimension(n1,n2),intent(in):: array

    average = sum(array)

    average = average / n1
    average = average / n2

end function avg2d_double

function avg3d_float(array,n1,n2,n3) result(average)

    implicit none
    real(kind=4):: average

    integer:: n1,n2,n3
    real(kind=4),dimension(n1,n2,n3),intent(in):: array

    average = sum(array)

    average = average / n1
    average = average / n2
    average = average / n3

end function avg3d_float

function avg3d_double(array,n1,n2,n3) result(average)

    implicit none

    real(kind=8):: average

    integer:: n1,n2,n3
    real(kind=8),dimension(n1,n2,n3),intent(in):: array

    average = sum(array)

    average = average / n1
    average = average / n2
    average = average / n3

end function avg3d_double

end module stat
"""

* The Fortran program is:

"""
!file: stat_example.f90
program stat_example

use stat
implicit none

integer,parameter:: n1=10,n2=10,n3=10
real(kind=4),dimension(n1,n2):: array2d_float
real(kind=8),dimension(n1,n2):: array2d_double

real(kind=4),dimension(n1,n2,n3):: array3d_float
real(kind=8),dimension(n1,n2,n3):: array3d_double

array2d_float = 4.
array2d_double = 4.

array3d_float = 4.
array3d_double = 4.

write(*,*) avg(array2d_float,n1,n2)
write(*,*) avg(array2d_double,n1,n2)

write(*,*) avg(array3d_float,n1,n2,n3)
write(*,*) avg(array3d_double,n1,n2,n3)

write(*,*) avg2d_float(array2d_float,n1,n2)

end program stat_example
"""

* The Python script is:

"""
#!/usr/bin/env python

#file stat_example.py

import numpy as np
import f90stat

def avg(a):

    if a.ndim == 2:
        if a.dtype == 'float32':
            return f90stat.stat.avg2d_float(a)

        elif a.dtype == 'float64' :
            return f90stat.stat.avg2d_double(a)

        else:
            raise ValueError, 'dtype = %r unsupported.' % (a.dtype)

    elif a.ndim == 3:
        if a.dtype == 'float32':
            return f90stat.stat.avg3d_float(a)

        elif a.dtype == 'float64' :
            return f90stat.stat.avg3d_double(a)

        else:
            raise ValueError, 'dtype = %r unsupported.' % (a.dtype)

    else:
        raise ValueError, 'ndim = %r unsupported.' % (a.ndim)

if __name__ == '__main__':

    a = np.arange(6.)
    a = a.reshape(2,3)

    print avg(a)
"""
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20100910/710214a5/attachment.html 


More information about the NumPy-Discussion mailing list