Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

when to use dimension?

4 views
Skip to first unread message

Nasser M. Abbasi

unread,
Oct 6, 2010, 8:51:41 AM10/6/10
to
(learning Fortran...)

Since I can write either of these, with same effect:

real, dimension(10) :: A
real :: A(10)

Then I was wondering, why one should use 'dimension'?

It seems just more typing for same result?

--Nasser

Arjan

unread,
Oct 6, 2010, 9:03:22 AM10/6/10
to
Consider:

real, dimension(10) :: A,B,C,D,F,G,H,I,J,L
real                ::
A(10),B(10),C(10),D(10),F(10),G(10),H(10),I(10),J(10),L(10)


> It seems just more typing for same result?

Now DIMENSION is your friend! ;-)

Arjan

e p chandler

unread,
Oct 6, 2010, 12:18:12 PM10/6/10
to
>> It seems just more typing for same result?

> "Arjan" wrote

> real, dimension(10) :: A,B,C,D,F,G,H,I,J,L
> real :: A(10),B(10),C(10),D(10),F(10),G(10),H(10),I(10),J(10),L(10)

> Now DIMENSION is your friend! ;-)

This can be used to group related arrays.

Eventually it makes sense to create a derived type and then declare an array
of that type.

Ron Shepard

unread,
Oct 6, 2010, 12:55:50 PM10/6/10
to
In article <i8i7g5$oqc$1...@news.eternal-september.org>,

"e p chandler" <ep...@juno.com> wrote:

> > real, dimension(10) :: A,B,C,D,F,G,H,I,J,L
> > real :: A(10),B(10),C(10),D(10),F(10),G(10),H(10),I(10),J(10),L(10)
>
> > Now DIMENSION is your friend! ;-)

Or, change the '10' to 'NumberOfPoints' or some other long
parameter, and it would save even more typing.

Having said that, however, I almost never use DIMENSION, I like to
see the array declaration right with the variable. I work on code
that does it both ways though.


> This can be used to group related arrays.
>
> Eventually it makes sense to create a derived type and then declare an array
> of that type.

Sometimes this is a good idea. The problem is that it stores
elements differently in memory. With declared separate arrays, the
elements within the array are contiguous; with a derived type array
the elements are not contiguous. If you are using a library routine
(say LAPACK) that relies on storage sequence rules to do some kind
of expensive operation on the arrays, then that might cause a lot of
extra copy-in/copy-out overhead. Or if you use assumed shape
declarations in your own code to operate on these arrays, the
nonunit strides might result in a different kind of extra overhead.
So sometimes it is a good idea to package related arrays into a
derived type, other times it isn't.

The other option is to define a derived type that has all of the
related arrays within it. This avoids the contiguous memory
problems, but it complicates somewhat the access to the arrays. So
this also is sometimes a good idea and other times it isn't.

$.02 -Ron Shepard

Wolfgang Kilian

unread,
Oct 6, 2010, 12:49:21 PM10/6/10
to
On 10/06/2010 06:55 PM, Ron Shepard wrote:

> Having said that, however, I almost never use DIMENSION, I like to
> see the array declaration right with the variable. I work on code
> that does it both ways though.

Another philosophy is to have all attributes of an entity on the left of
::, and only the name(s) on the right.

For instance, I like to have DIMENSION(:) and ALLOCATABLE together.

It's a matter of personal style.

-- Wolfgang


--
E-mail: firstnameini...@domain.de
Domain: yahoo

James Van Buskirk

unread,
Oct 6, 2010, 2:37:24 PM10/6/10
to
"Wolfgang Kilian" <see...@domain.invalid> wrote in message
news:i8icr1$m2a$1...@news.eternal-september.org...

> On 10/06/2010 06:55 PM, Ron Shepard wrote:

>> Having said that, however, I almost never use DIMENSION, I like to
>> see the array declaration right with the variable. I work on code
>> that does it both ways though.

