- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello -
I have some subroutine which process arrays of numbers. They are now called as follows:
CALL SUB1(A,NDA,NRA,NCA)
and in the subroutine itself, the array is referenced:
Subroutne SUB1(A,NDA,NRA,NCA)
REAL A(NDA,*)
Integer NDA,NRA,NCA,IRA,ICA
DoIRA=1,NRA
Do ICA=1,NCA
(code)
end do
end do
So NRA and NCA are the actual dimensions of the array, whichwould be imbedded in a larger array.
Now I am wondering: Is it absolutely necessary to supply the argument NDA, or is
there some way to pass that information thru the compiler interface?
In older Fortran versions, the number NDA is absolutely necessary to be passed.
I have some subroutine which process arrays of numbers. They are now called as follows:
CALL SUB1(A,NDA,NRA,NCA)
and in the subroutine itself, the array is referenced:
Subroutne SUB1(A,NDA,NRA,NCA)
REAL A(NDA,*)
Integer NDA,NRA,NCA,IRA,ICA
DoIRA=1,NRA
Do ICA=1,NCA
(code)
end do
end do
So NRA and NCA are the actual dimensions of the array, whichwould be imbedded in a larger array.
Now I am wondering: Is it absolutely necessary to supply the argument NDA, or is
there some way to pass that information thru the compiler interface?
In older Fortran versions, the number NDA is absolutely necessary to be passed.
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes - through a Fortran 90 feature called assumed-shape arrays, but I am a bit confused by your description.
To declare an assumed-shape array, use a colon for each dimension. For example:
REAL A(:.:)
When you pass an array to this, the extents of the actual argument are used for the dummy in the subroutine. Two important points.
1. An explicit interface is required if an argument is assumed-shape. The easiest way to do this is to put the subroutine in a module and USE the module.
2. The lower bound of each dimension will be 1. no matter what the lower bound of the thing you passed was. The upper bound will be the "extent" - the number of elements in that dimension.
You can pass an array section, say A(10:20,4:10) and this will be picked up as A(1:11,1:7).
To declare an assumed-shape array, use a colon for each dimension. For example:
REAL A(:.:)
When you pass an array to this, the extents of the actual argument are used for the dummy in the subroutine. Two important points.
1. An explicit interface is required if an argument is assumed-shape. The easiest way to do this is to put the subroutine in a module and USE the module.
2. The lower bound of each dimension will be 1. no matter what the lower bound of the thing you passed was. The upper bound will be the "extent" - the number of elements in that dimension.
You can pass an array section, say A(10:20,4:10) and this will be picked up as A(1:11,1:7).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> So NRA and NCA are the actual dimensions of the array, whichwould be imbedded in a larger array.
The first part is wrong and the second misses the point. NDA is the leading declared dimension of A, whereas NRA and NCA are the number of logical rows and columns of a submatrix of A. Of these three numbers, NDA is needed by the compiler to put out code to compute the memory address of array elements such as A(i,j). The other two are needed in the algorithm itself (such as transposing the matrix, computing its singular values, etc.
To see why, put yourself in the place of the compiler and ask how the array notation A(i,j) in your program gets transformed to a memory address. In Fortran, a 2-D array is equivalent (in addressing terms) to a 1-D column array starting with Column-1 of A, followed by Columns-2, 3,....
Thus, the logical array
A(1,1) A(1,2) A(1,3) ...
A(2,1) A(2,2) A(2,3) ...
...
A(M,1) A(M,2) A(M,3)...
...
A(NDA,1) A(NDA,2) A(NDA,3) ... (portion of larger matrix that is not used when M < NDA)
is interpreted as
A(1,1)
A(2,1)
...
A(NDA,1)
A(2,1)
A(2,2)
..
A(NDA,2)
A(3,1)
A(3,2)
...
Thus, A(i,j) is equivalent to V(k) with k = NDA*(j-1) + i, where A and V have the same base address.
In a properly written program, we must have NRA <= NDA, and NCA <= the declared second dimension of A. A commonly used hack in the days when memory was scant was to pack the logical matrix into the 1-D array by squeezing out the (logically) unused part of A below row M, but such programs are difficult to read and debug.
The first part is wrong and the second misses the point. NDA is the leading declared dimension of A, whereas NRA and NCA are the number of logical rows and columns of a submatrix of A. Of these three numbers, NDA is needed by the compiler to put out code to compute the memory address of array elements such as A(i,j). The other two are needed in the algorithm itself (such as transposing the matrix, computing its singular values, etc.
To see why, put yourself in the place of the compiler and ask how the array notation A(i,j) in your program gets transformed to a memory address. In Fortran, a 2-D array is equivalent (in addressing terms) to a 1-D column array starting with Column-1 of A, followed by Columns-2, 3,....
Thus, the logical array
A(1,1) A(1,2) A(1,3) ...
A(2,1) A(2,2) A(2,3) ...
...
A(M,1) A(M,2) A(M,3)...
...
A(NDA,1) A(NDA,2) A(NDA,3) ... (portion of larger matrix that is not used when M < NDA)
is interpreted as
A(1,1)
A(2,1)
...
A(NDA,1)
A(2,1)
A(2,2)
..
A(NDA,2)
A(3,1)
A(3,2)
...
Thus, A(i,j) is equivalent to V(k) with k = NDA*(j-1) + i, where A and V have the same base address.
In a properly written program, we must have NRA <= NDA, and NCA <= the declared second dimension of A. A commonly used hack in the days when memory was scant was to pack the logical matrix into the 1-D array by squeezing out the (logically) unused part of A below row M, but such programs are difficult to read and debug.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page