Несоответствие ранга Fortran 90 при попытке извлечь вектор из массива - PullRequest
0 голосов
/ 03 августа 2011

В моем коде Fortran 90 я создал следующий массив (называемый array ) целых чисел:

 1     2     3     4     5     6     7     8     9    10
11    12    13    14    15    16    17    18    19    20
21    22    23    24    25    26    27    28    29    30
31    32    33    34    35    36    37    38    39    40

Я хочу извлечь первый столбец и сохранить его в четырехэлементном векторе, называемом время . У меня есть следующий код:

PROGRAM test
  IMPLICIT NONE
  INTEGER, PARAMETER :: numrows=4, numcols=10
  INTEGER :: i, j, k
  INTEGER, DIMENSION(:,:), ALLOCATABLE :: array, time

  ALLOCATE(array(numrows,numcols))
  ALLOCATE(time(numrows))

  k=1
  DO i=1,numrows
    DO j=1,numcols
      array(i,j)=k
      k=k+1
    END DO
  END DO

  DO i=1,numrows
    WRITE(*,"(100(3X,I3))") (array(i,j), j=1,numcols)
  END DO

  time=array(:,1)
END PROGRAM test

Но я получаю следующее сообщение об ошибке (при компиляции в gfortran):

test.f90:8.15:

  ALLOCATE(time(numrows))
               1
Error: Rank mismatch in array reference at (1) (1/2)
test.f90:22.2:

  time=array(:,1)
  1
Error: Incompatible ranks 2 and 1 in assignment at (1)

Почему это так? Кажется, в сообщении об ошибке указывается, что массив array(:,1) имеет ранг 2, а не ранг 1. Можно ли каким-либо образом преобразовать array(:,1) в массив ранга 1? Нужно ли использовать RESHAPE для сжатия массива? Или проблема в том, что при использовании array(:,1) я указываю вектор столбца, а не вектор строки? Большое спасибо за ваше время.

1 Ответ

4 голосов
/ 03 августа 2011

Вы указываете размещаемый массив ранга 2 с именем time:

INTEGER, DIMENSION(:,:), ALLOCATABLE :: array, time

и затем пытаетесь выделить его как массив ранга 1:

  ALLOCATE(time(numrows))

- don 'сделать это.Это прекрасно работает:

PROGRAM test
  IMPLICIT NONE
  INTEGER, PARAMETER :: numrows=4, numcols=10
  INTEGER :: i, j, k
  INTEGER, DIMENSION(:,:), ALLOCATABLE :: array
  INTEGER, DIMENSION(:), ALLOCATABLE :: time

  ALLOCATE(array(numrows,numcols))
  ALLOCATE(time(numrows))

  k=1
  DO i=1,numrows
    DO j=1,numcols
      array(i,j)=k
      k=k+1
    END DO
  END DO

  DO i=1,numrows
    WRITE(*,"(100(3X,I3))") (array(i,j), j=1,numcols)
  END DO

  time=array(:,1)
END PROGRAM test
...