For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2007 > dimension question









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author dimension question
sc

2007-02-25, 8:04 am

Hi everybody,
I'm newbie at fortran. So I have a question about 'dimention'. Here is
an example of code to show problem.
cccccccccccccccccccccccccccccccccccccccc
ccccccccc
program dimtest
c
integer n, maxn
parameter(maxn=100)
real a
dimension a(maxn, maxn)
c
n = 2
a(1,1) = 1
a(1,2) = 2
a(2,1) = 3
a(2,2) = 4
call test(a, n)
end
cccccccccccccccccccccccccccccccccccccccc
ccccccccc
subroutine test(a, n)
integer n
real a
c problem is in the next string
dimension a(n, n)
c but in this case everithing is fine
c dimension a(100, n)
print *, a(1,1), a(1,2), a(2,1), a(2,2)
end
cccccccccccccccccccccccccccccccccccccccc
ccccccccc
My expected output is:
1.000000 2.000000 3.000000 4.000000
But in above test program output is like this:
1.000000 0.000000 3.000000 0.000000
So my first question is "why is it so critical to declare the first
dimension of a multidimension array as big as initial declaration
was?"
I used f95 and f77 compilers from gcc suite on linux.
The second question is "what the best practice to solve such
problems?"
Thanks for any advice

glen herrmannsfeldt

2007-02-25, 8:04 am

sc wrote:
> Hi everybody,
> I'm newbie at fortran. So I have a question about 'dimention'. Here is
> an example of code to show problem.
> cccccccccccccccccccccccccccccccccccccccc
ccccccccc
> program dimtest
> c
> integer n, maxn
> parameter(maxn=100)
> real a
> dimension a(maxn, maxn)
> c
> n = 2
> a(1,1) = 1
> a(1,2) = 2
> a(2,1) = 3
> a(2,2) = 4
> call test(a, n)
> end
> cccccccccccccccccccccccccccccccccccccccc
ccccccccc
> subroutine test(a, n)
> integer n
> real a
> c problem is in the next string
> dimension a(n, n)
> c but in this case everithing is fine
> c dimension a(100, n)
> print *, a(1,1), a(1,2), a(2,1), a(2,2)
> end
> cccccccccccccccccccccccccccccccccccccccc
ccccccccc
> My expected output is:
> 1.000000 2.000000 3.000000 4.000000
> But in above test program output is like this:
> 1.000000 0.000000 3.000000 0.000000
> So my first question is "why is it so critical to declare the first
> dimension of a multidimension array as big as initial declaration
> was?"


In the main program the array elements are stored in
10,000 elements in order a(1,1), a(2,1), a(3,1) ...
a(100,1), a(1,2), a(2,2), a(3,2), ... etc.

If the subroutine DIMENSION statement is a(2,2) the array
is expected to be stored a(1,1), a(2,1), a(1,2), a(2,2),
such that array elements map into the first four elements
in the main program, a(1,1), a(2,1), a(3,1), and a(4,1).

> I used f95 and f77 compilers from gcc suite on linux.
> The second question is "what the best practice to solve such
> problems?"


The Fortran 77 solution is to supply another argument to
the subroutine indicating the actual dimension for the
first subscript:

subroutine test(a, n, norig)
integer n
real a
c problem is in the next string
dimension a(norig, n)

Use n when referencing the array as n by n, but
norig such that the right array elements are referenced.

Another possible solution for f95, but not f77, is to
use assumed shape for the subroutine. For assumes shape,
the actual shape is automatically sent to the subroutine.
If you want to use less than the whole array, you still
pass n as a subroutine argument.

-- glen

Michael Metcalf

2007-02-25, 7:06 pm


"sc" <stas_ch@inbox.ru> wrote in message
news:1172402080.302635.176180@h3g2000cwc.googlegroups.com...
> I used f95


Since you have a f95 compiler, might I suggest that you learn Fortran 95
rather than Fortran 77. The solution to your problem is then to use an
assumed-shape array:


program dimtest
!
integer n, maxn
parameter(maxn=100)
real a
dimension a(maxn, maxn)
!
n = 2
a(1,1) = 1
a(1,2) = 2
a(2,1) = 3
a(2,2) = 4
call test(a(:n, :n) )

