장 진희의 모든 글

Makefile

  • 기본구조
    • 목표: 의존파일들
      (탭문자)명령
  • 명령에 쓸 수 있는 특수 문자들
    • $@ – 목표 그대로를 의미함
    • $^ – 의존파일 전체 리스트를 의미함
    • $< – 의존파일에서 제일 첫번째 있는 파일을 의미함
    • $* – 목표에서 확장자를 뗀 파일명만을 의미함
    • ; \ – 명령 문장 끝에 써줘서 다음 줄이 같은 쉘에서 실행되도록 한다. 예를들어 첫번째 명령이 A라는 폴더로 들어가는거고 두번째 명령이 거기에 B라는 폴더를 만드는거라고 하면, 이 문자를 쓰고 안쓰고에 따라 A안에 B가 있느냐 A와 B가 같은 폴더안에 있느냐가 갈리게 된다. 두 문자가 셋트임에 주의.
    • @ – 명령 문장 제일 앞에 써서 명령어가 실행될때 쉘에서 보이지 않게 한다.
    • % – 모든것을 의미 (쉘에서의 * 같은 의미)
  • .PHONY
    • 이것도 나중에
  • .SUFFIXES – 지정된 확장자를 가진 파일에 대해 동일한 처리를 하도록 하는 명령어인데….
    아래 명령어로 대체 가능하다길래 무시하기로 하고 정리 안함

    • %.o: %.cc
      (탭문자)명령
  • 변수 정의법
    • VARIABLE = 어쩌구저쩌구 # 정의
    • $(VARIABLE) # 사용
  • 환경변수가 정의돼있는지 확인할 때 if문
    • ifdef ENVIRONMENT_VARIABLE
    • 어쩌구
    • else
    • 어쩌구
    • endif
  • 쉘에서 실행한 결과를 사용하고 싶을 때
    • $(shell 명령어)
  • 뒷쪽 이름에 앞쪽 이름을 다 붙이고 싶을 때
    • $(addprefix 앞, 뒤)
    • 출력되는 결과는 “앞뒤”. 만약 “뒤”에 오는 내용이 스페이스로 구분된 문자라면, 스페이스 다음에 나오는 문자에는 다 앞이 붙는다. 예를들어 “뒤 = a b c d” 라면 위 명령의 결과는 “앞a 앞b 앞c 앞d” 가 된다.
  •  쉘에서 ls를 쳐서 나오는 모든 cc확장자를 가진 파일을 리스트로 만들고 싶을 때
    • $(wildcard *.cc)
    • 만약 어떤 디렉토리 안에 들어가서 가져오고 싶으면 앞에 경로도 같이 써주면 된다.
  • 어떤 문자에서 단어를 치환하고 싶을 때
    • $(patsubst 이거를, 이걸로, 여기서)
    • 예) $(patsubst %.c, %.o, x.c.c bar.c)
      결과) x.c.o bar.o
  • 변수에 여러개의 아이템이 있는데, 한개만 지우고 싶을 때
    • $(filter-out 이거를,여기서)
    • 예)
      HEADER = A B C D
      HEADER2 = $(filter-out D,$(HEADER)) # 결과는 HEADER2 = A B C
  • 조건문도 사용할 수 있다. (ifeq, ifneq)
    • ifeq (A,B)
      내용
      else
      내용2
      endif

Root Mean Square (RMS)

우리말로 평균 제곱근이라고 하는 이 값은 수학에서는 다음과 같이 정의한다.

\[x_\text{rms}=\sqrt{\frac1n\sum_{i=1}^n x_i^2}\]

ROOT v5.34.04 버전 기준으로 TH1의 GetRMS()라는 메소드와, 특정 집단의 사람들이 RMS라고 말을 하면서 표준편차를 사용하는 경우가 있으니 주의하자. 참고로 GetRMS()에서 나오는 값은 표준편차이고 다음과 같이 정의된다.

\[\sigma=\sqrt{\frac1n\sum^n_{i=1}(x_i-\mu)^2}\]

물론 \(\mu\)는 분포의 평균이다. 자유도 글을 잘 생각해보면 \(n\)으로 나누는것이 아니라 \(n-1\)로 나누는게 더 좋은 값을 준다는 것을 알 수 있다.

Byte 순서 (Big-endian & Little-endian)

Big-endian은 값을 앞에서부터 기록하고, Little-endian은 값을 뒤에서부터 기록한다고 알고있자. 예를들어, 0x12345678을 binary로 기록한다고 하면, 각각은 다음과 같이 기록된다.

  • Big-endian: 12 34 56 78
  • Little-endian: 78 56 34 12

C++에서 ‘#include <arpa/inet.h>’를 이용해 include 해 주면, Byte 순서를 바꿔주는 네가지 함수를 사용할 수 있다.

  • uint16_t ntohs(uint16_t)
  • uint32_t ntohl(uint32_t)
  • uint16_t htons(uint16_t)
  • uint32_t htonl(uint32_t)