> Another philosophy is to have all attributes of an entity on the left of
> ::, and only the name(s) on the right.

> For instance, I like to have DIMENSION(:) and ALLOCATABLE together.

> It's a matter of personal style.

But you can't always use DIMENSION(N). In some instances of generic
programming you really need the DIMENSION statement and this requires
the array-spec to be appended to each varaible. Example:

C:\gfortran\clf\generic_heap>type heapsort.i90
subroutine generic_heapsort(Q,N)
integer, intent(in) :: N
dimension Q(N) ! You can't say dimension(N) Q
integer i
integer current
integer parent
integer left_child
integer right_child
integer the_max

do i = 1, N
current = i
parent = current/2
do while(current > 1)
if(Q(current) <= Q(parent)) exit
Qtemp = Q(parent)
Q(parent) = Q(current)
Q(current) = Qtemp
current = parent
parent = current/2
end do
end do

do i = N, 1, -1
Qtemp = Q(i)
Q(i) = Q(1)
Q(1) = Qtemp
current = 1
left_child = 2*current
right_child = 2*current+1
do while(left_child < i)
the_max = left_child
if(right_child < i) then
if(Q(the_max) <= Q(right_child)) the_max = right_child
end if
if(Q(the_max) <= Q(current)) exit
Qtemp = Q(current)
Q(current) = Q(the_max)
Q(the_max) = Qtemp
current = the_max
left_child = 2*current
right_child = 2*current+1
end do
end do
end subroutine generic_heapsort

C:\gfortran\clf\generic_heap>type generic_heap.f90
module intmod
implicit integer(Q)
private
public heapsort
interface heapsort
module procedure generic_heapsort
end interface heapsort
contains
include 'heapsort.i90'
end module intmod

module typedef
implicit none
private
public mytype, operator(<=), assignment(=)
type mytype
integer key
end type mytype
interface operator(<=)
module procedure less_or_equal
end interface operator(<=)
interface assignment(=)
module procedure do_assign
end interface assignment(=)
contains
function less_or_equal(x,y)
type(mytype), intent(in) :: x, y
logical less_or_equal

less_or_equal = x%key <= y%key
end function less_or_equal

subroutine do_assign(x,y)
type(mytype), intent(out) :: x
type(mytype), intent(in) :: y

x%key = y%key
end subroutine do_assign
end module typedef

module typemod
use typedef
implicit type(mytype) (Q)
private
public heapsort
interface heapsort
module procedure generic_heapsort
end interface heapsort
contains
include 'heapsort.i90'
end module typemod

program generic_heap
use intmod
use typedef
use typemod
implicit none
integer A(10)
integer i
real harvest
type(mytype) B(10)

call random_seed()
do i = 1, size(A)
call random_number(harvest)
A(i) = size(A)*7*harvest
end do
write(*,*) 'A=',A
call heapsort(A,size(A))
write(*,*) 'Sorted A=',A
do i = 1, size(B)
call random_number(harvest)
B(i) = mytype(int(size(B)*7*harvest))
end do
write(*,*) 'B=',B
call heapsort(B, size(B))
write(*,*) 'Sorted B=',B
end program generic_heap

C:\gfortran\clf\generic_heap>gfortran generic_heap.f90 -ogeneric_heap

C:\gfortran\clf\generic_heap>generic_heap
A= 69 39 67 52 25 33
5 0 24 23
Sorted A= 0 5 23 24 25
33 39 52 67 69
B= 15 9 63 27 31 46
1 45 45 22
Sorted B= 1 9 15 22 27
31 45 45 46 63

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Wolfgang Kilian

unread,
Oct 7, 2010, 3:04:46 AM10/7/10
to
On 10/06/2010 08:37 PM, James Van Buskirk wrote:

> But you can't always use DIMENSION(N). In some instances of generic
> programming you really need the DIMENSION statement and this requires
> the array-spec to be appended to each varaible. Example:

