DO 는 루프문이다.  구문은 다음과 같다.

DO [ index_variable = index_start, index_end [,index_increment ]]
   ...

END DO

카운팅 루프를 위한 [ ]  부분은 옵션이다. [ ] 부분을 생략할 경우, DO ~ END DO 는 기본적으로 무한루프이다.
이경우, 반드시 루프 탈출을 위한 문장이 루프내부에서 실행되어야 한다.

탈출을 위해서 EXIT 를 사용할 수 있다.
IF 로 탈출조건을 제시하며 탈출하면 원하는 바를 수행하는데 용이하다.
즉, 루프내부에 다음과 같은 줄을 추가하는 것이다.

IF ( exit condition ) EXIT

물론, 탈출을 위한 IF , EXIT 가 위와 같이 한줄 IF 여야할 필요는 없다.
다음과 같이 블럭 IF 로 들어가도 된다.

IF ( exit condition )
  ...
  EXIT
END IF

또한, 루프바디 내부에 탈출을 시도하는 부분이 여러개여도 무방하다.




카운팅 루프를 위한 부분을 살펴보면, 첫번째 항은 루프변수의 시작값, 두번재항은 종료값, 세번째 값은 증가치이다.

루프변수는 정수타입이어야 한다. ( 이전버전에서는 실수타입도 사용가능했으나 95 에서는 제거되었다. )

index_start, index_end [,index_increment ]  부분은 상수일수도 있고, 변수일수도 있고, 수식일수도 있다.
다만, 루프시작전에 그 값들을 평가한다.

실행순서는 다음과 같다.
일단 루프시작시 카운팅제어 부분에 대한 평가가 실행된다.

루프변수의 시작값을 배정하는 부분이 우선 실행되고, 종료값과 비교하여 바디를 실행하거나 건너뛴다.
바디가 실행되면, 바디실행후, 증분만큼 증가 ( 값이 음수이면 감소) 시키고, 다시 비교하여 바디를 실행하거나 넘어간다.
바디를 실행시 위의 과정이 반복된다.

즉, 다음과 같은 구조일때,

DO expr 1 , expr 2 , expr 3
... body
END DO

1 -> 2 -> body -> 3 -> 2 -> body -> 3 -> 2 -> body -> 3 -> 2 -> ...    와 같은 순서이다.



루프변수와 종료값의 비교에 의한 바디 실행조건은, 증분값이 양수이냐 음수이냐에 따라 다르다.
양수인경우, 루프변수는 증가하고, 따라서 상식적으로 루프변수가 종료변수 이하일때 바디가 실행된다.
음수인경우, 루프변수는 감소하고, 따라서 루프변수가 종료변수 이상일때 바디가 실행된다.

증가분 부분이 생략되는 경우, 1로 간주한다.



루프변수도 역시 변수인 관계로, 루프 내부에서 조작 및 참조가 가능하다.
단, 루프변수를 루프내부에서 조작시, 루프 전체를 변화시키므로 주의가 요구된다.

루프종료시 루프변수의 값은 신뢰할 수 없다.
많은 컴퓨터/컴파일러 들이 루프종료후에도 루프변수값을 보존하지만, 포트란의 표준은 이에대해 보장하지 않는다.
따라서, 루프종료후의 코드가 루프변수를 참조한다면, 이식성에 문제가 생길수있으므로 주의를 요한다.



EXIT 가 루프자체를 완전히 탈출시킨다면,  CYCLE 은 컨트롤을 expr 3 으로 이동시킨다.

DO expr 1 , expr 2 , expr 3
... body
END DO

결과적으로 루프1회를  ( 하던데까진 하고, CYCLE 만난부분 부터..) 건너뛰는 기능을 한다.

EXIT 와 CYCLE 은 C의   break , continue 와  같다고 할 수 있다.



루프문에도 네이밍이 가능하다. 이는 앞의 IF 나 SELECT CASE 에서 처럼 네스티드 구조일때 상당한 효용을 제공한다.

name : DO
     ...
     ...  CYCLE [name]
     ...  EXIT  [name]
...
END DO name

DO 에 네이밍했으면 END DO 도 매치되는 네이밍을 요구한다.
CYCLE 과 EXIT 에 대해서는 네이밍은 옵션이지만 네이밍 할경우, 대응되는 루프의 네임과 매치되어야 한다.
포트란의 다중분기는 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개를 왼쪽에 올렸더니 수평을 이뤘다.

물체의 무게는 얼마인가?