contains

subroutine test(a)
real a(:, :)
print *, a(1,1), a(1,2), a(2,1), a(2,2)
end subroutine test

end

Regards,

Mike Metcalf


glen herrmannsfeldt

2007-02-25, 7:06 pm

Michael Metcalf wrote:

(snip)

> Since you have a f95 compiler, might I suggest that you learn Fortran 95
> rather than Fortran 77. The solution to your problem is then to use an
> assumed-shape array:


(snip)

With assumed shape the subroutine can find out the actual size of
the array, and use that.

subroutine test(a)
real a(:, :)
integer i,j
do i=1,size(a,2)
print *, (a(j,i),j=1,size(a,1))
end subroutine test

If you require a square array compare size(a,1) and size(a,2)
and complain appropriately. For assumed shape it is still faster
to have the leftmost subscript vary faster, as above. In this
case the a in the subroutine is in non-contiguous storage, which
may be slower.

-- glen

sc

2007-02-25, 7:06 pm

Thanks everybody a lot.
All advices helped me to understand fortran arrays memory storage
quite clear. As well as to solve this problem correctly.
Well, array storage method in fortran is a little bit different from
other languages I know.
Thanks again.

Richard Maine

2007-02-25, 7:06 pm

sc <stas_ch@inbox.ru> wrote:

> Well, array storage method in fortran is a little bit different from
> other languages I know.


Some other languages use row-first instead of column-first ordering, but
your original code (which passed a 100x100 actual argument to a 2x2
dummy) wouldn't have worked any better that way.

If you you know of any languages where anything like that would have
worked, then what is happening is that it is working with a slice of the
larger array - not just counting on the memory layout to happen to fit
(it won't). The notation might possibly hide that, but that's bound to
be what is happening. Fortran does have a way to do that - at least as
of f90. That's the array slice notation that Mike Metcalf illustrated.

If you restrict yourself to Fortran 77, then yes, lots of array-related
things are harder. Fortran 77 doesn't have a concept of an array slice;
all you can do is play tricks with the memory layout.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
glen herrmannsfeldt

2007-02-25, 7:06 pm

Richard Maine wrote:

> sc <stas_ch@inbox.ru> wrote:


[color=darkred]
> Some other languages use row-first instead of column-first ordering, but
> your original code (which passed a 100x100 actual argument to a 2x2
> dummy) wouldn't have worked any better that way.


> If you you know of any languages where anything like that would have
> worked, then what is happening is that it is working with a slice of the
> larger array - not just counting on the memory layout to happen to fit
> (it won't). The notation might possibly hide that, but that's bound to
> be what is happening. Fortran does have a way to do that - at least as
> of f90. That's the array slice notation that Mike Metcalf illustrated.


The usual way to pass dynamic arrays in C89 is an array of pointers
to sub-arrays. Otherwise, C89 arrays do work similar to Fortran arrays,
(but row-wise) and require the rightmost dimensions to be compile time
constants.

There are also interpreted languages like Matlab, Mathematica, and R
that may allow it to work.

> If you restrict yourself to Fortran 77, then yes, lots of array-related
> things are harder. Fortran 77 doesn't have a concept of an array slice;
> all you can do is play tricks with the memory layout.


Since he didn't say what the other languages were, it is hard to say more.

-- glen

Richard Maine

2007-02-25, 7:06 pm

glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:

> There are also interpreted languages like Matlab, Mathematica, and R
> that may allow it to work.


That would be what I already described as:
[color=darkred]

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
glen herrmannsfeldt

2007-02-25, 10:05 pm

Richard Maine wrote:
> glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
>
>
[color=darkred]
> That would be what I already described as:

[color=darkred]

In Mathematica, a two dimensional array is a list of lists, where a one
dimensional array is a list. (and List[] is actually a function, in
Mathematica's 'everything is a function' system.)

In R, two dimensional arrays are column major like Fortran, but the
system will create a copy of a subset with any slice-like operation.
Otherwise, dimension information is passed to called routines.

I don't know about Matlab, so I won't say anything about how it
does it.

-- glen

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com