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

Automatic reallocation and lower bounds other than 1

98 views
Skip to first unread message

Arjen Markus

unread,
Apr 20, 2021, 4:58:27 AM4/20/21
to
Hello,

I just came across a situation where it would be nice (though not essential) to have a lower bound of 0, while building up an array. Something like:

newarray = [oldarray, newelement]
write(*,*) newarray(0:)

Is that possible?

Like I said, nothing essential, but I am curious whether it can be arranged and how.

Regards,

Arjen

rbader

unread,
Apr 20, 2021, 8:29:27 AM4/20/21
to
The lower bound of the automatically allocated array is the same as LBOUND( [oldarray, newelement] ), i.e. 1. A zero lower bound can only be achieved if a whole array is specified as the RHS. In your situation, you therefore need to perform explicit allocation with the desired lower bound.

Regards
Reinhold

Arjen Markus

unread,
Apr 20, 2021, 11:16:23 AM4/20/21
to
On Tuesday, April 20, 2021 at 2:29:27 PM UTC+2, rbader wrote:
Clear enough - in my particular case I simply needed a shift to get the right answers (so could use a lower bound of 1) but it made me wonder.

Thanks,

Arjen

gah4

unread,
Apr 20, 2021, 9:19:22 PM4/20/21
to
On Tuesday, April 20, 2021 at 1:58:27 AM UTC-7, arjen.m...@gmail.com wrote:
> Hello,
>
> I just came across a situation where it would be nice (though not essential) to have a lower bound of 0, while building up an array. Something like:
>
> newarray = [oldarray, newelement]
> write(*,*) newarray(0:)

allocate(newarray(0:size(oldarray)))
newarray = [oldarray, newelement]

to be more sure that it doesn't reallocate, or to make it more
obvious to readers:

allocate(newarray(0:size(oldarray)))
newarray(0:size(oldarray)) = [oldarray, newelement]

The ability to add elements to an array this way is convenient, but
not so efficient. It requires allocating and copying the whole array.

If you do this a lot, or deeply nested in loops, it is often worth allocating
a larger array and separately keeping track of the number of elements in use.

(I presume from the name that newelement is a scalar. If not, you need
to consider its size, too.)
I note that you didn't say:

oldarray = [oldarray, newelement]

It isn't so obvious what compilers might do with this, but one might create a
temporary array for the right side, copy data into it, reallocate oldarray,
and copy the data over. In that case, you might do better using movealloc().

Just to be sure, I am not suggesting premature optimization, but in case optimization
is needed, you know where to look for it.

Otherwise, array expressions always have a lower bound of 1.


Arjen Markus

unread,
Apr 21, 2021, 2:15:41 AM4/21/21
to
On Wednesday, April 21, 2021 at 3:19:22 AM UTC+2, gah4 wrote:
I was working on a small toy program to generate the Recamán sequence (or better one of the two), when I realised that I wanted to have an array with a lower bound of 0 instead of 1 (see this thread - https://fortran-lang.discourse.group/t/integer-sequences/1081). In this case, the program is even simpler with 1 as the start (as I could drop the "i-1" argument) and indeed, I use the pattern "oldarray = [oldarray, newelement]" there. I used this for compactness and to show off a bit ;).

Regards,

Arjen

gah4

unread,
Apr 21, 2021, 2:58:32 AM4/21/21
to
On Tuesday, April 20, 2021 at 11:15:41 PM UTC-7, arjen.m...@gmail.com wrote:

(snip)

> I was working on a small toy program to generate the Recamán sequence
> (or better one of the two), when I realised that I wanted to have an array
> with a lower bound of 0 instead of 1 (see this thread -
> https://fortran-lang.discourse.group/t/integer-sequences/1081).
> In this case, the program is even simpler with 1 as the start (as I could drop
> the "i-1" argument) and indeed, I use the pattern "oldarray = [oldarray, newelement]"
> there. I used this for compactness and to show off a bit ;).

The previous one uses a preallocted array, which doesn't seem so bad.

I suppose with the small n that this is likely to be used I don't worry about it,
but the allocation loop results in O(n**2) timing even if the rest if fast.

I think it isn't so hard to allocate the array once and use array slice
notation in the loop, using similar array expression notation.


Arjen Markus

unread,
Apr 21, 2021, 5:29:24 AM4/21/21
to
On Wednesday, April 21, 2021 at 8:58:32 AM UTC+2, gah4 wrote:
Very true :). I like the functional style, which is why I did it this way. I do not claim that my implementation is the most efficient.

Regards,

Arjen
0 new messages