포트란의 다중분기는 SELECT CASE 에 의해 이루어진다. C언어의 SWITCH 문과 비슷하다.

기본 구문은 다음과 같다.

SELECT CASE ( case expression )
CASE ( case selector 1 )
    ...
CASE ( case selector 2 )
   ...
...
CASE DEFAULT
   ...

END SELECT


case expression 부분에 들어가는 내용의 평가값은 정수형, 문자형(문자열포함), 논리형 이 가능하다.
case selector 는 case expression 의 평가값이 포함될 범위나 특정 값을 나타낸다.
case expression 의 평가값이,  case selector 들에 대해, 동시에 두개이상을 만족시켜서는 안된다.

case selector 가 특정값일 때는, 괄호안에 그 값을 써주면 된다.

특정값들의 목록일 경우에는 콤마(,) 를 이용하여 나열해준다.

범위일때는 콜론 (:) 을 이용한다. a : b   는  ' a 이상 b 이하 '  를   나타낸다.  
또한,   : b   는  'b 이하' 를 나타내고,    a :   는  'a 이상' 을 나타낸다.


( SELECT CASE 도 IF 와 마찬가지로 네이밍이 가능하다. )



기본자료형으로 복소수형을 제공하고, 게다가 실수와 믹스트모드 연산이 자유롭게 가능하므로,
이차방정식의 근을 구하는 프로그램을 몇줄로 간단히 짤 수 있다.

뭐, 이런저런 안내문을 집어넣으면 늘어나겠지만, 암튼 정말 간결하게 만들수 있다.

다음은 2차방정식의 근을 구하는 예제 코드이다.


다음은 실행결과의 예이다.


허수부가 0 으로 나오면 그건 실근인거고, 두근이 완전히 똑같게 나오면 중근인거다.

예를들어,    i  x^2   +   ( 1 + i ) x   + 1  =    0    을 풀어보면, 다음과 같이 된다.


따라서, 두 근은  x = -1  과    x = i   이다.

실행파일. 

qdeq.exe



조건 분기문 IF 의 구문은 다음과 같다.

IF (logical expression) THEN
        statements
END IF

IF 와 END IF 사이의 블락은 logical expression 의 논리값이 참일 경우에만 실행된다.

IF 문에 의해서 실행되는 문장이, 하나밖에 없을때에는, THEN 과 END IF 를 생략하고, 같은줄에 다음과 같은 형식으로 쓸 수 있다.

IF (logical expression) statement

END IF 로 블락을 묶어서 쓰는 IF 를 block-IF, 한줄IF 를 logical-IF 라고 부르기도 한다.



IF 를 사용한 다중분기는 ELSE 와 ELSE IF 를 이용한다.

구문은 다음과 같다.

IF (logical expr1) THEN
       statements
ELSE IF (logical expr2) THEN
       statements
ELSE IF ...
       ...
ELSE
       statements
END IF
    



라인 넘버링에 의한 레이블링 이외에, 포트란의 IF 문 또는 ELSE IF 문은 또다른 레이블링을 지원하는데, 이것은 특히, 네스티드(nested) IF 문의 경우에 어떤 ELSE IF 가 누구꺼인지, 어떤 END IF 가 어떤 IF 랑 대응되는지등을 표시할때 유용하다. 물론, 보통의 경우 인덴테이션으로도 충분하지만, 대형 프로그램의 경우 그렇지 않은경우도 있다.

레이블링 구문은 다음과 같다.

name: IF ( ... ) THEN
      ...
ELSE IF ( ... ) THEN [name]
     ...
...
ELSE [name]
     ...
END IF name

IF 문에 네이밍을 하면, END IF 문에도 똑같은 네이밍을 해야된다. 어떠한 IF 랑 짝인지를 보려고 하는거니까...
[ ] 로 표시한 부분은 optional 이다. 동일한 레벨의 IF 블락에 대해서는 같은 이름이 사용되어야 한다.
nested 된 경우에는, 부모IF 와 자식IF 가 당연히 다른 이름이 사용되어야 한다.
조건분기와 루프를 하려면, 우선 논리연산 부터 찾아봐야 한다.

포트란의 논리연산에 필요한 것은 다음과 같다.

1. 논리값

이름         코드            표시

참          .TRUE.          T
거짓       .FALSE.         F




2. 논리연산 

이름         연산자                       비고

논리곱       .AND.                      둘다참일때만 참, 나머진 거짓
논리합       .OR.                        둘다거짓일때만 거짓, 나머진 참
부정          .NOT.                      논리값을 반대로 뒤집는다.
동치          .EQV.                      논리값이 같으면 참, 다르면 거짓.           ( XOR 에 NOT 을 한것이다. )
비동치       .NEQV.                    논리값이 다르면 참, 같으면 거짓.           ( XOR 와 같다. )




3. 관계연산 ( 대소비교연산 )

대소비교에 의한 평가값은 논리값을 가진다.

연산자(기호)          연산자(문자)                   비고

==                         .EQ.                             같다                     EQual to
/=                         .NE.                             같지않다               Not Equal to
>                          .GT.                             크다                     Greater Than
<                          .LT.                              작다                     Less Than
>=                         .GE.                             크거나같다            Greater than or Equal to
<=                         .LE.                             작거나같다             Less than or Equal to










입력  READ ( io unit , format ) input list
출력  WRITE ( io unit , format ) output list

READ 와 WRITE 는 제어부와 입출력리스트로 구성된다.


input list 와 output list 는 comma(,) 에 의해 구분된다.

READ 에서,  실제 입력데이터는 콤마, 빈칸, 줄에 의해 구분된다.

입력값은 각 데이터형 상수 방식으로 입력한다.

가령 복소수를 입력할때는 ( a,b ) 꼴로 입력을 한다.
괄호없이 그냥 수로 입력하면, 실수로 처리되어 실수로 입력되고, 허수부는 0 이 된다.
이는 복소수 자료형이 실수형을 포함하는 데이터 타입이기 때문에 그렇다.

논리형이라면 .TRUE. 와 .FALSE. 로 입력하면 되는데, 이것이 상당히 번거로우므로, 간단히 T 와 F 로 입력할 수 있다.

그런데, READ 는 기본적으로 한줄로 부터 입력을 받는다.
한줄에 받기로한 데이터보다 더 많은 데이터가 입력될 경우, 버리기 때문에, 줄로 구분해서 데이터를 입력시 유의해야한다.
단, 입력이 부족할때는 다음줄로 부터 받을수 있다.



제어부

( ) 는 제어부로, 첫번째 부분은 입출력 유닛에 대한 부분이고, 두번째 부분은 입출력 포맷에 관한 부분이다.

 io unit 는 어디서 데이터를 읽어올 것인가를 나타낸다.
* 는 스탠다드 인풋 디바이스 를 나타내며, 보통 키보드 입력을 뜻한다.

format 은 입출력 형식에 관한 것이다.
* 는 list-directed (free format) 으로, input list 의 변수자료형이 입력받을 자료의 포맷을 결정한다는 의미이다.

io unit 과 format 에 대해서는 나중에 자세히 다루도록 한다.






C 에서 #define 으로, 상수에 이름을 붙여서 사용했던것과 비슷한 이유로 포트란에서도 상수에 이름을 붙여서 사용할수 있다.
이는 프로그램의 수정 및 이식에 있어서 상당히 중요하다.

C의 #define 이 컴파일전에, 코드를 치환하는 역할만 했던것과는 달리, 포트란에서는 키워드 PARAMETER 를 이용하여, 데이터타입을 지정해줄수 있다.

구문은 다음과 같다.

datatype, PARAMETER :: var_name = value , ...


예.




문자열상수에 이름을 붙이는 것도 가능하다.

인텔 포트란의 경우 다음과 같이 하면 된다.



포트란에서 수학교과서 냄새가 풀풀 나는 재밌는 컨벤션이 있는데, 바로 변수명 i , j , k , l , m , n  을 기본적으로 정수형 데이터로 취급한다는 것이다. 물론, 명시적으로 타입을 선언해주지 않았을때의 이야기이다. 수학시간에 툭하면 써메이션 변수로 i , j, k, l, m, n 을 쓰는 습관이 그대로 녹아있다.

참고로, 변수명이 i,j,k,l,m,n 으로 시작하는 모든 변수는, 명시적으로 타입을 선언하지 않았을 경우, 정수형으로 가정한다.

그밖에 다른 변수는, 타입이 명시되지 않으면, 실수타입으로 가정한다.





결과를 보면, i 와 k 로 시작하는 변수에 실수값 대입했음에도, 결과를 보면 정수로 찍혀있다.
이것은 두 변수를 정수형으로 인식한상태에서, 실수값을 대입해, 소숫점 이하의 데이터가 버려진 결과이다.



위와 같은 컨벤션은 상당히 편리할수 있지만,  예기치 못한 문제를 일으킬 수도 있다.

가령, 코딩중에 미스스펠의 오류를 범했다고 치자. 실제로는 프로그래밍중의 실수이지만, 포트란에서는 그것역시 새로운 변수로 받아들이고 이름에 따라서 정수형이나 실수형으로 처리해버린다. 이는 프로그래머가 의도한바가 아니므로, 에러가 나야하지만, 컴파일러는 에러를 내지 않는다.