각각 uint16_t 또는 uint32_t형 변수를 받아서, uint16_t 또는 uint32_t형 변수를 반환한다. 입력 된 변수의 주소값 Byte 순서를 바꿔서 반환하므로, 반환되는 값은 전혀 다른값이 돼 있다. 물론 값을 쓰려고 이런일을 하는건 아닐테니 그냥 참고사항으로 적어둔다.

위 함수들은 XtoY(s,l) 형태로 이해하면 되는데, X에서의 Byte순서의 (short, long) 변수를 Y에서의 Byte순서로 바꿔서 반환하라는 의미이다. 만약 X에서의 Byte순서와 Y에서의 Byte순서가 같다면 입력값이 그대로 반환된다.

참고로 uint16_t 와 uint32_t에서 u는 unsigned를 의하고, 16과 32는 각각 비트수를 의미, _t는 typedef를 이용해서 정의된 변수형이라는 의미이다. 따라서 uint16_t는 unsigned형 int이기 때문에 음수는 사용할 수 없고, 16비트이므로 2바이트의 크기를 가지는 변수형이라는걸 알 수 있다.

Symbolic link 사용시 주의사항!

예를들어 /home/geniejhang/test 라는 폴더를 symbolic link로 /home/geniejhang/test_sym 이라고 만들었다고 해보자.

이 상태에서 rm -rf /home/geniejhang/t 까지 치고 tab을 누르면 /home/geniejhang/test 까지 완성되고, _를 친 다음 다시 tab을 누르면 /home/geniejhang/test_sym/ 까지 완성된다!

여기서 주의 할 곳은 /home/geniejhang/test_sym여기서의 마지막 슬래시! 이놈이 있을 때, rm -rf 를 해버리면 폴더 안에 있는 내용이 다 날아간다ㅠ

Symbolic link를 지울땐 rm으로 하자ㅠㅠ

Chi-squared Test

어떤 것을 측정하는 실험을 한다고 할 때, 측정을 매우 많이 반복해서 얻을 수 있는 측정값의 분포는  가우시안(Gaussian) 분포, 이항(binomial) 분포 그리고 푸와송(Poisson) 분포로 크게 3가지가 있다.

실험을 한 후에 얻은 분포가 정말 맞는 분포인지 테스트 할 때 \(\chi^2\) 테스트를 사용한다. 측정값이 연속적인 값이든 불연속적인 값이든 상관없이 데이타를 한 빈에 5개 이상이 들어가고 빈 수가 4개 이상인 히스토그램으로 만든다. \(\chi^2\)는 다음과 같이 정의된다.

\[\chi^2=\sum^N_{k=1}\frac{(O_k-E_k)^2}{\sigma_k^2}.\]

위 식에서 \(E_k\)는 \(k\)번째 빈에 기대되는 데이타 갯수이고, \(O_k\)는 \(k\)번째 빈의 측정 데이타 갯수, \(\sigma_k\)는 테스트할 분포의 \(k\)번째 빈에서의 통계오차이다. 이렇게 구한 \(\chi^2\)값이 자유도 \(d\)근처에 있거나 작으면 기대했던 분포와 같은 결과임을 의미한다.

비교를 쉽게 하기 위해 \(\chi^2\)를 자유도 \(d\)로 나눠준 값을 reduced \(\chi^2\)라고 한다.

\[\tilde{\chi}^2=\frac{\chi^2}{d}.\]

이 때에는 \(\tilde{\chi}^2\)값이 1보다 많이 크지 않거나 작으면 우리가 예상했던 분포와 맞다는 것을 의미한다.

\(\tilde{\chi}^2\)값이 1보다 큰 경우, 우리가 실험에서 얻은 reduced \(\chi^2\)를 \(\tilde{\chi}^2_0\)라고 하면, 자유도 \(d\)에서의 \(\tilde{chi}^2\) 확률분포를 이용해서 \(\tilde{\chi}^2_0\)보다 큰 값이 나올 확률을 구하여 분포가 맞는지 틀리는지 여부를 결정한다.

\(N\)개의 데이타 포인트가 있을 때, 가장 일반적인 \(\chi^2\)의 정의는 다음과 같다.

\[\chi^2=\sum^N_{i=1}\left(\frac{y_i-f(x_i)}{\sigma_i}\right)^2.\]

\(f(x_i)\)는 \(x_i\)에서 기대되는 값, \(y_i\)는 실험값, \(\sigma_i\)는 표준편차이다.

Degrees of freedom: 통계 계산에서의 자유도

예를들어 \(N\)개의 데이타 포인트를 가지고 이 점들을 가장 잘 설명하는 일차함수를 찾는다고 하자. 이 때 찾아야 할 미정계수는 절편값과 기울기로 2개이다.

