COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Passing subsections of arrays in f77

• Email
• Follow

```Hi,

How do I pass a subsection of an array to a subroutine?  Thanks, Rudy

For example, suppose I have:

Real*8 a(10,10)

call subrout(a(,10))

.. . .

subroutine subrout(a)

real*8 a(10)

```
 0
Reply rjmagyar (14) 9/19/2006 6:20:55 PM

See related articles to this posting

```rjmagyar wrote:
> Hi,
>
> How do I pass a subsection of an array to a subroutine?  Thanks, Rudy
>
> For example, suppose I have:
>
> Real*8 a(10,10)
>
> call subrout(a(,10))
>
> . . .
>
> subroutine subrout(a)
>
> real*8 a(10)

Fortran arrays are stored in column-major order, so you can just write

call subrout(a(1,10))

Here is an example in Fortran 95 using an integer matrix:

subroutine sub(ivec)
integer :: ivec(2)
print*,"in sub, ivec =",ivec
end subroutine sub

program xsub
integer, parameter :: n1 = 2, n2 = 3
integer            :: imat(n1,n2),i1,i2
do i1=1,n1
do i2=1,n2
imat(i1,i2) = i1 + 10*i2
end do
end do
print*,"imat=",imat
call sub(imat(1,n2))
end program xsub

output:

imat= 11 12 21 22 31 32
in sub, ivec = 31 32

With few changes this code could be F77. I don't think there is a
simple way to pass a row subsection in F77. Fortran 95 offers more
powerful array handling, including array sections, than F77, and has
many other advantages. Why don't you use it?

```
 0
Reply beliavsky (2211) 9/19/2006 6:44:58 PM

```rjmagyar <rjmagyar@gmail.com> wrote:

> How do I pass a subsection of an array to a subroutine?  Thanks, Rudy

> For example, suppose I have:

> Real*8 a(10,10)

> call subrout(a(,10))

In standard Fortran 77 you pass A(1,10) and realize that the
called routine gets the ten elements in memory starting at A(1,10).

Fortunately for you, those are A(1,10), A(2,10), A(3,10), ...

(The called routine is allowed to read any element from the specified
element through the end.  If you pass A(1,5) 60 elements are
available to the called routine.  You can also pass the number
of elements, and use that in the DIMENSION statement in the
called routine.)

If you instead wanted to pass A(10,) you would have to make a copy
yourself first.

This is still true for assumed size arrays in versions since 1977.

-- glen

```
 0
Reply gah1 (524) 9/19/2006 6:45:34 PM

