수색…


기본 표기법

모든 유형의 치수 특성하거나 직접 표시하여 사용하거나 배열로 선언 될 수 dimension 어레이 (들) :

! One dimensional array with 4 elements
integer, dimension(4) :: foo

! Two dimensional array with 4 rows and 2 columns
real, dimension(4, 2) :: bar

! Three dimensional array
type(mytype), dimension(6, 7, 8) :: myarray

! Same as above without using the dimension keyword
integer :: foo2(4)
real :: bar2(4, 2)
type(mytype) :: myarray2(6, 7, 8)

후자의 다차원 배열 선언 방법은 다음과 같이 동일한 유형의 다른 랭크 / 차원 배열을 한 줄에 선언 할 수있게합니다

real :: pencil(5), plate(3,-2:4), cuboid(0:3,-10:5,6)

허용되는 최대 순위 (차원 수)는 Fortran 2008 표준에서 15이며 전에 7이었습니다.

Fortran은 컬럼 우선 순위로 배열을 저장합니다. 즉, bar 의 요소는 다음과 같이 메모리에 저장됩니다.

bar(1, 1), bar(2, 1), bar(3, 1), bar(4, 1), bar(1, 2), bar(2, 2), ...

포트란에서 배열 번호는 기본적으로 0 부터 시작하는 C와는 달리 1 로 시작합니다. 사실 Fortran에서는 각 차원에 대한 상한 및 하한을 명시 적으로 지정할 수 있습니다.

integer, dimension(7:12, -3:-1) :: geese

이것은 shape (6, 3) 의 배열을 선언하며, 첫 번째 요소는 geese(7, -3) 입니다.

2 (또는 그 이상) 차원을 따라 상한 및 하한은 내장 함수 uboundlbound 통해 액세스 할 수 있습니다. 실제로 lbound(geese,2)-3 을 반환하지만 ubound(geese,1)12 반환합니다.

배열의 크기는 내장 함수 size 로 액세스 할 수 있습니다. 예를 들어 size(geese, dim = 1) 는 첫 번째 측정 기준의 크기 인 6을 반환합니다.

할당 가능 배열

배열은 할당 가능한 속성을 가질 수 있습니다 :

! One dimensional allocatable array
integer, dimension(:), allocatable :: foo
! Two dimensional allocatable array
real, dimension(:,:), allocatable :: bar

이것은 변수를 선언하지만 변수를위한 공간을 할당하지 않습니다.

! We can specify the bounds as usual
allocate(foo(3:5))

! It is an error to allocate an array twice
! so check it has not been allocated first
if (.not. allocated(foo)) then
  allocate(bar(10, 2))
end if

변수가 더 이상 필요하지 않으면 할당을 해제 할 수 있습니다.

deallocate(foo)

어떤 이유로 allocate 문이 실패하면 프로그램이 중지됩니다. stat 키워드를 통해 상태를 확인하면이 문제를 방지 할 수 있습니다.

real, dimension(:), allocatable :: geese
integer :: status

allocate(geese(17), stat=status)
if (stat /= 0) then
  print*, "Something went wrong trying to allocate 'geese'"
  stop 1
end if

deallocate 문에는 stat 키워드가 있습니다.

deallocate (geese, stat=status)

status 는 할당 또는 할당 해제가 성공한 경우 값이 0 인 정수 변수입니다.

배열 생성자

rank-1 배열 값은 배열 생성자 를 사용하여 구문을 사용하여 만들 수 있습니다.

(/ ... /)
[ ... ]

[...] 형식은 Fortran 2003에 도입되었으며 일반적으로 특히 복잡한 표현식에서 더 명확하게 인식됩니다. 이 양식은이 예제에서 독점적으로 사용됩니다.

배열 생성자에 포함 된 값은 스칼라 값, 배열 값 또는 암시 적 루프 일 수 있습니다.

구성된 배열의 형식 및 형식 매개 변수는 배열 생성자의 값과 일치합니다.

[1, 2, 3]      ! A rank-1 length-3 array of default integer type
[1., 2., 3.]   ! A rank-1 length-3 array of default real type
["A", "B"]     ! A rank-1 length-2 array of default character type

integer, parameter :: A = [2, 4]
[1, A, 3]      ! A rank-1 length-4 array of default integer type, with A's elements