여기서 자유도는 측정한 횟수에서 찾아야 할 미정계수를 뺀 수로 정의한다. 따라서, 위 예제의 자유도는 \(N-2\)가 된다.

(2013. 4. 6) 추가

\(N\)개의 데이타 포인트를 가지고 평균값을 구했다고 해보자. 이 때, 평균값을 가지고 있으면, \(N-1\)개의 데이타 포인트만 있으면 나머지 하나의 값은 구해낼 수 있기 때문에, 이 계의 자유도는 \(N-1\)이 된다.

자유도는 데이타 포인트의 갯수에서 제한자의 갯수를 빼준 수로 정의한다. 제한자는 데이타 포인트를 통해서 계산해낸 값을 말한다.

 

  • 참고 문헌

  1. John R. Taylor, An Introduction to Error Analysis 2nd Edition, University Science Books (1997).

Least-squares Fitting

최대 우도(maximum likelihood) 방법을 이용한 일련의 실험 포인트를 가장 잘 맞추는 직선을 찾아내는 해석적인 방법을 선형 회귀(linear regression) 또는 선의 최소 제곱 핏(least-squares fit for a line)이라고 한다.

 

  • Linear fit

우리가 측정한 실험 데이타 포인트들이 1차 함수를 따라야 한다고 하고, 이 함수를 다음과 같이 정의하자.

\[y=ax+b\]

측정값의 \(x\)의 오차는 무시할 수 있다고 가정하고, \(y\)의 오차는 진실값에서 표준편차 \(\sigma_y\)를 가지는 가우시안 분포로 존재한다고 할 때, \(i\)번째 값 \(y_i\)를 얻을 확률은 다음과 같다.

\[P(y_i)\propto\frac1\sigma_ye^{-(y_i-ax_i-b)^2/2\sigma_y^2}\]

\(N\)개의 데이타 포인트를 얻을 확률은, 각각의 확률의 곱으로 나타낼 수 있으므로,

\[P(y_1,\cdots,y_N)\propto\frac1{\sigma_y^N}e^{-\sum_i(y_i-ax_i-b)^2/2\sigma_y^2}\]

와 같이 나타낼 수 있고, 여기서 지수함수의 지수부분의 합을 다음과 같이 \(\chi^2\)로 정의한다.

\[\chi^2=\sum^N_{i=1}\frac{(y_i-ax_i-b)^2}{\sigma^2_y}\]

미정계수 \(a\)와 \(b\)의 최적 추정값은 주어진 데이타 포인트들을 얻을 확률을 가장 크게 하는, 즉 \(\chi^2\) 값을 가장 작게 하는 방식으로 얻어낸다. \(\chi^2\) 값은 2차 함수이기 때문에 임의의 0이 아닌 임의의 값 \(a\)에 대해 최소값을 항상 가지고, 이 값은 \(a\)와  \(b\)로 \(\chi^2\) 값을 미분해서 얻어낼 수 있다.

미분값이 0이 되는 \(a\), \(b\)에 관한 두 식을 적어보면,

\[\begin{split}a\textstyle\sum x_i+bN&=\textstyle\sum y_i \\ a\textstyle\sum x_i^2+b\textstyle\sum x_i &=\textstyle\sum x_iy_i \end{split}\]

와 같고, \(a\), \(b\)의 값은 다음과 같다.

\[a=\frac{N\textstyle\sum x_iy_i-\textstyle\sum x_i\textstyle\sum y_i}{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2},\quad b=\frac{\textstyle\sum x_i^2\textstyle\sum y_i-\textstyle\sum x_i\textstyle\sum x_iy_i}{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2}.\]

이렇게 얻어진 선을 데이타의 최소 제곱 핏(least-square fit) 또는 x에 대한 y의 회귀선(line of regression)이라고 한다.

 

  • 측정값 \(\mathbf{y}\)의 표준편차 \(\mathbf{\sigma}_\mathbf{y}\)

측정값 \(y\)는 참값 주위로 가우시안 분포를 가지고 있기 때문에, 최적 추정 핏으로 얻은 값 주위로 가우시안 분포를 가지고 있다고 볼 수 있다. 따라서 표준편차는 다음과 같이 구할 수 있다.

\[\sigma_y=\sqrt{\frac1N\sum(y_i-ax_i-b)^2}.\]

하지만, 데이타 포인트들을 가지고 미정계수 2개(\(a\), \(b\))를 구해냈기 때문에, \(N\)자리에는 이 계산에서의 자유도 \(N-2\)를 넣어 다음과 같이 표준편차를 구한다.

\[\sigma_y=\sqrt{\frac1{N-2}\sum(y_i-ax_i-b)^2}.\]

 

  • 미정계수 \(\mathbf{a}\)와 \(\mathbf{b}\)의 오차