```Um. Ooops. I just finished typing this whole thing and then noticed that
the subject line said f77. Almost all of my reply was about features new
to f90. I guess I'll go ahead and post it anyway, along with a short f77
answer and the suggestion that the OP consider moving to f90/f95.

To answer the original question in a pure f77 context, f77 basically has
no such thing as an array subsection, so you can't readily pass one.
There is a hack you can do for some cases, but it is really quite quirky
and only works at all for very limited cases.

The hack is that you pass an array element as the actual argument. Note
that the OP's a(,10) is not a proper syntax for an array element. THat
looks like an attempt at inventing a syntax for a section, but again,
f77 has no such thing. The syntax for the appropriate array element here
would be a(1,10).

Yes, the syntax is highly confusing and irregular in that there is no
way to tell by looking at it whether you are passing just that array
element or using this hack to pass what amounts to a section.

Anyway, if you pass an array element as an actual argument for an array
dummy argument, the dummy argument "gets" consecutive memory locations
starting with the specified element. You hav eto know about Fortran
array layout in memory in order to figure out what that means in any
particular case. Generally, it ends up meaning that this hack can be
used to pass an array column, but not to pass an array row.

So just changing your a(,10) to a(1,10) will probably do what you want.
But I recommend looking into f90/f95 instead. See below for that.

rjmagyar <rjmagyar@gmail.com> wrote:

> How do I pass a subsection of an array to a subroutine?

Well, there are 2 basic parts to it.

> For example, suppose I have:
>
> Real*8 a(10,10)
>
> call subrout(a(,10))

The first part is how to write a subsection of an array in any context.
This has nothing in particular to do with subroutines. I'm not 100% sure
what you mean by a(,10) above, as that is not a standard Fortran syntax
and you didn't explain what you intended, but I am reasonably confident
that what you meant was the 10th column of the array. That can be
written in any of several ways, the simplest of which is a(:,10). The
":" is the important part here; it indicates that there is a slice along
that dimension. You could more verbosely write a(1:10,10), explicitly
indicating the range of the slice, but the simple colon uses the
declared upper and lower bounds as defaults.

> subroutine subrout(a)
>
> real*8 a(10)

While this will work, it can have several undesired consequences.

1. Of course, if the actual argument ever has a size other than 10,
there will be problems. That might or might not be an isssue for your
code.

2. This might trigger copy-in/copy-out in some cases with some
compilers. Basically, this f77-style (I'm ignoring the non-standard
real*8 bit) array declaration implies that the array is contiguous in
memory (like all f77 arrays are in practice). With array slices, you can
make non-contiguous actual arguments. The compiler is likely to make a
temporary contiguous copy to work around this.

I generally recommend declaring dummy arguments with assumed shape in
f90. That is, use the declaration form (again, I don't recommend the
real*8 part, but I'll copy your usage of that as it is not the main
point here)

real*8 a(:)

This form says to get the array size from whatever is passed as the
actual argument. It also directly accomodates non-contiguous slices; the
information needed to deal with them is also passed from th eactual
argument.

However, when you have an assumed shape dummy argument, you will also
*NEED* to have an explicit interface. Note the emphasis; it is not
optional. If you don't have an explicit interface, it won't work
correctly. Having an explicit interface means doing one of three things

1. Putting the subroutine in a module. Many things in f90 work most
conveniently with modules.

2. Making the subroutine an internal one. That's simple, but has
limitted applicability.

3. Write an interface body. This is laborious and error prone. I
recommend one of the other options. Consider this as a last resort.

--
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
```
 0
Reply nospam47 (9744) 9/19/2006 6:47:43 PM

3 Replies
41 Views

Similar Articles

12/5/2013 6:48:45 PM
[PageSpeed]

Similar Artilces:

reverse arrays
was needing to build an array that prints backwards ( stringReverse ) and returns nothing. should stop processing and print nothing when null is encountered. this is what i have so far. was going to build my function from the call but could not make it compile from this point. #include <stdio.h> #define SIZE 30 int main() { int loop; char strArray[ SIZE ] = "Print this string backwards."; for ( loop = 0; loop < SIZE; loop++ ) { printf( "%c", strArray[ loop ] ); } printf( "\n" ); stringReverse( strArray ); printf(

Cloning arrays
Another newbie question. I have started recoding some of my homegrown Tcl/Tk applications in Ruby/rubytk and have hit an unexpected snag when attempting to clone arrays. The following code is snipped verbatim from the program: # Calculate coordinates for the Postscript page canvas and the # label icons canvas in the setupInkjet window. def User.calcxy ( disposition, f ) xygrid = { } # Split the disposition string into x and y counts. xy = Typefaces::Disposition[disposition] # Obtain the label dimensions. labelsize = Typefaces::Labelsizes[disposition] # Populate the coordinate data structure. xygrid['x'] = nx = xy[0] xygrid['y'] = ny = xy[1] xygrid['dx'] = dx = labelsize[0] * f xygrid['dy'] = dy = labelsize[1] * f # Obtain an array of 4 element arrays from the Typefaces module. # These represent opposing corners of the address spaces on the # Postscript canvas. xygrid['page'] = Typefaces.labelgrid( disposition ) puts 'page coordinates' puts xygrid['page'][0] puts '______________' # Copy the page label coordinates. e = xygrid

