3

This doesn't work

program main
   implicit none
   integer :: nx = 3
   integer :: ny = 5
   integer :: nz = 8

   real, allocatable, dimension(:,:,:) :: A
   real, allocatable, dimension(:,:) :: B

   allocate(A(nx,0:ny,nz) )
   ! ...do something with array A and at some point cope a slice of A to B:
   B = A(:,:,1)
   ! in this case B is (1:nx, 1: ny+1) 
end program main

The code above automatically allocates B and copies A(:,:,1) to B. However it doesn't keep the lower/upper bound of 0/ny, instead B has its lower bound to 1 and upper bound to ny+1.

The only way I found to keep the lower/upper bound of A 2dn-dim is by explicitly allocate B as:

   allocate(B(nx, 0:ny))
   B = A(:,:,1)
   ! in this case B is (1:nx, 0:ny)

Given that I have many more variables than in this simple example, is there a way to assign like B=A(:,:,1) and also keep the bounds of A without explicitly allocating B?

francescalus
  • 30,576
  • 16
  • 61
  • 96
pablosaa
  • 108
  • 1
  • 5
  • I have seen the same behavior. It is not quite a bug, but an accidental feature. Essentially you are copying one array to another with different bounds with the `=` operator. – John Alexiou Apr 10 '20 at 23:05
  • Does this answer your question? [Preserve bounds in allocation in intrinsic assignment](https://stackoverflow.com/questions/56114861/preserve-bounds-in-allocation-in-intrinsic-assignment) – francescalus Apr 11 '20 at 11:41
  • Thank you francescalus, yes partially it does answer. – pablosaa Apr 11 '20 at 16:50

2 Answers2

2

A(:,:,1) is an expression. It has bounds (1:nx, 1:ny), BOTH ranks start at 1. It is not the original array, it is a new expression.

However, even if it was an array that had some other lower bounds, automatic allocation always allocates indexes starting from 1. Basically, the right hand side is an expression again.

For your case you do have to allocate explicitly.

  • Thanks @vladimir-f for your answer. A(:,:,1) is actually the original array and when assigned to B it copies all the elements from bounds (1:nx, 0:ny) to (1:nx, 1:ny+1). Since I have many arrays like A with different lower/upper bounds, I was wondering if there is a way to copy directly keeping the bounds without allocating explicitly. – pablosaa Feb 02 '20 at 22:52
  • @pablosaa NO, please do read my answer again. `A` is the original array. `A(:,:,1)` is a **subarray**, it is NOT the original array, it is an expresdion. I do understand what you wanted to do and my answer is exactly about that. – Vladimir F Героям слава Feb 03 '20 at 06:32
1

You can use:

allocate(B(lbound(A,1):ubound(A,1), lbound(A,2):ubound(A,2)))
  • 1
    Yes, it seems the only work around is to explicitly allocate the variable with low and upper bound of use source=A in allocation. – pablosaa Apr 11 '20 at 16:52