에러가 나야하는 부분에서 에러가 나지 않는것 만큼 디버깅에 어려움이 없는것도 없다.


위와 같은 문제를 막기위해, 컨벤션을 금지시킬수 있는데, 바로 IMPLICIT NONE 을 사용하는 것이다.
이 문장은 PROGRAM 과 변수 선언부 사이에 들어가야 한다.

IMPLICIT NONE  이 들어갈 경우, 선언되지 않은 변수의 사용은 모두 에러로 간주한다.
즉, 모든 변수를 explicit 하게 선언해 주어야 한다.
포트란의 기본 자료형은 다음의 5 가지이다.

정수형 INTEGER
실수형 REAL
복소형 COMPLEX
논리형 LOGICAL
문자형/문자열 CHARACTER

( 세부적인 자료형의 규정은 KIND 로 배열은 DIMENSION 으로 한다. 또, C의 구조체와 마찬가지로, TYPE 을 통한, 사용자 정의 데이터형도 사용 가능하다. )


변수의 선언시 위의 키워드와 함께 :: 를 사용하는 것이 새로운 규약이다.
물론, 90/95 가 이전버전과 호환이 되도록 만들어졌기 때문에 :: 을 생략해도 되지만, 되도록 써주는 것이 좋다.

예.   INTEGER :: i , j



1. 정수형 데이터 타입

정수형 상수는 점을 찍을 경우, 실수로 인식한다.

예. 100 은 정수지만, 100. 과 같이 점을 찍으면 실수이다.

정수형 데이터가 메모리에 저장될때, 기본 크기는 해당 컴퓨터의 word 싸이즈에 의존한다.
가령 4바이트 워드 컴퓨터 ( 32비트 컴퓨터) 의 경우, 정수형 데이터는 기본 4바이트가 된다.

몇 바이트 형 정수형 데이터 타입을 쓸 것인가는 KIND 를 사용해서 기술할 수 있다.

INTEGER ( KIND = kindnumber ) :: variables
INTEGER ( kindnumber ) :: variables

kindnumber 는 보통 바이트수를 나타내는데, 꼭 그런건 아니며 컴퓨터/컴파일러에 의존적이다. 

사용하고자 하는 숫자가 몇바이트 정수형을 요구하는지를 체크하는 함수로 SELECTED_INT_KIND()수가 있다.