I always regarded DIMENSION (and the other attributes in their form as
statements) as an artefact of implicit typing.

You show a nice trick how to abuse implicit typing for generic
programming in Fortran. I sometimes use include files for this task,
but wasn't aware of this particular possibility, good point.

Still, I'd prefer explicit support for generic programming in Fortran.
What I'd like to see is something like this fictitious syntax

abstract subroutine heapsort (Q, N) uses_type (Q_type)
type(Q_type), dimension(N), intent(inout) :: Q
...
end subroutine

procedure, implements heapsort (integer) :: heapsort_int

(There are likely better solutions.) The point is that the dummy type
would be an explicit argument to the generic definition, and its
realization an argument to the concrete implementation.

robin

unread,
Oct 7, 2010, 7:01:20 AM10/7/10
to
"James Van Buskirk" <not_...@comcast.net> wrote in message news:i8ifl7$37l$1...@news.eternal-september.org...

| "Wolfgang Kilian" <see...@domain.invalid> wrote in message
| news:i8icr1$m2a$1...@news.eternal-september.org...
|
| > On 10/06/2010 06:55 PM, Ron Shepard wrote:
|
| >> Having said that, however, I almost never use DIMENSION, I like to
| >> see the array declaration right with the variable. I work on code
| >> that does it both ways though.
|
| > Another philosophy is to have all attributes of an entity on the left of
| > ::, and only the name(s) on the right.
|
| > For instance, I like to have DIMENSION(:) and ALLOCATABLE together.
|
| > It's a matter of personal style.
|
| But you can't always use DIMENSION(N). In some instances of generic
| programming you really need the DIMENSION statement and this requires
| the array-spec to be appended to each varaible. Example:
|
| C:\gfortran\clf\generic_heap>type heapsort.i90
| subroutine generic_heapsort(Q,N)
| integer, intent(in) :: N
| dimension Q(N) ! You can't say dimension(N) Q

You don't need to. You only need dimension Q(:).

And then you don't need N as a dummy argument.

And another thing.
Try using IMPLICIT NONE.


Wolfgang Kilian

unread,
Oct 7, 2010, 6:55:00 AM10/7/10
to
On 10/07/2010 01:01 PM, robin wrote:

> And another thing.
> Try using IMPLICIT NONE.

The curious fact is that the heapsort example code can work *only* with
implicit typing. Quite peculiar.

Richard Maine

unread,
Oct 7, 2010, 1:23:49 PM10/7/10
to
Wolfgang Kilian <see...@domain.invalid> wrote:

> The curious fact is that the heapsort example code can work *only* with
> implicit typing. Quite peculiar.

Yes, and I agree with your comment elsewhere that it almost counts as an
abuse of implicit typing. I have seen this trick and a related one
(using implicit typing to sort-of-handily change precision) before, but
I don't like them. This doesn't seem to me like the kind of thing
implicit typing was for (I use the past tense because I don't like using
it at all any more). Just the fact that these tricks keep you from
getting the benefits of implicit none is already a big negative in my
mind.

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

James Van Buskirk

unread,
Oct 7, 2010, 6:24:32 PM10/7/10
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1jpzlxg.14o9l5e1xynw8xN%nos...@see.signature...

> Wolfgang Kilian <see...@domain.invalid> wrote:

>> The curious fact is that the heapsort example code can work *only* with
>> implicit typing. Quite peculiar.

> Yes, and I agree with your comment elsewhere that it almost counts as an
> abuse of implicit typing. I have seen this trick and a related one
> (using implicit typing to sort-of-handily change precision) before, but
> I don't like them. This doesn't seem to me like the kind of thing
> implicit typing was for (I use the past tense because I don't like using
> it at all any more). Just the fact that these tricks keep you from
> getting the benefits of implicit none is already a big negative in my
> mind.

Since you don't like this use of implicit typing, how would you prefer
to structure the solution to the problem solved by it in my example?

