수색…
기본 표기법
모든 유형의 치수 특성하거나 직접 표시하여 사용하거나 배열로 선언 될 수 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 (또는 그 이상) 차원을 따라 상한 및 하한은 내장 함수 ubound
및 lbound
통해 액세스 할 수 있습니다. 실제로 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 가지 측면을 가지고 있습니다 :
- 전체 배열
x
; -
x(1)
과 같은 배열 요소; -
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)