SELECTED_INT_KIND( range

가령 SELECTED_INT_KIND(x) 는  ( -10^x ,  +10^x ) 을 표현하는데 요구되는 최소 kind_number 를 준다.

예를 들어, 본인의 x200 / 인텔패럴렐스투디오 로 SELECTED_INT_KIND(18) 를 출력해보면, KIND = 8 이 나온다.
반면, SELECTED_INT_KIND(19) 는 -1 이 나오는데, 이는 해당범위를 나타낼수 있는 정수형 타입을 기본적으로 제공하지 않는다는 것이다.

정수형 상수의 경우에도, 메모리사이즈를 지정해줄수 있다. 상수 뒤에 underscore _ 와 kind 를 기술해주는 것이다.
예를 들어, 32 라고 하면, 이것은 디폴트 kind 를 갖는다.
그러나, 32_8 이라고 하면, 8바이트(64비트) 정수형 자료가 된다.

SELECTED_INT_KIND() 는 생긴건 이래 생겼어도, 엄연히 내장함수다 ㅡ_ㅡ;




10의 지수형 범위가 아니라, 그냥 해당 상수나, 해당 변수에 대해서 직접 KIND 를 주는 내장함수로 KIND() 가 있다.
이것은 자신의 디폴트를 확인하는데도 유용하다.

KIND( data )

예. KIND( 3 ) , KIND( 3_8 )             앞에꺼는 디폴트를 줄것이고, 뒤에껏은 8 을 준다.

예. KIND (i)                                  변수 i 의 KIND 를 보여준다.

참고로, KIND() 함수는, 정수형데이터에 국한되는 것이 아니라, 범용적으로 쓸 수 있는 함수이다.



2. 실수형 데이터 타입

실수형상수에서 지수형표기법은 E 와 D 를 사용하는데, E는 싱글프리시젼(single precision) , D는 더블 프리시전( double precision) 용이다.
(참고로, 유효숫자 부분에 소숫점을 찍는게 원칙.)

C에서 싱글프리시전으로 float , 더블프리시젼으로 double 을 썼던것과 비슷하게, 포트란에서는 KIND 를 이용해, 실수 자료형의 정밀도를 선택할 수 있다.

참고로, 보통, 32bit 워드 컴퓨터의 경우 보통 싱글 프리시젼이 싱글워드(32bit), 더블 프리시젼이 더블워드(64bit) 인데,
64비트 프로세서의 경우 싱글이 64비트, 더블이 128비트인 경우도 있다.

가장 흔한 경우는, KIND = 4 가 4바이트실수(32비트)형 ,  KIND =8 이 8바이트실수(64비트)형이다.

역시, 실수형 상수 뒤에 underscore _ 와 kind number 를 써줌으로써, 상수데이터도 세부적인 데이터타입을 지정할수 있다.

예.    32.  은 디폴트,  32._8   은 KIND=8 이다.
        32.E0 은 싱글프리시젼, 32.D0 는 더블프리시전이다.   ( E0 나 D0 모두 10^0 승 이므로, 수치상의 변화는 없다. )

실수형 변수의 선언은 다음과 같다.

REAL(KIND= kind number) :: variables
REAL(kind number) :: variables

() 의 kind 는 옵션으로 생략하면 디폴트가 적용된다.

정수형에 SELECTED_INT_KIND() 함수가 있었던 것처럼, 실수형에는 SELECTED_REAL_KIND() 함수가 있다.

SELECTED_REAL_KIND( p= precision, rrange )

여기서, precision 은 유효숫자의 수이고, range 는 10의 지수범위이다.

리턴값은 kind number 이고,  precision 에서 오바되면 -1 , range 에서 오바되면 -2 , 둘다 오바되면 -3 을 리턴한다.

다음과 같은 형태로 입력해도 된다.
SELECTED_REAL_KIND( precisionrange )
SELECTED_REAL_KIND( p= precision )
SELECTED_REAL_KIND( rrange )
SELECTED_REAL_KIND( precision )





리얼 데이터의 프리시젼과 레인지를 갈챠주는 내장함수로 다음의 두 함수가 있다.

PRECISION( real_or_complex )
RANGE( real_or_complex )

두 함수 모두 인자로 실수데이터나 복소수데이터르 받는다.
precision() 은 decimal precision 을 리턴하고,
range() 는 decimal exponent range 를 리턴한다.

어떤 실변수가 있을때, 그 변수에 대한 제반정보 3가지 ( KIND , PRECISION, RANGE ) 를 아는 것은 때때로 중요하다. 그것은 코드가 다른 컴퓨터에서 수행될때를 고려할때 특히 더욱 그러하다. 많은경우, 코드를 짤때, 프로그램이 실행되는 환경에 맞춰 돌아갈수 있도록 위의 정보에 대한 부분을 삽입한다.


3. 복소형 데이터 타입

아무래도 계산에 특화된 프로그래밍 언어다보니, 복소형 타입이 사용자정의형으로 만들어서 쓰는게 아니라 그냥 기본형타입으로 지정되어있다.

복소상수는 (a,b) 꼴로 씌여지고, 이것은 a + i b 를 나타낸다. 여기서 a 와 b는 자동으로 실수타입으로 가정된다.


복소변수의 선언은 다음과 같다.
COMPLEX (KIND= kind number ) :: variables
COMPLEX (kind number ) :: variables

KIND 는 실수형과 같다. 다만, 실수타입 두개를 하나로 통채로 사용할 뿐이다.

복소수의 기본적인 사칙연산은 우리가 아는 그대로 적용된다.



복소수 타입은 실수 타입을 포함하는 데이터타입으로, 상당히 유연하여, 실수와 믹스트모드로 연산이 가능하다.
( 각종 혼합모드의 연산에 대해서는 따로 다루도록 한다. )

예를들어, 3 + (2,4) = (5,4) 로 연산된다.
즉, 복소수의 입출력에 있어서도, 괄호없이 실수만 입력할경우 그것을 실수부로 받아들이고, 허수부는 0 이 되도록 한다.

포트란의 복소수 타입은 사칙연산 외에도 다른 연산들을 지원하는데, 특히 염두에 둘 것은 거듭제곱 연산자 ** 이다.
가령, (3,2) **  0.5 이나 (3,2) ** (4,-1) 과 같은 연산이 가능하다.



4. 논리형 데이터 타입

논리상수는  .TRUE. 와 .FALSE.  두가지인데, 주의할 점은, 양쪽에 점을 찍어줘야 한다는 거다. 그렇지 않고, 그냥 TRUE 와 FALSE 로 넣게 되면, 변수명이 된다.

.TRUE. 와 .FALSE. 를 그냥 WRITE로 찍으면,  .TRUE. 는 T 로 , .FALSE. 는 F 로 인쇄된다.
논리형 타입의 입력시에도 .TRUE. 나 .FALSE 대신 T 와 F 로 간단히 입력할 수 있다.

논리형 변수 선언.

LOGICAL :: variables

대소비교 연산이나 조건분기 등의 조건문에 대한 평가는 논리값으로 이루어진다.

논리연산자에 대해서는 따로 다루기로 한다.



5. 문자형 데이터 타입

포트란의 문자 및 문자열 상수는 따옴표 ( single quote ) 나 쌍따옴표 ( double quote ) 를 사용한다.
C에서는 문자에 싱글 따옴표, 문자열에 더블 따옴표였는데, 포트란에서는 짝만 맞게 써주면 구분하지 않는다.

근데, 이것이 신기한 유용성을 가져다 준다.

가령,   Man's best friend    라는 문자열을 묶어서 문자열 상수로 만들때, 외따옴표로 묶는 방법과, 쌍따옴표로 묶는 방법을 살펴보면, 다음과 같다.

외따옴표   :     'Man''s best friend'                   어파스트로피를 찍기위해 ' 를 연달아 두번 찍어준다.
쌍따옴표   :     "Man's best friend"                    쌍따옴표로 묶을때는 어파스트로피가 문제되지 않는다.


쌍따옴표 자체가 들어있는 문장을 찍을때는 그 문장자체를 외따옴표로 감싸고, 혹시 그 안에 어파스트로피 있으면, 외따옴표를 연달아 써서 '를 찍도록 한다.

예를들어  "This is me."  를 나타내는 문자열상수는    ' "This is me." '         으로 쓸 수 있다.

예.



문자/문자열 변수의 선언은 다음과 같다.

CHARACTER :: single_character_variables

CHARACTER ( len = length ) :: string_variables
CHARACTER ( length ) :: string_variables

즉, 길이를 넣어주면 문자열이고, 안넣어주면 문자형이다.



참고로, 포트란 77 문법은 다음과 같다.

CHARACTER*length variables
CHARACTER variable_name1 * length1 , variable_name2 * length2 , ...



Datatype Conversion Functions

마지막으로, 데이터 타입 변환 함수에 대해서 살펴보자.

C에서 괄호를 이용해 캐스트연산자를 쓴것과 비슷하게, 포트란 90/95 에서 자료형변환 함수가 다음과 같이 제공된다.

INT(x)                    실수자료에서 소숫점이하 버리고 정수부분만 리턴한다.
NINT(x)                  소수부분을 반올림한 정수를 리턴한다. 앞의 N 은 nearest 를 의미한다.
REAL(i)                   정수값을 실수형으로 변환한다.



친구들이랑 녹두에 포텐X 당구장에서 당구를 치고, 집에 오는데, 애들하고 빠이빠이 흩어지고 거의 집에 도달했을때, 그 핸드폰을 포X샤 당구장에 놓고온 사실을 인지했다.

바로 택시를 타고 돌아가려다, 일단 당구장에 전화를 해보기로 마음먹고, 114 에 전화를 걸었는데, 전화번호가 없다.

음, 영세한 곳이라 등록 안했을수도 있겠다는 생각이 들어서 일단 집으로 들어가서, 자주 애용하는 다음 로드뷰로 간판을 확인해야지 생각했다.
간판에는 전화번호가 쪼매낳게 썼있을수 있으니까...

다음 로드뷰로 골목골목 찾아서, 간판을 찾았는데, 그집만 간판에 전화번호가 없다...

다시 나가서 바로 택시를 타고, 포텐X 당구장으로 갔다. ㅅㅂ 문닫았다. ㅠㅠ

그 앞집 당구장이랑 옆집 당구장은 불이 훤한데, 그집만 불끄고 깜깜하다. 안쪽엔 아무것도 시커매서 아무것도 안보이고..

주변을 살펴보니, 포X샤 당구장은, 간판을 4개나 쓰는데, 그 근처 어느곳에도 눈꼽만한 전화번호 하나 없다. OTL...

완벽한 내부 인테리어와 환기시스템이 어쩌고 뭐라 써놨는데... ㅡ.ㅡ 하얗게 페인트 칠해놓은게 인테리어 쩌는거였냐? 

아  띄뱅... 내일 아침에 중요한 약속있는데.. 놓고온건 내탓이지만... 거기도, 장사할 생각 없으면, 그냥 망해버렸으면 좋겠다. 잉~
포트란 (Fortran) 은 FORmula TRANslation 의 약자로, 수학/과학 계산을 위한 프로그래밍 언어이다.
C 가 더 범용적인데 반해, 포트란은 빠른 계산속도를 자랑한다.

사실 C 로 도 충분한데, 포트란을 쓰는 이유는,
1. 이미 짜여진 방대한 수학/과학 라이브러리와
2. 수퍼컴퓨터(병렬컴퓨터) 때문이라나...

이러한 이유라면, 포트란 77 에 관한 내용을 기록해 두는것이 맞다고 할 수 있다. 방대한 양의 코드가 이미 포트란 77 로 짜여져있으니까.
그럼에도 불구하고, 포트란 90/95 관련 메모를 남기는 건 90/95 가 더 좋기 때문이다 -_- 특히, 각종 짜증나는 규칙들이 제거되었다.
게다가 77 코드는 90/95 에서 대부분 호환이 되는데, 90으로 버전업을 할 때, 77 로 짜여진 방대한 라이브러리를 염두에 두었기 때문이다.
즉, 90/95 에서는 77의 장점도 쓸 수 있고, 90/95 의 장점도 쓸 수 있다. 말하자면, 짬뽕 규약의 코드를 짤 수 있다.
반면, 90 형식으로 짠 코드는 77 에서 호환이 안된다. 당연한게, 77의 짜증나는 규칙들을 상당수 제거했기 때문에, 77 입장에서는 형식에 맞지 않는 코드가 되어버리기 때문이다. 포트란의 버전업은, C의 장점들을 차용한 것들이 많다.

확장자는 77 이 .for 이고, 픽스트 포맷이며, 90 은 .f90 이고, 프리포맷이다. 간단히 말하면, 줄맞춰야 되느냐 막짜느냐 의 차이이다.
다른 언어와 마찬가지로, 컴파일과 링크는 컴퓨터 아키텍쳐 및 운영체제에 종속적이다. 따라서, 운영체제등을 고려하여 컴파일러를 결정한다.
예전에 MS 비주얼 씨 6.0 쓸때, CVF 6.6 같이 깔아서 썼었는데, VS 2008로 업글한 뒤에는 포트란을 써본적이 없다. 게다가 지금은  VS 2010 을 쓴다. 찾아보니, 인텔 포트란이 VS 2010 에 물려서 쓸수가 있다고 한다. 음...갖고 싶...   ( 인텔 싸이트 들어가보니, 리눅스용은 무료배포다. )

개인적으로 나는 "포트란으로는 코드 안짜지 말입니다. " 지만, 대충 읽고 C 로 다시 짜야되는데, 안쓰는 언어라 자꾸 까먹고 그래서 매번 레퍼런스 보기도 귀찮고, 그래서 기초적인걸 남겨두는게 좋을것 같다. 안쓰는 언어는 상상을 초월할 정도로 빠르게 까먹는다. 아 ...영어 ㅠㅠ...





1. 주석

포트란 77 까지는 주석문의 시작을 레이블링 하는 컬럼에 C ( comment ) 로 나타냈으나,
90/95 는 프리포맷으로, 아무 위치에서나 ! 를 사용한다.  컴파일러는 주석문을 무시한다.

! 주석문은 그줄의 끝 까지 이다.





2. 코딩문자

포트란 90/95 코딩에서 사용되는 문자들은 대충 다음과 같은 것들이다.

알파벳 26 개 ( 혹은 42개 )              주의. case insensitive : 대소문자 구별 안함 , 반면 C 는 대소문자를 엄격히 구분한다.

숫자 9 개

언더스코어 _

사칙연산  + - * /
거듭제곱    **
대입연산자 =

각종 기호들 ( ) < > : ; . , ' " ! ? % & $
빈칸




3. 문장 (statement)

C 처럼 문장 끝에 세미콜론 ; 같은게 붙지 않는다.

기본적으로 한 문장은 한 줄에서 작성하고, 너무 길거나 가독성의 이유로, 여러줄로 쓸때는 & 를 사용한다.


예)

a = b + c              와                      a  =   b   &
                                                           +  c                              는                     같다.


포트란의 문장은 실행문(executable statement) 와 비실행문(nonexecutable statement) 로 구분된다.
실행문은 연산과 같이 어떠한 액션 수행의 문장이고, 비실행문은 프로그램이 잘 작동하기위한 정보를 제공해주는 문장이다.
가령, 연산의 수행 및 대입 따위는 실행문이고, 변수의 선언은 비실행문이다.






4. 레이블링 (labeling)

문장에 고유번호를 부여해서, 레이블링 할수 있는데,  1 부터 99999 까지의 숫자를 사용한다.





5. 기본구조

프로그램의 큰 틀은 크게 3 가지 영역으로 구성된다.

1. 선언영역 (Declaration section)
2. 실행영역 (Execution Section)
3. 종료영역 (Termination Section)

선언영역에서 프로그램명, 변수 따위가 선언된다.
실행영역에서 각종 계산 및 명령을 수행한다.
종료영역에서 프로그램을 닫아준다.

서브루틴이나 모듈 등도 위와 같은 구조를 갖는다. 이에 대해서는 나중에 자세히 살펴보도록 한다.