\[a=\frac{N\textstyle\sum x_iy_i-\textstyle\sum x_i\textstyle\sum y_i}{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2},\quad b=\frac{\textstyle\sum x_i^2\textstyle\sum y_i-\textstyle\sum x_i\textstyle\sum x_iy_i}{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2}.\]

위 식에서, 각각을 오차 전파식을 사용해서 구해내면 된다. 다음과 같다.

\[\sigma_a=\sigma_y\sqrt{\frac N{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2}},\quad\sigma_b=\sigma_y\sqrt{\frac {\textstyle\sum x_i^2}{N\textstyle\sum x_i^2-(\textstyle\sum x_i)^2}}\]

 

  • 측정값 \(y\)의 각각의 표준편차가 다를 경우

가중 최소 제곱(weighted least-squares) 방법을 사용해야 한다. 별 다른건 없고, \(\chi^2\)의 \(\sigma_y\)를 각 항에 맞는 표준편차인 \(\sigma_i\)로 바꿔준 후 계산하면 된다.

 

  • 실제 적용을 위한 Tip

위에서 얻은 두 식을 행렬로 적어보면,

\[\left[\begin{matrix}\textstyle\sum x_i & N \\ \textstyle\sum x_i^2 & \textstyle\sum x_i \end{matrix}\right]\left[\begin{matrix} a \\ b \end{matrix}\right]=\left[\begin{matrix}\textstyle\sum y_i \\ \textstyle\sum x_iy_i\end{matrix}\right]\]

와 같이 적을 수 있고, \(a\)와 \(b\)는 내부 함수로

\[\left[\begin{matrix} a \\ b \end{matrix}\right]=\left[\begin{matrix}\textstyle\sum x_i & N \\ \textstyle\sum x_i^2 & \textstyle\sum x_i \end{matrix}\right]^{-1}\left[\begin{matrix}\textstyle\sum y_i \\ \textstyle\sum x_iy_i\end{matrix}\right]\]

을 계산하면 쉽게 얻을 수 있다.

(2013. 4. 5) 라고 생각했지만 오차까지 계산할거면 행렬보다는 단순합이 더 나은 것 같다.

 

  • 의문

  1. 오차가 임의적일 때 측정값 \(y\)의 표준편차는 어떻게 구할 것인가?
    1. 오차가 임의적이면 실험을 잘못한거다. 어떤 값이 1차함수로 피팅돼야 한다면, 참값주위에 측정값이 많이 분포할 수 밖에 없다.

 

  • 참고문헌

  1. John R. Taylor, An Introduction to Error Analysis 2nd Edition, University Science Books (1997).

Linux Terminal 단축기 (당연 맥에서도 됨)

  • Ctrl + A
    • 지금 치고 있는 줄의 제일 앞으로 커서를 이동
  • Ctrl + E
    • 지금 치고 있는 줄의 제일 뒤로 커서를 이동
  • Ctrl + U
    • 지금 커서가 있는 위치부터 앞을 지워버림
  • Ctrl + K
    • 지금 커서가 있는 위치부터 뒤를 다 지워버림
  • Ctrl + W
    • 지금 커서가 있는 위치부터 앞 한 단어를 지워버림
  • Ctrl + R
    • 이전에 친 명령어를 검색해서 찾음
    • history 에서 나오는 것들을 검색으로 찾을 수 있다고 보면 됨
    • 한번 더 누르면 더 과거의 겂이 나옴
  • Ctrl + F (→, Forward), Ctrl + B (←, Backward)
  • Ctrl + P (↑, Previous), Ctrl + N (↓, Next)
  • Ctrl + Y
    • Ctrl + U, K, W로 방금전에 지워버린 내용을 붙여넣기
  • Ctrl + M
    • 엔터
  • Ctrl + D
    • 지금 커서가 있는 위치의 문자 지우기
    • 아무것도 없을땐 exit 명령어와 동일

gfortran on OSX

http://hpc.sourceforge.net

이곳에 가면 자신의 OSX에 맞는 gfortran 바이너리를 받을 수 있다. 압축을 풀면 “usr”폴더가 나오는데, 무시하고 “usr” 안에 “local” 폴더를 “/Applications/gfortran-v#.#” 폴더로 이름을 바꿔서 옮긴다. 그 다음 환경변수를 입력해주면 된다. 아래 예시를 적어둔다.

# for gfortran
export PATH=$PATH:/Applications/gfortran-v4.8/bin
export MANPATH=$MANPATH:/Applications/gfortran-v4.8/share
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Applications/gfortran-v4.8/lib

마지막으로, 컴파일시에 라이브러리가 필요한 경우, LDFLAG에 “-L/Applications/gfortran-v#.#/lib -lgfortran” 이 들어가도록 잘 수정해주면 된다.