Compile with Boolean Arrays
Can anyone explain why this works: MatrixMultiply = Compile[ {{a, _Integer, 2}, {x, _Integer, 1}}, Inner[Times, a, x, Plus], {{Inner[__], _Integer, 1}} ] MatrixMultiply[{{2, 0}, {0, 1}}, {2, 1}] But this doesn't: LogicalMatrixMultiply = Compile[ {{a, True | False, 2}, {x, True | False, 1}}, Inner[And, a, x, Or], {{Inner[__], True | False, 1}} ] LogicalMatrixMultiply[{{True, False}, {False, True}}, {True, False}] I thought I used the correct syntax for Boolean arguments in Compile...

Declaring Multi-Dimensional Arrays
hi all, I have perused the internet a bit and don't see a simple beginner's answer. All I need right now is how to declare a multi-dimensional array in C++. // one dimensional array - simple enough int array[4] = {0,0,0,0}; // two dimensional array - ? int array[4][5] = {0,0,0,0 ... ? thx! joe wrote: > hi all, > > I have perused the internet a bit and don't see a simple beginner's answer. > All I need right now is how to declare a multi-dimensional array in C++. > > // one dimensional array - simple enough > int array[4] = {0,0,0,0}; > > //

problems with associative arrays
Hi, I'm facing issues with using associative arrays in non-IE browsers. In particular, I have code like the following: var IDToAddress = new Array(); IDToAddress['1000000'] = 'apple tree lane, mars'; IDToAddress['2000100'] = 'orchard street, venus'; The keys used in this array are all strings, but each key is actually just a v. large integer e.g. '1000000'. There are several hundred such key-value pairs that make up this array. This works fine in IE, but other browsers simply hang, using up huge amounts of memory. It appears that not all browsers handle such associative arrays well - whose keys are large numbers represented as strings. Has anyone faced similar problems, and are there work-arounds? thanks Nagender On 30 Sep 2005 00:33:38 -0700, nkparimi@gmail.com wrote: > var IDToAddress = new Array(); > IDToAddress['1000000'] = 'apple tree lane, mars'; > IDToAddress['2000100'] = 'orchard street, venus'; Use simply object, not Array: var IDToAddress=new Object(); IDToAddress['1000000'] = 'apple tree lane, mars'; IDToAddress['2000100'] = 'orchard street

Inversion Density of 0-1 Arrays
I am looking for more references to inversions in 0-1 arrays. Given an array A indexed from 1 to n with values from the set {0,1}, an inversion of A is a pair (i,j) such that 0<i<j<(n+1), i.e. i and j are two different valid indices of A with i<j, and also A[i]=1 > A[j]=0 . Inversions are also defined for arrays with values coming from some totally ordered set, but for now I just care about 0-1 arrays. I am looking for results on how inversions are distributed in subintervals of a given array. Since there are n choose 2 distinct ordered pairs of indices for an array of size n, I will call the inversion density of the array the quantity I/(n^2), where I is the number of inversions of the array. Most references I have found so far either do not specify 0-1 arrays, or do not consider the inversion density. One reference I have has a result I paraphrase as: "There is a number K > 0 such that every 0-1 array A has at least one contiguous subarray of each size with an inversion density at least K times the inversion density of A." In this reference the author does a rough estimation of K because all he needs is a specific such K; I want to find K

Sorting associative arrays
Hello, I'm having some difficulties sorting an associative array. I have a project that I'm working on which requires me to write my scripts in a UNIX for Windows environment. I have gawk version 3.0.4, but I'm not able to use the asort function to sort my array. I'm having difficulties getting the contents to be read back from the array in the order in which they were entered, which was numerically sorted from lowest to highest. Does anyone have a quick function that will allow me to get this working? Any other suggestions? Thanks in advance! In article <kOqdne

2D arrays elements extract and calculate
Please help. I have 2D array (m x n). I want to read each row and extract row elements. Then I need to compare these with previous row elements. Can anyone please guide me ? Thanks venurg@gmail.com wrote:I have 2D array (m x n). I want to read each row ... Just feed it into a FOR loop. It will autoindex and at each iteration you'll get one row until all rows are processed. venurg@gmail.com wrote:...and extract row elements. Then I need to compare these with previous row elements. Can anyone please guide me ? Do you want to compare each row with the previous row&nbsp;or do you