Richard Maine

unread,
Oct 7, 2010, 6:51:48 PM10/7/10
to
James Van Buskirk <not_...@comcast.net> wrote:

> "Richard Maine" <nos...@see.signature> wrote in message
> news:1jpzlxg.14o9l5e1xynw8xN%nos...@see.signature...
>
> > Wolfgang Kilian <see...@domain.invalid> wrote:
>
> >> The curious fact is that the heapsort example code can work *only* with
> >> implicit typing. Quite peculiar.
>
> > Yes, and I agree with your comment elsewhere that it almost counts as an
> > abuse of implicit typing.

> Since you don't like this use of implicit typing, how would you prefer


> to structure the solution to the problem solved by it in my example?

I'd prefer that the language more directly facilitate doing such things.
My dislike was not aimed at your choice of what was available in the
language at the time, but rather at the fact that what was available was
ill suited to the task. It could (as you demonstrated) be made to work,
but that doesn't mean I think it was well suited.

I think that unlimitted polymorphics might serve the purpose, but I'm
afraid there weren't adequate implementations of them available for me
to experiment much when I was still working for a living, and I haven't
spent much time on such things recently. Heck, I'm not sure how many
compilers have them yet now. I have previously and repeatedly vented my
dislike of having to paw through lists of individual features to see
whether compilers have what I need. Part of that dislike stems from bad
experiences in trying compilers that claimed to implement some f2003
features, but omitted others that I regarded as necessary to use the
included ones. (For a very particular example, I find f2003 polymorphism
pretty much pointless without f2003's allocatable scalars.) I have
access to zero full f2003 compilers.

Ordinary polymorphics with inheritance should also be able to do it.
It's pretty much a textbook example of using that kind of feature.
Again, you need f2003 compilers for that.

With f95, I couldn't point to any half decent alternative. I've hacked
up things, but they are pretty hacky and I would not try to defend them
as better that the way you showed.

Again, I wasn't criticising your choice, particularly in the context of
wanting something that actually works with today's compilers (and even
more so, those of a few years ago). I'm just looking at it in terms of
language features needed to facilitate such things in the future. I
think there's enough in f2003, but if that proves inadequate in
practice, then that would be an area for future work. The fact that
there has been so little opportunity for users to work with those f2003
features in practical application illustrates part of my complaint with
what I regarded as the very premature standardization of a later
standard (f2008).

glen herrmannsfeldt

unread,
Oct 7, 2010, 7:38:58 PM10/7/10
to
Richard Maine <nos...@see.signature> wrote:
(snip)

