Determining the length of an input matrix

Determining the length of an input matrix

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.

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Steve Lionel (Intel)'s picture

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". 

Steve
jimdempseyatthecove's picture

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

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.

interface
  integer*2 function  sum(a)
    implicit none
    integer, intent(in) :: a(:) ! assumed shape
  end function sum
end interface

Jim Dempsey

www.quickthreadprogramming.com

I will try the SIZE function. I have two books about Fortran, but they are not very helpful re this question.

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.

Jim,

I can not get lbound and ubound values to be transferred in an interface. See the following example:

    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

John

 

 

Attachments: 

AttachmentSize
Download bb.log1.01 KB
Download bb.f90583 bytes
Steve Lionel (Intel)'s picture

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.

Steve
Steve Lionel (Intel)'s picture

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.

Steve

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

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.

Steve Lionel (Intel)'s picture

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.

Steve

Login to leave a comment.