[SciPy-dev] genetic algorithm, number theory, filterdesign,zerofinding

pearu at scipy.org pearu at scipy.org
Thu Apr 11 16:21:32 EDT 2002


On Thu, 11 Apr 2002, Chuck Harris wrote:

> > > Hmm... f2py handles this?
> > 
> > Yes, it does (cblas,clapack are wrapped with f2py, for example). The
> > signature files may look Fortran but there is actually only little
> > difference in wrapping Fortran or C functions. And there are some  
> > additional hooks available for the signature files that ease 
> > overcoming
> 
> Signature file?

Basically, f2py can read Fortran sources and extract from them relevant
information (arguments, types, etc.) that are needed for calling Fortran
functions from C (or from Python as in the final layer). This information
(the signatures of functions) is saved in the so-called signature files or
.pyf files using Fortran 90 syntax (take a look at some .pyf files in
SciPy tree).

For C functions, one has to create these signature files manually taking
into account the correspondance between C and Fortran types
(e.g. Fortran real*8 is C double, etc). 

And f2py constructs a Python extension module based on the information in
signature files. If requested it can compile and build it all in one
call.

> > these small differences (intent(c), fortranname, callstatement,
> > callprotoargument etc. statements).
> > Of course, I am assuming that C functions do not use 
> > complicated struct's,
> > except the complex one.
> 
> Root finders are pretty basic. Looks like the standard call for all of
> them would be:
> 
> solve(f,a,b,args=(),xtol=default,maxiter=default)
> 
> with a (python) float return. a,b,xtol should be double, or converted
> to double. maxiter is integer, and f returns double to the C routine.
> 
> There is a disagreement between say, fsolve and bisection, where one
> has the named argument xtol, and the other tol. How should this be
> resolved?

If the meaning is the same, we should stick to the same name.
I would prefer tol.

> I could probably just look at the wrapper for fsolve and make a few
> changes, eh?

Wrapper of hybrd is pretty complicated because the Fortran function
hybrd is complicated.

In your case you can just write a normal C function, say

double solve((void*)() f,double a,double b,double xtol,int maxiter) {
 /* do your stuff here */
}

and the corrsponding Fortran signature looks like the following

function solve(f,a,b,xtol,maxiter) result (x)
  external f
  double precision f,solve
  fortranname solve
  intent(c) solve
  double precision intent(in,c) :: a,b
  double precision intent(in,c),optional :: xtol = 1e-12
  integer intent(in,c),optional :: maxiter = 100
end function solve

and the Python signature of the wrapper function that f2py generates looks
like the following

def solve(f,a,b,xtol=1e-12,maxiter=100):
    # do your stuff here

If the Fortran signature is saved in a file foo.pyf and C function is
saved in a file foo.c, then calling

  f2py -c foo.pyf foo.c -m bar

will construct and build extension module bar.so into the current
directory. And you can do, for example

>>> import bar
>>> bar.solve(lambda x:1-x**2,0,2)
1.0

Be warned that I skipped some details like extra arguments and
callback functions and there may be minor typos, but the purpose was to
give a quick and general overview of how you can wrap C functions with
f2py.

Pearu






More information about the SciPy-Dev mailing list