> (For a very particular example, I find f2003 polymorphism
> pretty much pointless without f2003's allocatable scalars.) I have
> access to zero full f2003 compilers.

Reminds me of Java. An Object variable can reference any Object,
which includes any class object or array, but not primitive scalars.
(The primitive types are byte, char, short, int, long, float, double.)

I have had programs with arrays dimensioned [1] to get around that.

So, there is a sort routine for each of the primitive types
and one for Object.



> Ordinary polymorphics with inheritance should also be able to do it.
> It's pretty much a textbook example of using that kind of feature.
> Again, you need f2003 compilers for that.

-- glen

robin

unread,
Oct 7, 2010, 10:41:23 AM10/7/10
to
"Wolfgang Kilian" <see...@domain.invalid> wrote in message news:i8kcem$tov$1...@news.eternal-september.org...

| On 10/07/2010 01:01 PM, robin wrote:
|
| > And another thing.
| > Try using IMPLICIT NONE.
|
| The curious fact is that the heapsort example code can work *only* with
| implicit typing. Quite peculiar.

The curious fact is that the heap example can be made to work with IMPLICIT NONE.

Quite peculiar.


Wolfgang Kilian

unread,
Oct 8, 2010, 3:54:23 AM10/8/10
to
On 10/08/2010 12:51 AM, Richard Maine wrote:
> I'd prefer that the language more directly facilitate doing such things.
> My dislike was not aimed at your choice of what was available in the
> language at the time, but rather at the fact that what was available was
> ill suited to the task. It could (as you demonstrated) be made to work,
> but that doesn't mean I think it was well suited.

With the present state of Fortran and its implementations, I would use
a preprocessor, e.g., declare a macro GENERIC_SORT(GENERIC_TYPE) with
contents

subroutine sort (A)
GENERIC_TYPE, dimension(:), intent(inout) :: A
...

and insert GENERIC_SORT(integer) or whatever is needed in the code. M4
is well suited for such tasks. But usually I try to avoid preprocessors.

> I think that unlimitted polymorphics might serve the purpose,

Yes, but you lose some power of compile-time type-checking. Not a big
deal here. For generic data structures (list, etc.) you would like to
have it. You can be careful writing the modules, but the usual tricks
(TRANSFER, CLASS(*)) somehow give it away.

To me, generic programming is a major missing part in Fortran.

Ron Shepard

unread,
Oct 8, 2010, 12:19:50 PM10/8/10
to
In article <i8mm80$pp$1...@news.eternal-september.org>,
Wolfgang Kilian <see...@domain.invalid> wrote:

> With the present state of Fortran and its implementations, I would use
> a preprocessor, e.g., declare a macro GENERIC_SORT(GENERIC_TYPE) with
> contents
>
> subroutine sort (A)
> GENERIC_TYPE, dimension(:), intent(inout) :: A
> ...
>
> and insert GENERIC_SORT(integer) or whatever is needed in the code. M4
> is well suited for such tasks. But usually I try to avoid preprocessors.

This approach would work just as well with the declaration

GENERIC_TYPE, intent(inout) :: A(:)

so DIMENSION is not necessary. And, this works just fine with
IMPLICIT NONE, so implicit typing is also unnecessary with this
approach.

BTW, the filepp preprocessor is also well suited for this kind of
programming if you want something closer to the usual c preprocessor
approach. You can even define an array of GENERIC_TYPE values, and
loop over those values to generate the specific routines you want to
compile, along with the specific subroutine names and the generic
interface definition. This is a clear, powerful, and
straightforward approach for this kind of programming, and I have
always wondered why nothing like this has ever been incorporated
into the fortran standard.

$.02 -Ron Shepard

Wolfgang Kilian

unread,
Oct 8, 2010, 4:52:27 PM10/8/10
to
On 10/08/2010 06:19 PM, Ron Shepard wrote:
>> With the present state of Fortran and its implementations, I would use
>> a preprocessor, e.g., declare a macro GENERIC_SORT(GENERIC_TYPE) with
>> contents
>>
>> subroutine sort (A)
>> GENERIC_TYPE, dimension(:), intent(inout) :: A
>> ...
>>
>> and insert GENERIC_SORT(integer) or whatever is needed in the code. M4
>> is well suited for such tasks. But usually I try to avoid preprocessors.
>
> This approach would work just as well with the declaration
>
> GENERIC_TYPE, intent(inout) :: A(:)
>
> so DIMENSION is not necessary.

Of course. I just like to have all attributes to the left of the double
colon.

> And, this works just fine with
> IMPLICIT NONE, so implicit typing is also unnecessary with this
> approach.

That's my point.

> BTW, the filepp preprocessor is also well suited for this kind of
> programming if you want something closer to the usual c preprocessor
> approach. You can even define an array of GENERIC_TYPE values, and
> loop over those values to generate the specific routines you want to
> compile, along with the specific subroutine names and the generic
> interface definition. This is a clear, powerful, and
> straightforward approach for this kind of programming, and I have
> always wondered why nothing like this has ever been incorporated
> into the fortran standard.

Thanks for the type, didn't know about filepp. The advantage of M4 is
that it's available on any system that has autotools installed.

0 new messages