Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Passing array valued functions as argument to function.
Hi all,

I've spent several years working with Fortran 95, yet somehow I've
never needed to write functions which use other functions as arguments
until today. I've struggled to make sense of this from the books I
have to hand (no M&R just now).

The purpose of the code will be to compute a definite integral of the
passed function. Here's a toy code example of what I naively expected
to work:

MODULE one
CONTAINS
FUNCTION f1(x_in) RESULT (y_out)
DOUBLE PRECISION :: x_in(:)
DOUBLE PRECISION :: y_out(SIZE(x_in))
y_out = 2*x_in
END FUNCTION f1
END MODULE one

PROGRAM test
USE one
DOUBLE PRECISION :: a(3)=(/ 1.0d0,2.0d0,3.0d0 /)
PRINT*, f1(a)
PRINT*, eval(a,f1)

CONTAINS
FUNCTION eval(x_in,func) RESULT (y_out)
DOUBLE PRECISION :: x_in(:)
DOUBLE PRECISION :: y_out(SIZE(x_in))
DOUBLE PRECISION, EXTERNAL :: func

y_out = func(x_in)
END FUNCTION eval
END PROGRAM test

but I get:

bash$ f95 test.f90 #(Note f95=Nag's compiler on linux.)
Error: test.f90, line 14: Array supplied for scalar argument FUNC (no.
2) of EVAL
[f95 error termination]

Could someone explain how this is meant to be done in Fortran 95.
Many thanks,
Yours,
andy.

PS:
I'd also much appreciate an explanation of why when I replace the
function f1 with

FUNCTION f1(x_in) RESULT (y_out)
DOUBLE PRECISION :: x_in(:)
DOUBLE PRECISION :: y_out
y_out = 2*x_in(1)
END FUNCTION f1

the code segfaults instead.

Report this thread to moderator Post Follow-up to this message
Old Post
andy2o
11-19-04 08:58 PM


Re: Passing array valued functions as argument to function.
CVF 6.6C says:
Error: The shape matching rules of actual arguments and
dummy arguments have been violated.   [F1]
PRINT*, eval(a,f1)
-----------------^

which is because you declare the second argument of eval to be

>     DOUBLE PRECISION, EXTERNAL :: func

while f1 returns a rank-one double-precision array. If, instead, you
replace this line by

INTERFACE
FUNCTION func(x_in) RESULT (y_out)
DOUBLE PRECISION :: x_in(:)
DOUBLE PRECISION :: y_out(SIZE(x_in))
END FUNCTION func
END INTERFACE

at least CVF compiles the code and produces the correct result:

2.00000000000000        4.00000000000000        6.00000000000000
2.00000000000000        4.00000000000000        6.00000000000000

Jan

Report this thread to moderator Post Follow-up to this message
Old Post
Jan Vorbrüggen
11-19-04 08:58 PM


Re: Passing array valued functions as argument to function.
andy2o wrote:
| Hi all,
|
| I've spent several years working with Fortran 95, yet somehow I've
| never needed to write functions which use other functions as arguments
| until today. I've struggled to make sense of this from the books I
| have to hand (no M&R just now).
|
| The purpose of the code will be to compute a definite integral of the
| passed function. Here's a toy code example of what I naively expected
| to work:
|
| MODULE one
| CONTAINS
|   FUNCTION f1(x_in) RESULT (y_out)
|     DOUBLE PRECISION :: x_in(:)
|     DOUBLE PRECISION :: y_out(SIZE(x_in))
|     y_out = 2*x_in
|   END FUNCTION f1
| END MODULE one
|
| PROGRAM test
|   USE one
|   DOUBLE PRECISION :: a(3)=(/ 1.0d0,2.0d0,3.0d0 /)
|   PRINT*, f1(a)
|   PRINT*, eval(a,f1)
|
| CONTAINS
|   FUNCTION eval(x_in,func) RESULT (y_out)
|     DOUBLE PRECISION :: x_in(:)
|     DOUBLE PRECISION :: y_out(SIZE(x_in))
|     DOUBLE PRECISION, EXTERNAL :: func
|
|     y_out = func(x_in)
|   END FUNCTION eval
| END PROGRAM test
|
| but I get:
|
| bash$ f95 test.f90 #(Note f95=Nag's compiler on linux.)
| Error: test.f90, line 14: Array supplied for scalar argument FUNC (no.
| 2) of EVAL
| [f95 error termination]
|
| Could someone explain how this is meant to be done in Fortran 95.

