From: glen herrmannsfeldt on
Ron Shepard wrote:
> deltaquattro <deltaquattro(a)gmail.com> wrote:

>>However, the function to be integrated depends on many parameters, not
>>only on x. How can I pass it to quad? Is it better to modify the
>>interface in quad (and all the subroutines called by quad), or to
>>create a module containing func and all the modules needed by it? Have
>>you ever met a similar problem? Thanks

> This is the standard interface problem. Do not modify your quad()
> subroutine. If you do that, then you might as well not even use the
> dummy subroutine, you could just hardwire the call to your specific
> code, eliminating all advantages of having a modular reusable quad()
> routine for numerical integration.

(Snip on the use of COMMON or MODULE to pass static data
between routines.)

Note, though, that neither COMMON or MODULE allows for reentrant
calls. If, for example, one wanted to integrate a function inside
a recursive routine one would have to be very careful.

Even more, some have done double integrals through calling routines
like quad from inside the called function. The Fortran 66 solution
to such problems was more than one copy of quad, each with a different
name. (quad1, quad2, etc.) and more variables in COMMON.

Quoting Richard Maine from a thread on Fortran templates:

"I agree that something like templates can be useful in
some situations. But note that, depending on details,
the particular scenario described above can usually be
handled better in other ways. Typically, all you need
is an equivalent of a C void pointer, along with the data
size. Then you can do it all in a single procedure, with
no need for templates. I've done this exact thing for a
long time, as I also have Fortran code that passes data
via sockets. So have other people. This one is done a lot."

In a method related to the one Richard mentions, quad
could be written to accept a single variable, either a
C void pointer or unlimited polymorphic,
and pass this variable onto the called routine. (Both
requiring Fortran 2003 features that may or may not be
implemented in current compilers.) That would allow passing
any data through in a reentrant manner.

http://en.wikipedia.org/wiki/Reentrant

-- glen

From: Richard Maine on
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

> In a method related to the one Richard mentions, quad
> could be written to accept a single variable, either a
> C void pointer or unlimited polymorphic,
> and pass this variable onto the called routine. (Both
> requiring Fortran 2003 features that may or may not be
> implemented in current compilers.) That would allow passing
> any data through in a reentrant manner.

Thanks for mentioning that. I was thinking about doing so, but you beat
me to it.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: Richard Maine on
Richard Maine <nospam(a)see.signature> wrote:

> glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:
>
> > In a method related to the one Richard mentions, quad
> > could be written to accept a single variable, either a
> > C void pointer or unlimited polymorphic,
> > and pass this variable onto the called routine. (Both
> > requiring Fortran 2003 features that may or may not be
> > implemented in current compilers.) That would allow passing
> > any data through in a reentrant manner.
>
> Thanks for mentioning that. I was thinking about doing so, but you beat
> me to it.

Oh, but I forgot to mention on somewhat related method that I've used in
comparable situations. Pass a single adjustable-size array for such
auxillary data. I've normally used an array of reals, as much of the
auxillary data of interest is real, and much of the rest can be easily
converted to real. It isn't quite as "clean" as the void pointer or
polymorphic approaches in that you have to pack all the relevant data
into a suitable array, which then likely needs to be unpacked in the
called routine. On the other hand, it is perfectly standard f90 (and
almost standard f77, as long as you special-case the zero-sized case by
padding it to size 1 because zero-sized arrays aren't allowed in f77).

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: jamesgiles on
On Apr 17, 12:31 pm, glen herrmannsfeldt <g...(a)ugcs.caltech.edu>
wrote:
...
> In a method related to the one Richard mentions, quad
> could be written to accept a single variable, either a
> C void pointer or unlimited polymorphic,
> and pass this variable onto the called routine.  (Both
> requiring Fortran 2003 features that may or may not be
> implemented in current compilers.)  That would allow passing
> any data through in a reentrant manner.

Several years ago Alex Donev sent me an article (I think it was
published somewhere) where he demonstrated how to do all this with
inheritance based polymorphism and type bound procedures. No
procedure pointers (void or otherwise) and therefore lots more
typesafe.

His intent at the time was to demonstrate to me how important
inheritance was. But, any kind of polymorphism would work -
inheritance happened to be the one available. I've always said that
inheritance based polymorphism is better than no polymorphism at all -
barely. Even so, it's a better solution than these procedure pointer,
type cheating, tricky, illegible arcana.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
From: glen herrmannsfeldt on
Richard Maine wrote:

(snip regarding passing data through a generic integration routine)

> Oh, but I forgot to mention on somewhat related method that I've used in
> comparable situations. Pass a single adjustable-size array for such
> auxillary data. I've normally used an array of reals, as much of the
> auxillary data of interest is real, and much of the rest can be easily
> converted to real. It isn't quite as "clean" as the void pointer or
> polymorphic approaches in that you have to pack all the relevant data
> into a suitable array, which then likely needs to be unpacked in the
> called routine. On the other hand, it is perfectly standard f90 (and
> almost standard f77, as long as you special-case the zero-sized case by
> padding it to size 1 because zero-sized arrays aren't allowed in f77).

That should work well for integration, which usually uses real
data. (I might even go for double precision.) That last time I
wanted to do this was with a generic sort routine like C's
qsort. qsort does not provide this ability. Also, passing real
data to a sort routine is less likely to be useful than to an
integration routine.

Also, that should have worked even in Fortran 66, though I don't
know any that did it.

-- glen