integer i
[1, (i, i=2, 5), 6]  ! A rank-1 length-6 array of default integer type with an implied-do

위 양식에서 주어진 모든 값은 동일한 유형 및 유형 매개 변수 여야합니다. 혼합 유형 또는 유형 매개 변수는 허용되지 않습니다. 다음 예제 는 유효하지 않습니다.

[1, 2.]      ! INVALID: Mixing integer and default real
[1e0, 2d0]   ! INVALID: Mixing default real and double precision
[1., 2._dp]  ! INVALID: Allowed only if kind `dp` corresponds to default real
["Hello", "Frederick"]  ! INVALID: Different length parameters

서로 다른 유형을 사용하여 배열을 구성하려면 배열에 대한 유형 지정이 주어져야한다.

[integer :: 1, 2., 3d0]    ! A default integer array
[real(dp) :: 1, 2, 3._sp]  ! A real(dp) array
[character(len=9) :: "Hello", "Frederick"]  ! A length-2 array of length-9 characters

후자의 문자 배열 형식은 스페이스 패딩을 피하는 것이 특히 편리하다.

["Hello    ", "Frederick"]  ! A length-2 array of length-9 characters

constant라는 배열의 크기는 값을 설정하는 데 사용 된 배열 생성자에 의해 암시 될 수 있습니다.

integer, parameter :: ids(*) = [1, 2, 3, 4]

길이 매개 변수화 된 유형의 경우 길이 매개 변수가 가정 될 수 있습니다

character(len=*), parameter :: names(*) = [character(3) :: "Me", "You", "Her"]

형식 지정은 길이가 0 인 배열의 구성에도 필요합니다. 에서

[ ] ! Not a valid array constructor

존재하지 않는 값 세트에서 유형 및 유형 매개 변수를 판별 할 수 없습니다. 길이가 0 인 기본 정수 배열을 만들려면 :

[integer :: ]

배열 생성자는 순위 1 배열 만 구성합니다. 명명 된 상수의 값을 설정할 때와 같이 상위 배열 배열도 필요합니다. 구성된 rank-1 배열을 사용하여 reshape 된 결과에서 더 높은 순위의 배열을 얻을 수 있습니다.

integer, parameter :: multi_rank_ids(2,2) = RESHAPE([1,2,3,4], shape=[2,2])

배열 생성자에서 값 목록에있는 모든 배열을 가진 요소 순서의 배열 값은 개별 요소가 배열 요소 순서대로 자체적으로 주어진 것처럼 존재합니다. 따라서 이전 예제

integer, parameter :: A = [2, 4]
[1, A, 3]      ! A rank-1 length-4 array of default integer type, with A's elements

~에 해당합니다.

[1, 2, 4, 3]   ! With the array written out in array element order

일반적으로 생성자의 값은 중첩 배열 생성자를 포함하여 임의의 표현식이 될 수 있습니다. 이러한 배열 생성자가 상수 또는 사양 표현식과 같은 특정 조건을 충족 시키려면 제한이 구성 값에 적용됩니다.


배열 생성자가 아니더라도 특정 배열 값은 spread 내장 함수를 사용하여 편리하게 만들 수 있습니다. 예를 들어

[(0, i=1,10)]  ! An array with 10 default integers each of value 0

함수 참조의 결과이기도합니다.

SPREAD(0, 1, 10)

배열 자연 스팩 : 순위 및 모양

객체의 dimension 속성은 해당 객체가 배열임을 나타냅니다. Fortran 2008에는 5 개의 어레이 본성이 있습니다. 1

  • 명백한 모양
  • 가정 된 모양
  • 가정 된 크기
  • 지연된 모양
  • 내포 된 모양

3 개의 순위 1 배열 2를 취하십시오.

integer a, b, c
dimension(5) a    ! Explicit shape (default lower bound 1), extent 5
dimension(:) b    ! Assumed or deferred shape
dimension(*) c    ! Assumed size or implied shape array

이것들을 통해 어레이의 특성을 완전히 결정하기 위해서는 더 많은 컨텍스트가 필요하다는 것을 알 수 있습니다.

노골적인 모양

명시 적 모양 배열은 항상 해당 선언의 모양입니다. 배열이 서브 프로그램이나 block 구조에 대해 로컬로 선언되지 않는 한 모양을 정의하는 경계는 상수 표현이어야합니다. 다른 경우, 명시 적 모양 배열은 서브 프로그램이나 block 의 각 호출마다 다를 수있는 범위를 사용하여 자동 객체가 될 수 있습니다.

