|
From: glen herrmannsfeldt on 17 Apr 2008 14:31 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 17 Apr 2008 15:07 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 17 Apr 2008 15:31 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 17 Apr 2008 15:50 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 17 Apr 2008 16:02 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
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: Derived type argument to subroutine Next: cvf66c: building program |