6. 선언영역

6.1. 프로그램 명 선언

구문은 다음과 같다.
PROGRAM program_name

PROGRAM 문은 비실행문으로, 코드 첫줄에 오며, 프로그램의 이름을 컴파일러에게 전달한다.
포트란은 대소문자 구별 안하니까 당연히 program 이라고 써도 되는데, 보통 키워드를 대문자로 쓰는 관습이 있다.

프로그램 명에는 알파뉴머릭 (alphanemeric) 과 언더스코어(_) 를 쓸 수 있다.


6.2. 변수선언

정수변수의 선언은 INTEGER , 실수형 변수의 선언은 REAL  을 사용한다. 
문자변수는 CHARACTER 를 사용한다.

기본적인 구문은 다음과 같다.

INTEGER ::  variable names
REAL :: real_variables

CHARACTER [ ( len = length ) ] :: variable names
CHARACTER [ ( length ) ] :: variable names

length 부분에 숫자를 써넣으면, 문자열 데이터가 된다. ( len = ) 부분을 생략하면, 자동으로 길이가 1 로 설정되고, 단일문자 변수가 된다.
( len = 숫자 ) 대신 그냥 ( 숫자 ) 로 써도 된다.



7. 실행영역

기본적인 4칙 연산은 C 랑 같고, C에는 거듭제곱이 없는데, 포트란의 경우 계산언어답게 거듭제곱이 있다.
MS 계열의 프로그램이나, 각종 계산기에서 거듭제곱으로 많이 쓰는 ^ 의 경우, ALGOL인가(?) 에서 유래되었는데,
포트란에서는 ** 를 사용한다.

기본적인 입출력함수로 출력은 WRITE , 입력은 READ 문을 사용한다. ( 출력으로 PRINT 문도 있는데 권장되지 않는다고 한다. )

WRITE 와 READ 의 구문에 대해서는 따로 살펴보기로 한다.



8. 종료영역

종료영역에서는 STOP 문과  END PROGRAM 문을 사용한다.

STOP 문은 프로그램의 실행을 정지시키라는 명령으로, C로 치자면 BREAK 같은 것으로 생각할 수 있다.

END PROGRAM 은 컴파일러에게 더이상 컴파일될 문장이 없음을 알려주는 문장이다.

그런데, END PROGRAM 을 만나면, 어차피 컴파일러가 자동으로 STOP 명령을 내기때문에,
STOP 과 END PROGRAM 문이 연달아 붙어있는 경우에는 굳이 쓰지 않아도 상관없다.

END PROGRAM [ program name ]

END PROGRAM 뒤에, 종료시킬 프로그램을 명시적으로 나타내줄수도 있다.




예제코드 (.f90)

간단한 코드를 살펴봄으로써, 기본적인 구조를 살펴보자.
C 나 Java 였다면, Hello World 를 찍었겠지만, 그래도 명색이 계산용 언언데...

다음의 예제코드는 두 실수를 입력받아서, 그 첫번째 수에 두번째 수를 거듭제곱한 값을 출력하는 프로그램이다.


실행결과.



똑같은 프로그램을 C로 작성해보면, 포트란이 상당히 계산에 특화되어 있음을 느낄수 있다.
우선 리니어리티 ( 선형성 ) 에서 출발하자.

선형성(linearity) 은 알다시피 다음과 같다.

일차변환이라고 하는 것들이 바로 위와 같은 성질을 같는 것들을 말한다.

선형성이 1-벡터변수 함수에 대한 성질이었다면, 바이리니어리티는 bi- 라는 접두사에서 알수있듯이, 2-벡터변수 함수에 대한 성질로, 선형성이 두개가 있는 경우를 말한는데, 다음과 같다.


자세히 보면, 위에 두줄은 , 첫번째 벡터변수에 대한 선형성이고, 아래 두줄은 두번째 벡터변수에 대한 선형성이다.
즉, 두 벡터변수에 대해 각각 따로따로 선형성을 갖을 때, 이를 바이리니어리티 라고 한다.  그렇다, 전혀 어려운 개념이 아니다.


바이리니어리티를 갖는 대표적인 매핑은 이너 프로덕트 (inner product) 이다.


이 경우, 시메트리로 부터, 한쪽만 선형성 보이면 충분하다. ( 그렇다고 바이리니어리티가 교환법칙을 요구한다는 뜻은 아니다. )

교환법칙이 성립하지 않는, 바이리니어 매핑의 예로 행렬곱을 들 수 있다.

참고로, 벡터의 외적도 바이리니어 이다.


바이리니어를 이해했으면, 멀티리니어는 자동으로 이해가 된다.
단지 벡터변수가 증가하고, 각 벡터변수에 대해서  따로따로 선형성을 갖으면 된다.

철수가 어느 패밀리 레스토랑에 갔다.
주문을 도와주러 온 점원은 친절하게 중복할인이 된다고 웃으며 말했다.


철수가 물었다. " 어떤거부터 적용해도 상관없나요? "

점원은 친절하게 미소를 지으며 " 할인율이 높은것을 우선 적용해 드립니다. 고객님 ^^ "  이라고 했다.


가령, T카드가 20% 할인이고, 신한카드가 30% 할인이라면,
우선 신한카드 할인을 적용하고, 거기에 T카드 할인을 적용한다는 것이다.


철수가 다시 물었다. " 어떤거 부터 적용해도 상관없지 않나요? "

점원은 친절하게 미소를 지으며 " 할인율이 높은것 부터 적용하는게, 아무래도 고객님께 유리하겠죠? 고객님? ^^ "   하고 말했다.


철수가 다시 물었다. " 상관없을거 같은데.... 진짜 상관없지 않나요? "

그러자 철수앞에 앉아있던 영희가  " 싀발, 그만 쫌 해 ! "  라고 말했다.


둘은 맛있게 식사를 했다.





다음중 맞는 것은 ?

1)   할인율이 높은 것 부터 적용하는 것이 좋다.
2)   할인율이 낮은 것 부터 적용하는 것이 좋다.
3)   할인율에 따라 그때 그때 다르다.
4)   적용순서는 상관없다.



cmd 창에서, 리눅스 처럼, man 을 쳐서 도움말을 보도록 배치파일을 작성해보자.
단, 도움말이 길어서 차근차근 보기가 어려울때가 많으니까, 파일로 저장해서 메모장으로 보도록 만들자.


그니까 요딴식으로 되는거다. cmd 창에서 man 뒤에다가 명령어 치면, 메모장으로 보여주는거다.


물론, 실행창에다가 cmd /c 로 치면, cmd 창은 알아서 닫히고, 메모장에 도움말만 나온다.  ( 스위치 /c 는 cmd 와 한칸 띄어준다. )


즉, 요딴식으로 치면, attrib.exe 에 대한 도움말만 메모장으로 나오고, 커맨드 창은 사라진다.


더 간단히, 그냥 실행창에,   ' man 명령어 ' 를 쳐도 된다.





암튼, 위의 기능을 하는 배치파일을 만들어 봤다. 첨부 파일을 클릭해서 실행해보자.

mansetup.bat






배치 스크립트는 다음과 같다.

@echo off
echo @echo off> %SystemRoot%\system32\man.bat
echo IF NOT "%%1"=="" ( help %%1 ^> "C:\Users\%%USERNAME%%\My Documents\%%1.man">> %SystemRoot%\system32\man.bat
echo start notepad "C:\Users\%%USERNAME%%\My Documents\%%1.man">> %SystemRoot%\system32\man.bat
echo ) ELSE ( echo.>> %SystemRoot%\system32\man.bat
echo echo man [command]>> %SystemRoot%\system32\man.bat
echo echo.>>%SystemRoot%\system32\man.bat
echo echo provides the Manual for the specified command in the Notepad.)>> %SystemRoot%\system32\man.bat



간단히 해석을 해보자. 앞에붙인 숫자는 줄 번호이다.

@echo off 

배치파일에서 수행되는 명령들을 감춘다. @는 echo off 자기자신도 감춘다.


echo @echo off> %SystemRoot%\system32\man.bat

echo 로 @echo off 라는 메시지를 내보내는데, 리다이렉션 > 시켜서 우측의 대상으로 보낸다.

시스템은 % 를 만나면 곧바로 치환을 하는데, %SystemRoot% 는 환경변수로, Windows가 설치된 폴더를 가리킨다.
즉, 윈도우즈가 설치된 폴더의 system32 라는 폴더에 man.bat 이라는 배치파일을 생성하여, 거기에 @echo off 라는 메시지를 집어넣는다.