subroutine sub(n)
  integer, intent(in) :: n
  integer a(5)   ! A local explicit shape array with constant bound
  integer b(n)   ! A local explicit shape array, automatic object
end subroutine

가정 된 모양

가정 된 모양 배열은 allocatable 또는 pointer 속성이없는 더미 인수입니다. 이러한 배열은 연결된 실제 인수에서 모양을 취합니다.

integer a(5), b(10)
call sub(a)   ! In this call the dummy argument is like x(5)
call sub(b)   ! In this call the dummy argument is like x(10)

contains

  subroutine sub(x)
    integer x(:)    ! Assumed shape dummy argument
  end subroutine sub

end

가명 인수가 모양을 가정하면 프로 시저를 참조하는 범위는 해당 프로 시저에 사용할 수있는 명시 적 인터페이스를 가져야합니다.

가정 된 크기

가정 된 크기 배열은 실제 인수에서 가정 된 크기를 갖는 가짜 인수입니다.

subroutine sub(x)
  integer x(*)   ! Assumed size array
end subroutine

가정 된 크기 배열은 가정 된 모양 배열과 매우 다르게 동작하며 이러한 차이점은 다른 곳에서 문서화됩니다.

지연된 모양

지연 모양 배열은 allocatable 또는 pointer 속성이있는 배열입니다. 이러한 배열의 모양은 할당 또는 포인터 할당에 의해 결정됩니다.

integer, allocatable :: a(:)
integer, pointer :: b(:)

함축 된 모양

묵시적 쉐이프 배열은 값을 설정하는 데 사용 된 표현식에서 모양을 취하는 명명 된 상수입니다.

integer, parameter :: a(*) = [1,2,3,4]

더미 인수에 대한 배열 선언의 의미는 다른 곳에서 문서화되어야합니다.


1 Fortran 2008을 확장 한 기술 사양은 여섯 번째 배열 특성 인 가정 순위를 추가합니다. 여기서는 다루지 않습니다.

2 이것들은 등가 적으로 다음과 같이 쓸 수있다.

integer, dimension(5) :: a
integer, dimension(:) :: b
integer, dimension(*) :: c

또는

integer a(5)
integer b(:)
integer c(*)

전체 배열, 배열 요소 및 배열 섹션

다음과 같이 선언 된 배열을 고려하십시오.

real x(10)

그 다음 우리는 관심의 3 가지 측면을 가지고 있습니다 :

  1. 전체 배열 x ;
  2. x(1) 과 같은 배열 요소;
  3. x(2:6) 와 같은 배열 섹션.

전체 배열

대부분의 경우 전체 배열 x 는 배열의 모든 요소를 ​​단일 엔터티로 참조합니다. print *, SUM(x) , print *, SIZE(x) 또는 x=1 과 같은 실행 문에 나타날 수 있습니다.

전체 배열은 명시 적으로 모양이 지정되지 않은 배열을 참조 할 수 있습니다 (예 : 위의 x ).

function f(y)
  real, intent(out) :: y(:)
  real, allocatable :: z(:)

  y = 1.         ! Intrinsic assignment for the whole array
  z = [1., 2.,]  ! Intrinsic assignment for the whole array, invoking allocation
end function

가정 된 크기 배열은 전체 배열로 나타날 수도 있지만 제한된 환경에서만 나타납니다 (다른 곳에서 문서화해야 함).

배열 요소

배열 요소는 배열의 각 순위에 대해 정수 인덱스를 제공하여 전체 배열의 위치를 ​​나타냅니다.

real x(5,2)
x(1,1) = 0.2
x(2,4) = 0.3

배열 요소는 스칼라입니다.

배열 섹션

배열 섹션은 콜론을 사용하는 구문을 사용하여 전체 배열의 여러 요소 (아마도 하나만 포함)에 대한 참조입니다.

real x(5,2)
x(:,1) = 0.         ! Referring to x(1,1), x(2,1), x(3,1), x(4,1) and x(5,1)
x(2,:) = 0.         ! Referring to x(2,1), x(2,2)
x(2:4,1) = 0.       ! Referring to x(2,1), x(3,1) and x(4,1)
x(2:3,1:2) = 0.     ! Referring to x(2,1), x(3,1), x(2,2) and x(3,2)
x(1:1,1) = 0.       ! Referring to x(1,1)
x([1,3,5],2) = 0.   ! Referring to x(1,2), x(3,2) and x(5,2)