That was a nice (almost good) try. However, as you probably know:

- functions returning arrays require an explicit interface
- funcions with assumed-shape dummies require an explicit interface.

Your f1 above fulfills both conditions.

You don't have an explicit interface there -- only DOUBLE PRECISION,
EXTERNAL, which is not good enough. Even if you did USE one, and
"Eval" is internal to the program, "Eval" still does not know that
its dummy argument "Func" is associated with "F1". Compilers are
not required to look that deep into your thoughts.

Since func is a dummy argument, the only means to achieve the explicit
interface is the INTERFACE block. Instead of

DOUBLE PRECISION, EXTERNAL :: func

use
INTERFACE
FUNCTION func(x_in) RESULT(y_out)
DOUBLE PRECISION :: x_in(:)
DOUBLE PRECISION :: y_out(SIZE(x_in))
END FUNCTION
END INTERFACE

and there you are.

The second sigsegv is again consequence of lack of explicit interface --
without it, "Eval" "presumes" it has assumed-size rather than
assumed-shape dummy argument, and that mismatch causes the sigsegv.

--
Jugoslav
___________
www.geocities.com/jdujic

Please reply to the newsgroup.
You can find my real e-mail on my home page above.


Report this thread to moderator Post Follow-up to this message
Old Post
Jugoslav Dujic
11-19-04 08:58 PM


Re: Passing array valued functions as argument to function.
"Jugoslav Dujic" <jdujic@yahoo.com> wrote in message news:<306egrF2t1046U1@u
ni-berlin.de>...
[snip]
> You don't have an explicit interface there -- only DOUBLE PRECISION,
> EXTERNAL, which is not good enough. Even if you did USE one, and
> "Eval" is internal to the program, "Eval" still does not know that
> its dummy argument "Func" is associated with "F1". Compilers are
> not required to look that deep into your thoughts.


Dear Jan and Jugoslav,

Thanks for your replies, they solved my problem. There's a lot more
Fortran 95 left for me to learn, and I will read up on INTERFACE
blocks!

Thanks,
andy

Report this thread to moderator Post Follow-up to this message
Old Post
andy2o
11-22-04 02:02 PM


Re: Passing array valued functions as argument to function.
> Thanks for your replies, they solved my problem. There's a lot more
> Fortran 95 left for me to learn, and I will read up on INTERFACE blocks!

I believe the example we gave you is the 1 in the 1.5 reasons to actually
use INTERFACE blocks. The other 0.5 is when interfacing with library code
you do not control, and for which no module file are available. All other
documented uses should not be used, because better alternatives are availabl
e.
So you might as well read up other things, but not the gory details of
INTERFACE blocks.

Jan

Report this thread to moderator Post Follow-up to this message
Old Post
Jan Vorbrüggen
11-22-04 02:02 PM


Re: Passing array valued functions as argument to function.
Jan Vorbrüggen <jvorbrueggen-not@mediasec.de> writes:

> I believe the example we gave you is the 1 in the 1.5 reasons to actually
> use INTERFACE blocks....

> So you might as well read up other things, but not the gory details of
> INTERFACE blocks.

Yes. Some textbooks have been known to introduce interface bodies
too early, with the result that people try to overuse them (in
my opinion).  I really recommend that you *NOT* use them much;
you just happen to have found one of the few places where you
do need them.  Some people end up trying to use them in places
where they not only aren't needed, but aren't even allowed.

I'd agree with Jan's 1.5 reasons, but to me this is the 1/2.  Almost
all of my interface bodies are for external library routines,
particularly C ones.  So I'd label that as the 1 and dummy procedures
as the 1/2, but we are close enough.

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard E Maine
11-22-04 08:58 PM


Re: Passing array valued functions as argument to function.
> I'd agree with Jan's 1.5 reasons, but to me this is the 1/2.  Almost
> all of my interface bodies are for external library routines,
> particularly C ones.  So I'd label that as the 1 and dummy procedures
> as the 1/2, but we are close enough.

Hmmm - I put the dummy procedures as counting fully because in this case
there is a requirement to use them in scenarios as posited by the OP.
The case of the external libraries count, IMO, as the 0.5 because they
are a nice-to-have, additional-safety-net, and-so-on, feature, but not a
requirement to get compileable code.

Jan

Report this thread to moderator Post Follow-up to this message
Old Post
Jan Vorbrüggen
11-23-04 01:57 PM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

Fortran archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 06:23 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.