echo IF NOT "%%1"=="" ( help %%1 ^> "C:\Users\%%USERNAME%%\My Documents\%%1.man">> %SystemRoot%\system32\man.bat

man.bat 에 append(덧붙이기) 모드  >> 로 다음의 메시지를 집어넣는다.
IF NOT "%1"=="" ( help %%1 > "C:\Users\%USERNAME%\My Documents\%1.man"

%%는, 이 배치파일 mansetup.bat 내에서 치환하지 않고, 리디렉션으로 넘어가서 %로 치환된다.
man.bat 으로 넘겨졌을때는 %가 하나이므로, man.bat 의 수행해서는 미리 치환된다.

환경변수 USERNAME 도 마찬가지다. %를 하나만 쓰면, mansetup 에서 해당 사용자 계정명으로 치환된다.
( 물론 이경우에는 미리 치환해도 별 문젠없다)


따라서, %% 를 넘기고 싶다면, %%%% 로 써주면 된다.

man.bat 로 넘겨진 메시지는 조건문으로,
' %1 가 빈문자열이 아니면 %1 /? 의 결과를 내문서에 %1.man 이라는 파일로 저장하라 ' 이다.
앞의 이유와 마찬가지로,  리디렉션 > 앞에 탈출문자 ^ 를 붙여서, 일단 그냥문자로 넘겨주고 있다.


echo start notepad "C:\Users\%%USERNAME%%\My Documents\%%1.man">> %SystemRoot%\system32\man.bat

start 는 cmd 프로세스를 메모장 프로세스로 부터 분리시킨다. 즉, 메모장이 실행되고 난후, 메모장을 닫을때까지 대기하지 않고, 그냥 cmd로 돌아와서 계속 cmd 작업을 할수 있도록 한다.

그다음의 내용은 별다른게 없다.



삭제는 system32 폴더에 가서 man.bat 파일 지우거나, 아래처럼 del 로 경로지정해서 지워도 된다.

del C:\windows\system32\man.bat

보다시피 매우 단순한 배치파일이므로, 그냥 지우면 끝이다.

배치파일은 명령어의 묶음으로, 텍스트 파일이며, 확장자는 .bat 이다.  cmd 는 배치파일에서 한줄씩 읽어와 처리한다.

블럭화 혹은 그룹화(grouping) 는 괄호 ( ) 를 사용한다.  C의 { } 와 유사하다.


REM (remark)  는   주석문이다.

REM statement               해당 줄 자체가 무시된다.


명령어 앞에 @ 를 붙이면,  해당 "명령어"를 보이지 않게 한다.

이후의 명령어를 모두 감추려면, ECHO OFF 를 해준다.

따라서, ECHO OFF 자기 자신도 안보이게 하려면,  첫부분@ECHO OFF 라고 해주면 된다.


PAUSE 는 배치파일을 잠시 중단시키며, " Press any key to continue ...  "   와 같은 메시지를 보여준다.

중단은 Ctrl + C 나 Ctrl + Break 로 할 수 있다.


C 에서 main 함수의 인자 argv[] 로, 실행파일 이후에 오는 문자열들을 포인팅 했던것 처럼,
배치파일에서도 같은식으로 지정할 수 있다.

C에서, argv[0] 이 해당실행파일 명이었고, 그이후부터 argv[1] , argv[2] , ... 였던것과 마찬가지로, 배치파일에서도, 자기자신부터,
순서대로,    %0,  , %1 , %2 , ...  으로 포인팅한다.  최대 %9 까지 쓸수 있다.

참고로, 인자에 빈칸이 가능한경우 "%1" 과 같이 따옴표로 묶어준다.



배치파일에서, 무조건 분기는  GOTO (<--클릭) 문으로, 조건분기는 IF (<--클릭) 문으로, 루프는 FOR (<--클릭) 문으로 한다. 각 구문은 각 링크 참조.


주의할 점은,  윈도우 시스템이 배치파일의 %을 만나면, 곧바로 대응되는 녀석으로 치환을 해버린다는 것이다. 어떤의미에서 C의 #define 문이 하는 짓하고 좀 비슷하달까..

또한, C 에서 printf() 같은녀석으로 제어문자열 쓸때, 어떤녀석들은 기능을 탈출시키고, 문자로 찍어주기 위해서 두번반복해서 써야 하는 녀석들이 있었는데, 그와 비슷하게,  % 자체를 찍기위해서는 %% 를 써주면 된다.


예제로 간단한 배치파일을 작성해보자. 예제보기.

밀리컨 기름방울 실험

Misc.2010. 12. 7. 23:47 |
실험실에 누군가 해놓은 낙서인데, 너무나 맘에 드는 humor(휴우머)라... 영구간직해야겠다.


그나저나, 우석이형은 뭐하고 있으려나...
표준입출력은 디폴트로 키포드와 모니터이다. 그것을    > ( ---> 방향 )  과   <   ( <--- 방향 ) 을 이용해, 입출력 방향을 바꿔줄수 있다.

참고로,  > 는 덮어쓰기(overwrite)가 기본이므로, 덧붙여야 (append ) 할때는    >>  를 쓰도록 한다.




예제로, 환경변수와 네트워크 설정정보를 test.txt 라는 문서로 저장해보자.

다음과 같이 입력한다.



여기서 && 는 command separator 로 두 커맨드를 한줄에 입력할때 사용한다. ( doskey 가 default 로 ON 되어있다. )
&& 로 구분된 좌우를 두줄로 따로 따로 친것과 동일하다.

첫번째 커맨드에서 > 로 오버라이트 모드로 쓰고, 두번재 커맨드에서 같은파일에 어팬드모드로 쓴것이다.

c드라이브로 가서, test.txt 를 열어보면, 환경변수 정보와 ip 설정정보를 볼 수 있다.




< 를 사용해서, 만들어진 test.txt 파일을 한페이지씩 화면에서 보기위해,  more < test.txt 라고 입력해보자.





리디렉션 대상으로 다음을 사용할 수 있다.

NUL                                                            null                              ( 아무짓도 안함 )
COM1 , COM2  , COM3 , COM4  등                직렬포트
LPT1 , LPT2  등                                           병렬포트
CLOCK$                                                     클락

AUX                                                            보조장치                         ( 보통 COM1 )
PRN                                                            프린터                            ( 보통 LPT1 )
CON                                                            콘솔                               ( 키보드 , 모니터 )




C에서, printf 따위로 제어문자열을 출력할때, 이스케이프 문자로 \를 썼었는데, 그것과 마찬가지로,  탈출문자 ^  를 쓸 수 있다.

즉, > 는 리디렉션 이지만, ^> 는 그냥 문자 > 이다.


가령, echo a>b 라고 하면, a 를 b 에 저장한다. ( b는 확장자는 없지만, 텍스트문서이다. )

반면, echo a^>b > c  라고 하면, c 에  문자열   a>b   를 저장한다.


마찬가지로,  리디렉션의 append 모드인  >>  의 경우,   ^>^> 따위로 쓰면 된다.

cmd.exe 의 구문  ( 박스괄호 [] 는 옵션이라는 뜻이고, 여기서 파이프 | 는 OR 의 의미이다. )



각 스위치의 기능을 간단히 살펴보자.



/C 또는 /K  :   명령실행후, 세션 종료 또는 남겨두기

실행창에서 도스명령어들 치면, 자동으로 세션이 종료되는데, 다음과 같이 /K 옵션을 주면 세션이 종료되지 않는다.

다음과 같이 실행해보고 차이를 확인해 보자.


    ( 셸을 켜놓은 상태라면, /C 를 줌으로써 자동으로 세션을 종료되게 하면 편한경우가 있다. )





/S  따옴표로 묶인 스트링의 처리




/Q  명령으로 들어온 것이, 배치파일일때, 배치파일 내부의 명령어들이 나열되어 보이지 않도록 에코를 꺼준다.



/D 레지스트리 ( 아래 경로 참조 ) 에 등록된 명령을 건너뛴다.

아래 경로에, cmd.exe 실행시, 자동실행되도록 명령을 지정해 둘수 있다.
복수개의 명령은 command separator && 를 사용해서 구분한다.

가령, cmd.exe 를 실행할때마다, 환경변수를 확인하고 ip 설정정보를 확인하고 싶다면,
아래경로의 레지스트리값을 set&&ipconfig 라고 주면 된다.

/D 스위치는 이렇게 저장된 명령의 실행을 하지 않도록 한다.





/A 또는 /U      파이프나 파일로의 출력을 ANSI 또는 유니코드로 설정한다.

/T:                색상지정:  16진수 두자리로, 앞자리가 배경, 뒷자리가 폰트색이다.
                     ( 색상표는 여기에   http://sciphy.tistory.com/1182    )





/E:ON   또는   /E:OFF     명령확장(command extension) 을 켜거나 끈다. 디폴트 는 ON 임.



명령확장에 의해 추가되는 명령어들은 아래와 같다.   /? 로 자세한 구문을 확인할 수 있다.




/V:ON    또는    /V:OFF          ! (exclamation character) 를 구분기호로 하는
                                             지연된 환경변수 확장 ( delayed expansion  of  environment variable ) 의 사용여부.
                                             디폴트값은 OFF 이다.


이 기능은, 배치파일에서, 환경변수를 실제값으로 치환하는 시점을 딜레이 시켜준다.
디폴트 ( OFF) 에서는, 파일을 불러들이는 시점에서, 환경변수를 실제값으로 치환하는데,
이 스위치를 켜면, 배치파일 내의 해당 커맨드가 실행되는 시점에서 치환한다.



/F:ON    또는    /F:OFF    파일과 디렉토리 이름 완성기능의 사용. 컨트롤 F 로 넘겨가면서 찾게되고, 컨트롤 D 를 누르면 디렉토리만 보여준다.








1. 정의

르장드르 변환은 변수를 바꾸는 변환인데, '어떻게 변환하는지' 는 이제부터 설명하도록 하겠다.

어떠한 함수 f 가 n 개의 변수를 갖는 다변수함수 라고 하자.
편의상 바꾸기를 희망하는 m 개의 변수를 x1 , x2 , ... , xm 로 놓고,  변환하지 않는 나머지 n-m 개의 변수들을 y1 , y2 , ... , yn-m  라고 놓자.

더 간단히, x =  ( x1 , x2 , ... , xm ) , y = ( y1 , y2 , ... , yn-m )  라고 놓으면,  f = f ( x1 , x2 , ... , xm , y1 , y2 , ... , yn-m ) = f ( x, y ) 라고 쓸 수 있다. ( x , y 는 여기서 편의상 이렇게 부르자는 것이지, 실제 변수명이 x, y 일때, x는 변환하고 y는 그대로 두고 한다는 말은 아니다.-_-; )

또한, "변환할 변수 공간" 에서의 del 을 ∇x =  ∂/∂x  = ( ∂/∂x1 , ∂/∂x2 , ... , ∂/∂xm )  으로 쓰기로 하자.

그러면, 변수 x 를  ∇x f  (즉, ∂f /∂x ) 로 변환하는 르장드르 변환의 정의는 다음과 같다.


여기서  < , > 는 내적이다. 앞의 +, - 부호는 컨벤션이다. 어차피 변수가 변하는 것은 마찬가지다. 단지, 식의 부호가 바뀔 뿐이다. 아무거나 원하는 것을 써도 좋다.

일단 여기서는 간단히 + 컨벤션을 택하도록 하자. ( 필요하면 언제든지 - 컨벤션도 사용하겠다.)

참고로, 아래와 같은 벡터 노테이션도 많이 쓰인다. 



위의 르장드르 변환에 의해, 변수  x =  ( x1 , x2 , ... , xm )  가  ∇x f =  ∂ f/∂x  = ( ∂ f/∂x1 , ∂ f/∂x2 , ... , ∂ f/∂xm ) 로 바뀌게 되는데,

변환된 새로운 변수를 편의상   u = ∇x f =  ∂ f/∂x  = ( ∂ f/∂x1 , ∂ f/∂x2 , ... , ∂ f/∂xm ) 라고 놓으면,

 ( 즉,   u1 = ∂ f/∂x1  ,   ...   ,  um   =  ∂ f/∂xm   라고 놓은 것이다. )


르장드르 변환은 서메이션 컨벤션과 함께, 다음과 같이 간단히 표현된다.
( 주의, 서메이션 컨벤션이 쓰임. )


위에 나열한 세가지 표현은 모두 동일한 것이다.  ( 참고로, 세번째 노테이션 이 가장 선호된다. )





2. 변수와 함수의 변환 과정

함수의 르장드르 변환에 의해 변수의 변환이 이루어지는 과정을 살펴보자.

처음에 f 는 n 개의 변수를 갖는 다변수 함수였고, 이중에 선택된 m 개를 우리가 편의상 x 로 나타내었고, 나머지는 y 로 나타내었다.

르장드르 변환을 통해, f ( x , y ) 이  g ( u , y ) 로 변환된다.




여기서 g = x u  -  f  이고,  u와 곱해져있는 x 뿐 아니라, f 안에 들어있는 x 는 모두 u 의 함수로 써진다. ( = 좌표변환식 )







3. 르장드르 컨주게이트 와 역변환

르장드르 변환의 중요한 성질 중 하나는,  역변환이 자기 자신이라는 것이다.
즉, f 를 르장드르 변환해서 g 가 되었는데, 르장드르 변환을 한번 더하면, 다시 f 가 된다.

따라서, 르장드르 변환을 L 이라고 하면,   L ( L( f ) ) =  f  가 된다.  이는  L2 = I  , L -1 =  L  따위로 쓸 수 있다. ( I 는 identity 변환 )


증명을 하기전에 다음의 사실을 관찰하자.


즉, ∂ g / ∂ u 가 다시 x 가 되는 것만 보이면, 역변환이 르장드르 변환 그 자신이 된다는 것은 자명하다.

증명은 간단하다.

이것으로, 르장드르 변환의 중요한 성질 " 르장드르 변환의 역변환은 자기 자신이다 " 가 증명되었고, 이 때, 가장 중요한 역할을 한 것은 바로, 위의 파란별표친 박스이다.

파란별표친 박스는, 변환된 변수에서 본래의 변수로 돌아가는 방법을 말해주고 있으며, 그것이 원래의 변수변환과 같은 형태임을 보여준다.
이러한 변환의 대칭성은 다음과 같이 나타낼수 있으며, 서로를 르장드르 컨주게이트 라고 부른다.

간단히 말해서, 르장드르 변환에있어 변환 전후의 변수들을 서로 르장드르 컨주게이트 라고 부른다.





4. 듀얼리티

르장드르 컨주게이트 베리어블들은 f  (또는 g ) 를 기준으로, 서로 리씨프로컬한 디멘션을 갖는다.  르장드르 변환식에서 보듯, f 와 g 는 같은 디멘션이고, x u 가 곱해져서, 그러한 디멘션이 된다. 이렇게, 르장드르 컨주게이트 변수들은 서로 완전하게 대응되는 쌍이면서, 동시에 서로 다른 공간에 살고있다고 할 수 있다.

또한, f 와 g 는 물론 같은 디멘션을 갖지만, 사는 공간이 각각  x,y 스페이스와 , u,y 스페이스로, 서로 다른 공간에 사는 함수가 된다.







5. 간단한 예제

변수가 몇개 안되는 간단한 수식으로, 르장드르 변환을 해보자.

ex1. 1변수




ex2. 2변수 중에 2변수 모두 변환


ex3. 2변수 중에 1변수만


이정도면 충분 한듯. 같은 식에서 y를 변환해도 된다. 직접해보길.

또, 삼변수, 사변수 일때도, 변환변수 임의로 잡은다음, 르장드르 변환을 하는 것도 어렵지 않게 해볼 수 있다.



6. 라그랑지안에서 해밀토니안으로

라그랑지안은 제너럴라이즈드 코디네이트와 제너럴라이즈드 벨로시티들의 컨피규레이션 스페이스에 살고 있다.
여기서, 제너럴라이즈드 코디네이트는 그대로 두고, 제너럴라이즈드 벨로시티만 변환을 하도록 한다.

그럼 라그랑지안의 르장드르 변환 (w.r.t. 제너럴라이즈드 벨로시티) 는 다음과 같다.


특히, 변환된 변수가 제너럴라이즈드 모멘텀의 정의 이므로,  다음과 같이 쓸 수 있다.




해밀토니안의 변수들은 제너럴라이즈드 코디네이트와 제너럴라이즈드 모멘텀이므로, 헤밀토니안으로 운동을 기술하면, 제너럴라이즈드 코디네이트와 제너럴라이즈드 모멘텀에 의해 기술됨을 알 수 있다.

결과적으로, 헤밀토니안은 컨피규레이션 페이즈 스페이스에 살게 된다. 여기서, 제너럴라이즈드 코디네이트와 제너럴라이즈드 모멘텀을 서로 캐노니칼 컨주게이트라고 부른다. 또한, 르장드르 변환의 성질들을 그대로 가져오면... 제너럴라이즈드 벨로시티와 제너럴라이즈드  모멘텀은 서로 르장드르 컨주게이트이다.

간단히 도식화 하면 다음과 같다.


H 가 L 의 르장드르 변환인 관계로, 라그랑지 운동방정식도 모두 변환되어, 해밀턴's equations 이 된다.






7. 내부에너지/엔탈피 에서 헬름홀츠/깁스 프리에너지로

내부에너지와 엔탈피의 변화는 각각  dU = T dS - p dV   ,  dH = T dS + V dp  로,     U = U ( S , V )   ,    H = H ( S , p )   이다.
그런데 실제적으로, 엔트로피 S 는 컨트롤하는게 쉽지 않으므로,  르장드르 변환을 통해, S 를 다른 변수로 바꾼다.

참고로, 이때, 르장드르 변환의 - 사인 컨벤션을 쓴다.



이것이 헬름홀츠 프리에너지와 깁스 프리에너지의 정의이다.

각각 르장드르 변환을 통해, S 에서  ∂ U / ∂S = T  로,  S 에서 ∂ H / ∂S = T 로 변수가 변환되었다.


진짜로,   (S, V ) , ( S, p ) 에서 (T,V)  와 (T, p) 로 변수가 바뀌었는지를 확인하면서 글을 마무리 짓도록 하겠다.



망가 스튜디오를 일단 인스톨 하고, 그다음에 material 을 설치하게 되는데, 이때 중간에 오류가 나는거다.

오류 내용은 어떤 파일경로 principalufs Room and Meeting Rooms 에서 멈추더니,
The system cannot find the file specified.  ( 맞나? )  라고 뜬다.

그래서 일단 그 경로를 찾아가봤다.


웁스 !  저런,  u 에 움라우트가 들어있다 -_- ;;




해법은 간단하다.

CD 를 탐색으로 들어가면, 들어가자마자, Material 폴더와 Material.inf 가 있다.  이 두가지를 카피해서, 컴퓨터에 복사한다. 아무 폴더나 만들어서 넣은다음, 문제가 되는 폴더명의 u 움라우트를 그냥 u 로 바꿔주면 된다.

다음은 u 움라우트를 u 로 바꾼 모습이다.



그리고 나서 아래와 같이, 폴더로 부터 설치를 하면 된다.


그러면 폴더 선택하는 창이 뜨는데, 그때 "material 폴더와 inf 파일이 들어있는 상위폴더" 를 선택한다.
( inf 파일이 없으면, 망가 material 폴더가 아니라고 머라고 한다. )

암튼, 그러면 진행이 멈추지 않고 계속 고고싱 해서 설치가 완료된다.


설치가 끝났으면, 임시로 pc 에 저장했던 폴더는 삭제하면 된다.





방금, 네이버에서 검색했더니, 거기서는 정상적으로 인스톨 하지않고, 대신 하위 폴더들을 카피해다가 덮어쓰기 하는데, 어떤게 더 나은지는 모르겠다. 나는 그냥, 인스톨하는 장면이 나오는 이게 더 좋은거 같다. 선택은 각자.


Win7 은 사용자를 점차로 말단유저로 인식하는 경향이 강하다.

즉, 다음과 같은 전산세상의 위계질서에서, 최하위 계층으로 간주하는 것이다.

1. 시스템 디벨로퍼
2. 애플리케이션 디벨로퍼
2. 오퍼레이터
3. 어드밴스트 유저
4. "dumb-shit" end user


아무튼, 폴더에 접근이 안될때, 소유권을 가져와야하는데, 많은 경우 다음과 같이 해결할 수 있다. ( 모든 폴더가 다 되는건 아님. )

일단 해당폴더에서 우클릭을 하고, 보안(security)탭을 선택한다음, 고급(advanced) 로 들어간다.




거기서 소유권( Owner) 탭으로 들어가서,  편집(Edit) 를 누른다.




쇼유권을 가져올 계정을 선택하고, 하위폴더에 대해서도 가져오겠다고 체크해준다음, 확인을 누른다.



아래와 같이,  접근금지 되었던 폴더에 접근이 된다.





Alias Sketchbook 이 AutoCAD 만든회사인 Autodesk 로 넘어갔는데, 그바람에 스케치북이 무거워져서 나는 별로 좋아하지 않게 되었다.
그런데, 아이폰/아이팟터치 용으로 나온 무료앱 스케치북 모바일은 정말 "괜찮다~" 이다.
일단, 에일리어스 스케치북 때와 상당히 유사한 인터페이스를 가지고 있고, 네 귀퉁이의 터블탭으로 사용하는 기능도 상당히 편하다.


아이패드면 몰라도, 아이팟은 화면이 작기 때문에, 손으로 정교하게 그리기가 쉽지 않다. 그런뎐챠로, 낙서에 애로사항이 꽃피는데, 스케치북 모바일은 뒤로(실행취소, undo) 가 매우 편하게 되어있다. 그냥 좌하단 구석탱이를 손끝으로 두번 톡톡 치면 undo 가 적용된다. 그리다가 맘에 안들면 드립다 구석을 톡톡, 톡톡 치면 상당히 많은 스텝을 뒤로 돌아갈수 있다.

또한, 작은 화면에 정교하게 그리기 어려운 문제점을 획기적으로 보완한 부분이 '줌인'을 지원한다는 거다. 두손가락을 오믈락거려서 화면을 확대할수 있고, 손가락 두개를 댄체로 움직이면 화면을 좌우로 움직일수 있다. 따라서, 좀 자세하게 그리고 싶을때는, 화면을 확대하고 막 그린다음, 다시 오므려서 원래싸이즈로 돌아오면 그럭저럭 자세히 그린것과 같은 효과가 난다.

확대된 화면에서 곧바로 원래 싸이즈로 돌아오면서 화면에 핏되게 해주는거는, 오른쪽 상단을 두번 톡톡치면 된다.

암튼 재밌다 이거, 게다가 이 조그만게 레이어도 지원한다. 투명도도 설정가능하고, 붓싸이즈도 조절이 엄청 쉽다. 스포이드로 색상뽑아서 쓸수도 있고, 아무튼, 이건 칭찬을 해도 해도 부족하다. 무료앱주제에!
자주 팅기고 전송실패도 자주나고... 전송실패 난 트윗은 재전송해도 바로 전송실패가 뜬다.
그글 긁어다가 트윗덱에서 하면 잘되는데...
물론 트윗덱도 자주 팅겨서 좀 짜증...

음... 유료앱 가야되나...

이렇게 별천지이고 무궁무진한줄 몰랐고,
아이튠즈 U 에 그렇게나 많은 대학강의들이 올라와있는줄도 몰랐고...
다운받아서 들고다니면서 아이팟으로 보니까, 너무 좋다는거.

몇십개 다운받았더니 벌써 꽉찾다고 지우라하네 ㅠㅠ
아 64기가 살껄...


괜찮아 괜찮아... 아이패드 사면 되니까.

아이패드는 무조건 젤 큰 용량으로 사는거다 !

"아이튠즈U" 대박 !
"iTunes U"  만쉐이...

아이튠스 너무 좋아 ~~

p.s. 멜론꺼져, 벅스꺼져.

요즘 아이팟에 pdf 넣어서 책처럼 보는 재미에 푹 빠져있습니다.
아이패드에 대한 욕심이 안생길수가 없군요. ( 갤탭은 안중에도 없습니다... 이래서 애플 애플 하나봅니다. )

그린블루님 블로그에 예쁜 책이 한권올라왔더군요. 4판이던데, 웹에돌아다니는 아마도 1판인듯한 pdf 올려봅니다.
한폴더에 두개다 다운받아놓고, part1 을 압축풀기하면, 분할파일인 2번까지 같이 묶여서 풀립니다.


전부터 해보고 싶었던게 있는데, 바로 칠판 모드이다. ( 일전에 그린블루님 블로그 보고 나도 해보고 싶었다. )

SAI 툴이 레이어를 지원하니까, 칠판레이어 하나 놓고, 투명레이어에 흰색펜으로 쓰면서, 레이어만 추가해주면
상당히 편리하게 여러장의 그림을 그릴수가 있다. 오홋!

이번 글은,  다이버전스 띠어럼 ( 발산정리) 하고 스토크스 띠어럼 ( 스토크스 정리 ) 의 아주 간결한 폼에 대해서 간략하게 써보도록 하겠다.

여기서, 간결하다는거슨 엘레강스하고 알흠답다는 말과도 상통하기 때문에 우리가 추구하는 바이기도 하다.


일단, 우리의 논의는 다이버전스 띠어럼과 스토크스 띠어럼을 이미 알고있다는 상태에서 출발한다.

그거슨 다음과 같다.



( 노테이션 :    da 는 면적분이고, d3x 는 부피적분, dl 은 선적분이다. )




우선,  다이버전스 띠어럼 부터 살펴본 후, 이어서 같은방식으로 스토크스를 살펴본다.
딱히 어려운 내용이 없으므로, 더이상의 설명은 생략한다.

( 노테이션 주의사항:  중복첨자에 대한 서메이션 컨벤션이 사용되었음. )



그러므로, 다이버전스 띠어럼이랑 스토크스 정리를 다음과 같이 쓸 수 있다.



이제, 위의 두식을 외운다음,

스칼라 필드에 자유롭게 곱해도 되고,
벡터필드에 닷프로덕트로 곱해도 되고,
벡터필드에 크로스프로덕트로 곱해도 된다.

그냥 자유롭게 막 쓰면 된다.

[Paint Tool] SAI 1.1.0

Misc.2010. 11. 20. 15:42 |
그림판을 애용하고 익숙해진 나같은 유저에겐 딱인듯.

포토샵처럼 무겁고 거창한거 말고, 가벼운걸 원한다면 강추인 아이템임.



그림판처럼 가벼우면서, 레이어를 지원하고, 색깔도 섞어짐. ( 생각했던것보다 기능이 무진장 많은듯. )
저울에 올려진 반구형 밥그릇의 테두리에 실을 붙여, 윗쪽으로 붙잡아둔 상태에서,  그림과 같이 경사각을 재봤더니,
θ 가 되었다.



저울에 나타난 밥그릇무게의 감소율을 구하라.

(  단, 감소율 = 감소한양 / 원래의양  이라고 한다.         예를들어, 10 에서 7 로 되었다면,  감소율은 3  / 10   임.     )



동영상 볼때 대박 편한 필수 아이템. iStand

엘레컴껀데 엄지만한게 만원정도 함 ;;; 좀 비싼거 같음. 근데 엘레컴꺼 전에 애기볼살 마우스패드도 몇만원 줬던거 같은데... 암튼 좀 비싸게 파는 회사인듯.

대충 요래 생겼고...

요런식으로 쓰는거임.



만족도 ★★★★

뜨거운 입김으로 꾸욱 눌러붙여주지 않으면, 간혹 떨어지면서 넘어질수 있음.

지렛대의 양쪽 팔 길이를 모르는 지렛대와 1N 무게의 나무토막을 많이 가지고 있다.



어떤 물체를, 왼쪽 끝에 올려놓고  오른쪽 끝쪽에 나무토막 5개를 올렸더니 수평을 이뤘다.
반대로, 오른쪽 끝에 물체를 올려놓고, 나무도막 4개를 왼쪽에 올렸더니 수평을 이뤘다.

물체의 무게는 얼마인가?

어린이를 위한 미적분학이라는 포스팅을 아주 어쩌다 한번씩 비공개로 군데군데 쓰고있는데, 이것도 그 시리즈의 일부가 되겠다.
앞부분 글들이 완성이 안된 관계로 일단 글번호는 생략하고 나중에 앞부분 글들이 어느정도 잡히면, 그때 순서에 맞게 배치할 생각이다.

이 글은, 대략적으로, 기본적인 미분테크닉을 익힌 정도, 다음에 오면 될것같다.

이글은, 1변수 테일러급수만 간단히 설명한다.
2변수 테일러는, 다변수 미분을 정의하고, 그다음편에 쓰겠다.


멱급수 전개 (Power Series Expansion)

1, x, x^2 , x^3 , ... 이런식으로 차수가 증가 함에 따라,  그 기울기의 변화 정도는 이전의 것과 항상 다른 새로운 녀석이 되고, 그것은 점점더 격해진다. 이렇게 기울기의 변화가 모두 다른 녀석들을 잘 섞으면, 구불구불하게 생긴 이상한 함수를 만들어 낼수 있지 않을까?

이것은 달리 말하면,  임의의 함수 f(x) 를 ,  1 , x , x^2 , x^3 , .... 들의 조합으로 나타내보려는 것인데, 이러한 행위를  멱급수 전개 (Power Series Expansion) 이라고 한다. 

어떤 경우에는 유한개의 항만을 합쳐서 주어진 함수를 만들어 낼 수도 있겠지만, 상황에 따라서는 무한개의 항을 합쳐야지만 원하는 함수를 만들게 될수도 있을 것이다.  이것은 간단히 무한개의 항을 세팅하는것으로 모든상황을 포함시킬수 있다. 어차피 유한개의 항만 필요한 상황이라면 나머지 항의 계수를 모두 0 이라고 하면 되기 때문이다.


이제 1 , x , x^2 , x^3, x^4, ...  의 계수들을 an 이라고 하면, 어차피 베이시스(  1 , x , x^2 , x^3 , .... ) 는 고정되어 있으므로,
선형조합 계수들 an 만 모두 알면,  f(x) 를 아는것과 완전히 동일해진다.


따라서, 조합의 계수들을 구하는 것이 가장 큰 문제가 된다.

(1 + x ) ^ 3  를 예로 들어보자.



즉, (1+x)^3 이라는 함수를 기억하는 것과   수열 :  1,3,3,1, 0, 0 , 0 , 0 , ...   을 기억하는 것은 완전히 동일한 것이 된다. 즉, 중요한 것은 계수를 찾는 것이다.



테일러 급수 ( Taylor Series )

f(x) 의 멱급수 전개에 대해, f(x) 가 어떤 점 x = a 에서 무한번 미분가능할때 ( 미분값만 갖으면 되지, 값이 얼마인지는 상관이 없다. 주구장창 0 이어도 상관없다 ), 미분을 통해서, (x-a) 의 멱급수전개의 계수를 정할수 있는 일반적인 방법이 존재하는 데, 이를 a를 중심으로 테일러 전개를 한다라고 한다.

특히, x = 0 에서 무한번 미분가능하면, x 의 멱급수로 전개되고, 앞에서 언급한 예가 된다. 이럴때를 특히, 맥로린 급수라고 한다.
( 즉, 맥로린 급수는 0 을 중심으로 하는 테일러 급수 이다. )

우리도 심플함을 위해, x = 0 을 중심으로 전개한다고 하자.

이제 목표는, 무한번 미분가능이라는 무기를 가지고, 주어진 f(x) 에 대해, 어떻게 계수들을 모두 구하는 가이다.

멱급수 전개의 정의로 돌아가서, 양쪽이 완전히 같은 함수라는 말은,  이 식이 x 에 대한 항등식이라는 말과 같다.

x 에 0 을 때려넣어보면, 곧바로 a0 가 f(0) 라는 것을 알게 된다. 즉 주어진 함수에 0 값을 대입해서 나온 값이, 테일러 급수의 첫번째 계수가 된다.


이제, a1 부터 구해야 되는데, 어떻게 하면 다른계수들은 모두 죽어나가고, 원하는 계수만 죽지 않게 할 수 있을까?
그것은 바로, 한번 미분한뒤에 0 을 대입하는 것이다.

다항식의 경우 한번 미분하면 지수가 앞으로 내려오고 지수는 1씩 작아지는 것을 알고 있으므로, 한번 미분하면 다음과 같이 되고, x에 0 을 대입하면 a1을 제외한 모든 항이 날아간다. 따라서, 다음과 같이 a1 을 구할수 있다.


이쯤 되면 감이 와야 정상이다.  특정 an 만 남기고 다른 모든항을 날려버리느 방법은 n 번 미분하고 x 에 0 을 대입하는 것이다.

x의 차수가 n보다 작은 것들은, n번 미분했을때 모두  0 으로 날라가 버린다.
x의 차수가 n보다 큰 것들은 , n번 미분했을때 x의 차수가 1 이상이 되어, x=0 을 대입하면 모두 날아가버린다.

x의 차수가 n 인 항은 , n번 미분했을때 x의 차수가 0 이 되어 사라지며 남는것은 원래의 계수 an 와 미분때마다 하나씩 줄어들려 앞으로 내려온 n , n-1 , n-2 , ... , 1 들의 곱, 즉, n! 이 된다.


따라서 다음과 같이 테일러 계수를 일반적으로 구할수 있다.



이제 원래의 정의식


에 앞에서 구한 계수의 일반식을 대입하면, 아래와 같이 테일러시리즈의 일반식을 구하게 된다.




중심 a 에 대한 테일러 전개

위에서 심플함을 위해, 중심을 0 으로 놓았었는데, 이제 중심을 a 로 전개해보도록 하자.
앞에서 어떻게 원하는 계수를 포함하는 항 이외의 모든 항들을 날려버렸는지를 이해했다면, 이것은 정말로 쉬운 일이다.

특히, 1, x-a , (x-a)^2 , (x-a)^3 , ... 들로 전개되므로, 다른 항들을 죽일때, x = 0 을 넣는것이 아니라, x = a 를 넣어야 된다.

결과적으로 다음과 같이 된다.




멱급수 전개에 의한 함수의 변환

함수를 급수로 전개하는 것에 대한 중요한 관점은, 함수에서 수열로의 변환이다. 그것은 함수의 문제를 수열의 문제로 바꾸어준다. 해당 함수에서 다루기 어려웠던 문제가, 수열의 연산에 의해서 쉽게 풀릴수도 있다. 그리고 나서 다시 돌아가면 본래의 문제를 푼것이 되는데, 이것을 역변환이라고 한다.

특히, 멱급수 전개의 경우, (무한) 다항식이고, 많은 연산이 (무한) 다항식에 대해 항별 (term-by-term) 연산을 가능하케해, 상당히 다루기 용이한 면이 있다. 즉, 원래의 문제에서 어려워 보였던 문제가, 멱급수로 변환한후에 쉬워 보이고, 멱급수로 변환한 상태에서 쉽게 문제를 푼 후에, 다시 역변환을 통해 어떤 함수로 돌아가는지를 찾는 것이다.

이것은 변환 / 역변환 을 이용해서 문제를 해결하는 아주 중요한 아이디어이다.


또한, 멱급수 전개는 근사이론에서도 매우 중요한데,  x 에 대입하는 값이 절대값이 작은 경우, 고차항은 더더더 작아지기 때문에, 무시해도 정확한 함수값하고 별 차이가 생기지 않는다.  즉, 좋은 근사(approximation)를 얻을 수 있다. 이렇게 테일러 시리즈를 이용한 근사를 테일러근사 라고 한다.

테일러 근사에 대한 이야기는 다음에 따로 하도록 하겠다.



예제, 이항전개

f(x) = ( 1 + x ) ^k 승이라고 하자. 여기서 k 는 그냥 실수이다. 정수일 필요는 없다.

이것의 테일러 급수의 계수 an 을 구하기 위해, f(x) 를 n 번 미분해보도록 하자. n번 미분하고 0 을 대입한 후에, n! 로 나누면 그것이 an 이라고 했다.

n번 미분하면 일단 k 가 계수로 나오면서 곱해지고, 지수는 1 이 주는 행위가 n 번 반복된다. 그리고 0 을 넣어서 an 을 구한다.


우리는 원하던 테일러 급수를 얻었다. 주의할 것은 k 가 자연수일 필요가 없다는 것이다. k가 분수라든가 해도 상관없다.

만약 k 가 자연수인 경우에는 ,  k+1 번 미분할시 그냥 죽어버리므로, 서메이션은 k 까지 하게 된다.
그리고, k 가 자연수인 경우에, 테일러 계수의 분자부분은 k P n 이고, 이것을 n! 로 나눈것은  k C n 이 된다.

즉, k 가  자연수인 경우, 자연수 승에 대한 이항전개식과 같아진다.

따라서, 이항계수의 정의를 실수범위까지 확장하여, 다음과 같이 택하면...


실수 지수까지 확장된 이항정리를 얻을수 있다.