위의 마지막 형식은 벡터 첨자를 사용합니다. 이것은 다른 배열 섹션을 넘어 여러 가지 제한 사항이 있습니다.

각 요소 섹션은 하나의 요소 만 참조되는 경우에도 자체적으로 배열입니다. 즉, x(1:1,1)x(1:1,1) 의 배열이고 x(1:1,1:1) 는 2의 배열입니다.

배열 섹션에는 일반적으로 전체 배열의 속성이 없습니다. 특히, 어디에서

real, allocatable :: x(:)
x = [1,2,3]     ! x is allocated as part of the assignment
x = [1,2,3,4]   ! x is dealloacted then allocated to a new shape in the assignment

과제

x(:) = [1,2,3,4,5]   ! This is bad when x isn't the same shape as the right-hand side

허용되지 않는다 : x(:) , 모든 요소 어레이 부 있지만 x , 할당 가능한 배열이 아니다.

x(:) = [5,6,7,8]

x 가 오른쪽의 모양 일 때 괜찮습니다.


배열의 배열 구성 요소

type t
   real y(5)
end type t

type(t) x(2)

우리는 더 복잡한 설정에서 전체 배열, 배열 요소 및 배열 섹션을 참조 할 수도 있습니다.

위에서 x 는 전체 배열입니다. 우리도 가지고있다

