정보
-
업무명 : 포트란을 활용한 배열 : 개요, 정합성 요구, 배열 작성자 (constructor), 마스크된 배열 할당 (where문), 동적배열, 배열함수
-
작성자 : 이상호
-
작성일 : 2020-11-26
-
설 명 :
-
수정이력 :
내용
[개요]
-
안녕하세요? 웹 개발 및 연구 개발을 담당하고 있는 해솔입니다.
-
Fortran (포트란)은 수식 (Formular) 변환기 (Translator)의 약자로 과학 계산용으로 주고 사용되는 언어입니다.
-
복잡한 계산 수행 성능이 뛰어나 공학과 자연과학 등 특정분야에 주로 사용되며 기상 데이터 처리를 위해 널리 사용되고 있습니다.
-
오늘 포스팅은 포트란을 활용한 배열을 소개합니다.
[특징]
-
기상 데이터 처리를 위해서 포트란 (Fortran)기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 기술서
[기능]
-
개 요
-
정합성 요구
-
배열 작성자 (constructor)
-
마스크된 배열 할당 (where문)
-
동적배열
-
배열함수
[활용 자료]
-
없음
[자료 처리 방안 및 활용 분석 기법]
-
없음
[사용법]
-
없음
[사용 OS]
-
Linux (CentOS v7.8)
[사용 언어]
-
gfortran v4.8.5
세부 내용
개요
-
프로그램을 개발하는 이유 중 하나는 많은 양의 데이터를 동일한 방법으로 빠르게 처리하기 쉽게 하기 위한 위함이 있습니다.
-
예를 들면 수 많은 숫자 세트들 중 평균 값을 찾기 위해, 또는 방대한 양의 숫자 또는 이름 목록을 정렬하기 위하여, 또는 많은 학생들의 시험 결과를 분석하는 등 입니다.
-
이러한 데이터를 처리 하기 위하여 우리는 배열을 이용할 수 있습니다.
-
배열은 하나의 이름으로 참조할 수 있는 같은 타입의 변수나 상수의 집합이라고 할 수 있습니다.
-
이 집합은 메모리 상에서 연속적인 위치를 점유하게 됩니다.
-
연속적인 위치에 있기에 같은 반복적인 연산은 DO문을 이용하여 수 많은 데이터에 적용 할 수 있습니다.
-
혹은 특정 조건에 해당하는 경우만 WHERE문을 통해 계산 할 수 있습니다.
-
포트란에서는 조건만 만족한다면 배열끼리 연산도 가능합니다.
-
배열을 사용할 때 기본적인 다음 사항을 지키는 습관이 중요합니다.
-
배열 사용 전 에는 반드시 초기화
-
초기화를 하지 않을 경우 쓰레기(의도치 않은)값이 저장되어 잘못된 계산을 유발합니다.
-
-
배열 크기를 파라미터를 이용하여 선언하라
-
배열 크기를 항상 유의 해야 합니다. 의도했던 크기보다 넘어갈 경우 에러가 발생하거나 위와 비슷한 상황이 발생합니다.
-
-
정합성 요구
-
포트란에서는 반드시 스칼라로 제한되어 사용되는 소수의 연산을 제외하고는 어떤 연산도 배열을 피연산수로 가질 수 있으며 그 결과도 배열이 될 수 있습니다.
-
거의 모든 표현에 배열을 직접 사용할 수 있도록 함으로써 데이터 병렬을 지원하고 있습니다.
REAL, DIMENSION(100) :: a, b
a=2.0
b=b*a
-
배열 연산에서의 정합성 요구는 연산에 참여하는 배열들의 모양이 서로 일치해야 함을 의미합니다.
-
배열 연산에서 사용되는 피연산수 즉 배열은 서로 같은 차원을 가져야 하며 각 차원마다 원소의 개수가 같아야 한다는 것 입니다.
-
물론 연산의 결과 역시 연산에 참여한 배열들과 같은 모양을 가지게 될 것입니다.
-
간단하게 수학에서 배운 행렬연산을 생각하시면 이해가 쉬울 듯 합니다.
-
이와 같은 연산의 정의로 인해 연산에 참여하는 각 배열의 모양이 같아야 한다는 정합성 요구를 이해할
수 있습니다.
-
그러나 한가지 예외 사항이 있는데 피연산수 중 하나로 스칼라가 올 때입니다. 배열 B에 대해 B+2는 유효한 연산입니다.
배열 작성자 (constructor)
[암시적 DO 구문]
-
포트란에서는 1차원 배열을 명시적으로 구성 하기 위하여 배열 작성자(array constructor)를 이용할수 있습니다.
-
배열 작성자는 (/1, 2, 3, 4/)와 같이 (/…/)내에 콤마로 배열의 원소를 구분해 나열하는 것을 말합니다.
-
일반적으로 배열 작성자의 각 원소는 어떤 스칼라 표현도 가능합니다.
-
스칼라 표현과 더불어 배열 작성자의 원소를 나타내는 방법으로 암시적 DO구문과 배열표현이 있습니다.
-
암시적 DO 구문은 다음과 같은 형식을 가집니다.
(/ expression-list, index-variable=first-value, last-value[,increment]/)
-
표현식 (/(k, k=1,n)/)는 원소가 1,2,3, …,n으로 주어지는 1차원 벡터를 생성하며 n=4 이면 (/1,2,3,4/)가 됩니다.
(/1,0,1,0,1,...../) = (/(1,0, j=1,500000)/) ! 1과 0이 반복되는 100만개의 원소로 구성 되는 벡터
(/ ((i + j, i = 1, 3), j = 1, 2) /) ! = (/ 2, 3, 4, 3, 4, 5 /) ! 암시적 DO 구문을 대응되는 스칼라 표현
[배열표현]
-
배열 표현은 임의 차원의 배열을 이용해 배열 작성자를 구성하는 것입니다.
-
배열 A 가 1000ⅹ1000의 2차원 배열일 때 (/A+1.3/)은 100만개의 원소를 가지는 배열 작성자가 됩니다.
-
각 원소는 배열 A의 각 원소에 1.3을 더한 값이 되며, 1열 1000개, 2 열 1000개, … 와 같이 열-우선 순으로 나열돼 하나의 배열 작성자를 구성합니다.
(/A+1.3/) = (/ ( ( A(j,k)+1.3, j=1,1000 ), k=1,1000 ) /)
-
여기서 A+1.3의 원소를 열-우선 순으로 나열하지 않고 행-우선 순으로 나열된 배열 작성자를 원한다면다음과 같이 암시적 DO구문을 이용합니다.
(/ ( ( A(j,k)+1.3, k=1,1000 ), j=1,1000 ) /)
[RESHAPE 함수]
-
1차원으로 정의되는 배열 작성자를 이용해 원하는 모양의 배열을 구성하기 위해서 내부함수 RESHAPE를 사용할 수 있습니다. RESHAPE 함수는 다음과 같은 형태로 사용합니다.
RESHAPE (array-constructor, shape-vector)
-
shape-vector는 원하는 배열 모양에 대한 각 차원의 크기를 지정하는 값을 (/ …/)로 묶어 나타냅니다.
REAL, DIMENSION (3,2) :: ra
ra = RESHAPE((/ ((i+j,i=1,3),j=1,2)/), SHAPE=(/3,2/))
-
다음은 1000ⅹ1000크기의 실수타입 단위 행렬을 배열 작성자와 RESHAPE 함수를 이용해 Ident_1000이라는 이름을 가지는 배열 상수로 정의한 것입니다.
REAL, PARAMETER, DIMENSION(1000,1000) :: Ident_1000 = &
RESHAPE( ( /(1.0,(0.0,k=1,1000),j=1,999),1.0/ ), (/1000,1000/))
마스크된 배열 할당 (where문)
[WHERE 문]
-
마스크(mask)란 배열자료값을 이용한 논리형 표현식으로 마스크된 배열 연산은 배열의 각 원소에 병렬로 수행되는 연산이 일부 원소에만 적용되도록 logical 타입의 마스크를 사용하는 것입니다.
-
마스크를 통하여 배열에 값을 할당하기 위해 WHERE 문을 사용합니다.
WHERE (mask) array-assignment-statement
-
WHERE 구문의 마스크 원소가 .TRUE.일 때 이에 대응되는 배열 원소에 값이 할당 되며, .FALSE.가 되면 값이 할당되지 않습니다.
-
다음은 마스크를 이용해 배열의 일부 원소에 값을 할당하는 예제 입니다.
WHERE (C .NE. 0) A = B/C
-
여러 개의 할당에 하나의 마스크를 적용할 수 있으며 이때 WHERE 문은 다음과 같이 블록화 됩니다.
WHERE (mask)
array-assignment-1
array-assignment-2
.........
END WHERE
-
또한 블록화된 WHERE 문에 ELSE WHERE 옵션을 덧붙여 사용하면 마스크 원소가 .FALSE.일 때도 배열에 값을 할당하도록 할 수 있습니다.
WHERE (C .NE. 0)
A = B/C
ELSE WHERE
A = B
END WHERE
동적배열
[Automatic Array]
-
포트란이 지원하는 동적 배열은 프로그램 실행 중에 메모리가 할당되며 배열의 크기를 프로그램에서 계산되는 값 또는 입력 값으로 결정할 수 있습니다.
-
동적 배열은 automatic array, allocatable array, 그리고 pointer array 이렇게 세 가지 형태가 있습니다.
-
Automatic array는 크기가 dummy 인수에 의해 결정되는 지역 배열입니다.
-
프로시저 내에서 자동 생성되고 프로시저의 종료와 함께 자동으로 소멸됩니다.
-
크기가 프로시저의 dummy 인수에 의해 결정되므로 프로시저가 호출될 때 마다 그 크기는 달라 질 수 있습니다.
-
다음 예에서 배열 work1 과 work2 는 automatic array의 예입니다.
SUBROUTINE sub(n, a)
IMPLICIT NONE
INTEGER :: n
REAL, DIMENSION(n, n) :: a
REAL, DIMENSION (n, n) :: work1
REAL, DIMENSION (SIZE(a, 1)) :: work2
END SUBROUTINE sub
[Allocatable Arrays]
-
포트란에서는 ALLOCATE 문을 이용해 메모리를 동적으로 할당할 수 있습니다.
-
Allocatable array 는 다음과 같이 ALLOCATABLE attribute 로 선언하여 사용합니다.
PROGRAM simulate
IMPLICIT NONE
INTEGER :: n
INTEGER, DIMENSION(:,:), ALLOCATABLE :: a
END PROGRAM simulate
-
배열의 이름과 차원은 위와 같이 미리 결정되어 있어야 하지만 그 크기는 다음과 같이 입력 값으로부터받아오거나 프로그램 실행 중에 계산되는 값에 의해 결정됩니다.
PRINT *,'Enter n:'
READ *,n
IF(.NOT.ALLOCATED(a)) ALLOCATE( a(n,2*n) )
........
DEALLOCATE(a)
-
Allocatable array 는 프로시저 내에서 지역적으로 사용될 수도 있고 프로그램 전체에서 global 하게 사용될 수도 있습니다.
-
allocatable array를 더 이상 사용할 필요가 없다면 DEALLOCATE 문을 이용해 해제 시켜야 합니다.
-
그렇지만 , 프로시저 내에서 지역적으로 사용된 allocatable array는 SAVE로 명시해 두지 않은 경우 프로시저의 종료와 함께 자동으로 소멸됩니다.
[Pointer Arrays]
-
pointer array는 ALLOCATE 문을 이용해 명시적으로 할당되고 실행 중에 결정되는 크기를 가지며DEALLOCATE 문을 이용해 명시적으로 할당 해제 된다는 점에서 allocatable array와 유사합니다.
-
pointer array는 target으로 명시적으로 선언된 다른 배열과 배열 부분에 대한 aliasing 을 위해 사용됩니다.
REAL, TARGET :: B(100,100) ! 배열 B 는 target 속성을 가진다 .
REAL, POINTER :: U(:,:),V(:),W(:,:) ! 3 개의 포인터 배열 선언
...
U => B(I:I+2,J:J+2) ! U 는 B 의 3X3 부분을 point
ALLOCATE ( W(M,N) ) ! 크기가 MXN 인 W 를 동적할당
V => B(:,J) ! V는 B 의 J 번째 열을 point
V => W(I-1,1:N:2) ! V는 W 의 I-1 번째 열의 일부를 point 하도록 바꿈
-
allocatable 로 선언하는 대신 포인터 로 선언
-
다른 배열 또는 배열 부분으로의 대체(aliasing) 을 위해 사용
-
allocatable array의 모든 기능을 포함하지만 상대적으로 복잡하여 효율적인 면에서 좋지 않음
-
지역적으로 계산되는 값에 의존하는 크기를 가지는 동적 배열의 정의를 위해 일반적으로 allocatable array를 많이 사용합니다.
-
그러나 알고리즘에서 동적 대체(aliasing)가 필요한 경우에 pointer array를 사용하게 됩니다.
-
관련하여 보다 자세한 내용은 포인터와 같이 다시 한번 이야기 하겠습니다.
참고 문헌
[논문]
- 없음
[보고서]
- 없음
[URL]
- Fortran을 활용한 분석, 날씨마루 (기상기후 빅데이터 분석 플랫폼), bd.kma.go.kr/kma2020/dta/edu/KBP57200_Fortran.do?pageNum=5&menuCd=F040304000.
문의사항
[기상학/프로그래밍 언어]
- sangho.lee.1990@gmail.com
[해양학/천문학/빅데이터]
- saimang0804@gmail.com
'프로그래밍 언어 > Fortran' 카테고리의 다른 글
[Fortran] 인텔 (intel) 포트란 도움말 정보 (ifort --help) (0) | 2021.02.24 |
---|---|
[Fortran] 포트란을 활용한 인터페이스 : 개요, 외부 프로시저, 내부 프로시저, INTENT, 모듈 (0) | 2020.12.03 |
[Fortran] 포트란 기초 및 활용 문서 (4) | 2020.11.17 |
[Fortran] 포트란을 활용한 에러 : 개요, NaN and Inf3, 예외 처리 (Exception), 에러 종류와 예시 (0) | 2020.11.11 |
[Fortran] 포트란을 활용한 기초 2 : 상수,키워드, 기본 제어입출력, 연산자 (논리, 관계, IF, CASE, DO, CYCLE) (0) | 2020.11.10 |
최근댓글