- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Rather than specifically stating the length of an input matrix, how would one
aumtomatically determine that from the calling sequence. I tried using Ubound, but the
compiler doesn't like that, it say it is not determinable. And LEN is supposed to be
for character strings.
Here is a simple example;
--------------------------------------------------------------------------------------------------------
integer*1 a(200)
integer*2 asum, sum
asum=sum(a(3:24))
integer*2 function sum(a)
integer*4 na(1)
na=UBOUND(a) ! apparently not the right one
sum=0
do ia=1,na(1)
sum=sum+a(ia)
enddo
end
--------------------------------------------------------------------
I realize the FORTRAN already has a sum function, this is just an example.
In the above case, its supposed to give a value of 22 for length, since 22 elements are
being passed. I looked at the FORTRAN HELP, but could not find the proper function, if one exists
for getting the length of the passed array.
This would of course get more complicated for 2 or 3 dimensional arrays, since the length would be passed to an array
rather than a scalar.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm - thought I had replied to this.
Your sample source is somewhat confusing - you never declare the argument a in sum and na comes from - where?
There are generally two ways to get the bounds of a dummy argument. The modern way is to declare the argument as an assumed-shape array, with dimension (:). This requires that an explicit interface be visible to the caller, so the subroutine either has to be in a module or in a CONTAINS section. The older way is to pass the bound as a separate argument and use that in the declaration. For example:
subroutine sub(a,n)
integer n
real a(n)
With either of these you can use UBOUND (and LBOUND), and SIZE. SIZE gives you the number of elements, UBOUND gives the upper bound (which might not be the number of elements if the lower bound is not 1. Note that UBOUND by default returns an array of bounds, if you want a specific one add the DIM= argument.
Perhaps you should pick up one of any number of books teaching "modern Fortran".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]
integer*2 function sum(a)
implicit none
integer, intent(in) :: a(:) ! assumed shape
integer :: ia, sum
sum=0
do ia=lbound(a, DIM=1),ubound(a, DIM=1)
sum=sum+a(ia)
enddo
end
[/fortran]
Then place that into a CONTAINS section of a module that you USE in your program.
Alternatively, you can place an interface to the function, into a module, or into the variable declaration of a procedure.
[fortran]
interface
integer*2 function sum(a)
implicit none
integer, intent(in) :: a(:) ! assumed shape
end function sum
end interface
[/fortran]
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will try the SIZE function. I have two books about Fortran, but they are not very helpful re this question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe I got the wrong books? But it would be nice if they gave more examples.
The FORTRAN help on-line is pretty sparse as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim,
I can not get lbound and ubound values to be transferred in an interface. See the following example:
[fortran]
integer*4 aa(1000), n
interface
integer*2 function bb (a)
integer, intent(in) :: a(:) ! assumed shape
end function bb
end interface
n = bb (aa) ; write (*,*) 'bb(aa) =',n
n = bb (aa(5:33)) ; write (*,*) 'bb(aa(5:33)) =',n
end
integer*2 function bb (a)
integer, intent(in) :: a(:) ! assumed shape
write (*,*) 'lbound', lbound (a, DIM=1)
write (*,*) 'ubound', ubound (a, DIM=1)
write (*,*) 'size ', size (a)
bb = size (a) * kind (a)
end[/fortran]
John
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Our documentation is meant as a reference, not a tutorial. That said, the description of UBOUND, at least, is far from sparse and includes examples.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John, are you expecting that you'll see bounds of 5:33 when you pass aa(5:33)? That's not how the language works. The bounds in the caller are not used - the lower bound starts at 1 unless declared otherwise and the upper bound is the extent.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Your response implies I am expecting too much of the language.
I understand that this is how the language presently works, but would it have been unreasonable to expect it to provide the bounds via an INTERFACE, rather than just the SIZE ?
The purpose of the INTERFACE was to improve on the F77 explicit bounds definition and provide the dimension information of an array. It has clearly stoped short on providing the bounds definition. In the past I wanted to find out this information for an array section and was disappointed with the result.
John
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the general case - what if your procedure bb was called with the expression `aa(11:20) + aa(25:34)` as an argument. What would the bounds inside the procedure be then?
You could probably come up with some guidelines as to how it could work in some alternative Fortran universe, but I think they would end up being rather complicated, and in places counter-intuitive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian has it exactly right - not to mention something like aa(11:20:3). The standard chose a definition that works for all possible manner of arguments. It makes it easier to write a procedure that takes array arguments as you always know what the lower bound is. If you have a situation where you need to preserve the bounds exactly, pass a pointer to a pointer.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page