x(1)%y        ! A whole array
x(1)%y(1)     ! An array element
x%y(1)        ! An array section
x(1)%y(:)     ! An array section
x([1,2]%y(1)  ! An array section
x(1)%y(1:1)   ! An array section

그러한 경우 우리는 랭크 1의 배열로 구성된 참조의 한 부분 이상을 가질 수 없다. 예를 들어, 다음은 허용되지 않는다.

x%y             ! Both the x and y parts are arrays
x(1:1)%y(1:1)   ! Recall that each part is still an array section

배열 연산

계산상의 목표로 인해, 배열에 대한 수학 연산은 Fortran에서 간단합니다.

더하기 및 빼기

같은 모양과 크기의 배열에 대한 연산은 행렬 대수와 매우 유사합니다. 루프가있는 모든 인덱스를 실행하는 대신 추가 (및 빼기)를 작성할 수 있습니다.

real, dimension(2,3) :: A, B, C
real, dimension(5,6,3) :: D
A    = 3.    ! Assigning single value to the whole array
B    = 5.    ! Equivalent writing for assignment
C    = A + B ! All elements of C now have value 8.
D    = A + B ! Compiler will raise an error. The shapes and dimensions are not the same

분할에서 배열도 유효합니다 :

integer :: i, j
real, dimension(3,2) :: Mat = 0.
real, dimension(3)   :: Vec1 = 0., Vec2 = 0., Vec3 = 0.
i = 0
j = 0
do i = 1,3
  do j = 1,2
    Mat(i,j) = i+j
  enddo
enddo
Vec1 = Mat(:,1)
Vec2 = Mat(:,2)
Vec3 = Mat(1:2,1) + Mat(2:3,2)

기능

같은 방식으로, 대부분의 내장 함수는 구성 요소 방식의 연산을 가정하여 암시 적으로 사용될 수 있습니다 (체계적이지는 않지만).

real, dimension(2) :: A, B
A(1) = 6
A(2) = 44 ! Random values
B    = sin(A) ! Identical to B(1) = sin(6), B(2) = sin(44).

곱셈과 나눗셈

제품 및 부문에주의를 기울여야합니다. */ 기호를 사용하는 본질적인 작업은 요소별로 이루어집니다.

real, dimension(2) :: A, B, C
A(1) = 2
A(2) = 4
B(1) = 1
B(2) = 3
C = A*B ! Returns C(1) = 2*1 and C(2) = 4*3

이것은 행렬 연산과 혼동해서는 안됩니다 (아래 참조).

행렬 연산

매트릭스 연산은 내장 프로 시저입니다. 예를 들어, 이전 섹션의 배열의 행렬 곱은 다음과 같이 작성됩니다.

real, dimension(2,1) :: A, B
real, dimension(1,1) :: C
A(1) = 2
A(2) = 4
B(1) = 1
B(2) = 3
C = matmul(transpose(A),B) ! Returns the scalar product of vectors A and B

복잡한 연산을 사용하면 임시 배열을 만들어 함수를 캡슐화 할 수 있습니다. 일부 컴파일러 및 컴파일 옵션에서 허용되지만 권장되지는 않습니다. 예를 들어, 행렬 전치를 포함하는 제품은 다음과 같이 쓸 수 있습니다.

real, dimension(3,3) :: A, B, C
A(:) = 4
B(:) = 5
C = matmul(transpose(A),matmul(B,matmul(A,transpose(B)))) ! Equivalent to A^t.B.A.B^T

고급 배열 섹션 : 첨자 삼중 항 및 벡터 첨자

다른 예 에서 언급했듯이 배열 섹션이라고하는 배열 요소의 하위 집합이 참조 될 수 있습니다. 그 예에서 우리는 가질 수 있습니다.

real x(10)
x(:)   = 0.
x(2:6) = 1.
x(3:4) = [3., 5.]

배열 섹션은 이것보다 더 일반적 일 수 있습니다. 그들은 첨자 세 쌍 또는 벡터 첨자의 형태를 취할 수 있습니다.

첨자 셋잇단

첨자 트리플은 [bound1]:[bound2][:stride] 의 형태를 취합니다. 예를 들어

real x(10)
x(1:10) = ...   ! Elements x(1), x(2), ..., x(10)
x(1:) = ...     ! The omitted second bound is equivalent to the upper, same as above
x(:10) = ...    ! The omitted first bound is equivalent to the lower, same as above
x(1:6:2) = ...  ! Elements x(1), x(3), x(5)
x(5:1) = ...    ! No elements: the lower bound is greater than the upper
x(5:1:-1) = ... ! Elements x(5), x(4), x(3), x(2), x(1)
x(::3) = ...    ! Elements x(1), x(4), x(7), x(10), assuming omitted bounds
x(::-3) = ...   ! No elements: the bounds are assumed with the first the lower, negative stride

보폭 (0이 아니어야 함)이 지정되면, 요소의시 v 스는 지정된 첫 x 째 바운드로 시작합니다. 스트라이드가 양수인 경우 (음수) 시퀀스를 따라 선택한 요소가 두 번째 경계보다 크지 않은 마지막 요소 (최소 크기보다 작은 값)까지 스트라이드에 의해 증가 (감소)됩니다. 스트라이드가 생략되면 하나의 것으로 취급됩니다.

첫 x 째 Y 인드가 두 x 째 Y 인드보다 크고 스트라이드가 양수이면 요소가 지정되지 않습니다. 첫 x 째 Y 인드가 두 x 째 Y 인드보다 작고 스트라이드가 음수이면 요소가 지정되지 않습니다.

또한 주목해야한다 x(10:1:-1) 와 동일하지 x(1:10:1) 의 각 요소에도 x 두 경우 모두에 나타난다.

벡터 첨자

벡터 첨자는 랭크 -1 정수 배열입니다. 배열의 값에 해당하는 요소 시퀀스를 지정합니다.

real x(10)
integer i
x([1,6,4]) = ...     ! Elements x(1), x(6), x(4)
x([(i,i=2,4)]) = ... ! Elements x(2), x(3) and x(4)
print*, x([2,5,2])   ! Elements x(2), x(5) and x(2)

벡터 첨자가있는 배열 섹션은 사용 방법이 제한되어 있습니다.

  • 그것은 프로 시저에 정의 된 가짜 인수와 관련된 인수가 아닐 수도 있습니다.
  • 포인터 할당 문에서 대상이 아닐 수도 있습니다.
  • 데이터 전송 명령문의 내부 파일이 아닐 수도 있습니다.

또한, 동일한 요소가 두 번 선택 될 때 정의를 포함하는 명령문에 이러한 배열 섹션이 나타나지 않을 수 있습니다. 위에서:

print*, x([2,5,2])   ! Elements x(2), x(5) and x(2) are printed
x([2,5,2]) = 1.      ! Not permitted: x(2) appears twice in this definition

상위 순위 배열 섹션

real x(5,2)
print*, x(::2,2:1:-1)  ! Elements x(1,2), x(3,2), x(5,2), x(1,1), x(3,1), x(5,1)


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow