크리스마스 이브면서 토요일인데 난 왜 할 일이 많은 걸까.
파이썬에서 함수 짜는 과정은 큰 것부터 작은 것으로 들어가는 게 편하다.
일단 목적하는 밑그림을 설계해 두고, 필요한 부품들을 조금씩 채워 나가는 것이다.
이러한 방식을 'Incremental development' 라고 부른다.
입문 시 원하는 일을 설계하면서 뇌정지가 오는 상황을 막을 수 있다.
예를 들면,
라마누잔과 파이 - 수학노트
개요 라마누잔은 1914년에 다음과 같은 공식을 발표 [RAM1914]\[\frac{1}{\pi}= \frac{2\sqrt2}{9801}\sum_{n=0}^{\infty}\frac{(4n)!(1103+26390n)}{(n!)^{4}396^{4n}}\] Chudnovsky 형제 [CHU88] \[\frac{426880 \sqrt{10005}}{\pi} = \sum_{k=0}^\inf
wiki.mathnt.net
$$ \frac{1}{\pi}=\frac{2\sqrt{2}}{9801}\sum_{k=0}^\infty \frac{(4k!)(1103+26390k)}{k!^4396^{4k}} $$
라마누잔의 원주율 공식을 이용해 원주율 근삿값을 찾아보자.
일단 식을 그대로 스케치 한다.
import math
def pi():
k=0
value=update_res(k)
res=value
while value>1e-16:
k=k+1
value=update_res(k)
res=res+value
return 2*math.sqrt(2)*res/9801
- input 변수는 필요 없다.
- 라마누잔 공식의 시그마 이하의 값을 return해주는 함수를 update_res(k) 로 만들기로 했다. 저 자리에 계산을 그대로 때려 박기에는 공식이 복잡해서 헷갈릴 것 같다.
- sqrt를 처리해 주려면 math 모듈이 필요하다.
- 주피터에서 표시되는 소숫점 아래 숫자가 16자리라서, 시그마 아래의 더해주는 값이 그보다 작으면 연산을 멈추도록 했다.
그래서 이제 필요한 것은 update_res(k) 를 정의해 주는 것이다.
def update_res(k):
num=factorial(4*k)*(1103+26390*k)
denum=(factorial(k)**4)*(396**(4*k))
value=num/denum
return value
import math
def pi():
k=0
value=update_res(k)
res=value
while value>1e-16:
k=k+1
value=update_res(k)
res=res+value
return 2*math.sqrt(2)*res/9801
(import math 이하의 라인은 이전의 코드박스와 완전히 동일하다. 전체 그림을 보여주기 위해 복사 붙여넣기 했다)
update_res(k)의 바디는 그냥 내 개인적인 스타일인데, 각 라인이 최대한 간결하도록 간단한 연산이라도 여러 줄에 나눠서 코드를 작성한다. 나중에 문제가 생겼을 때 알아보기가 쉽다.
파이썬에서는 \( a^b\)를 a^b가 아니라 a**b로 쓴다는 것만 유의하면 어렵지 않다.
그런데 또 update_res(k)를 돌리려면 factorial이 필요하다.
물론 파이썬의 math 모듈에서 팩토리얼 함수를 지원하기는 하지만, 이 포스트는 점진적인 개발 과정의 예시로 쓰고 있으므로 factorial을 새로 짜는 과정이 필요하다고 치자.
필요한 걸 또 추가하자.
def factorial(k):
res=1
while k>0:
res=res*k
k=k-1
return res
def update_res(k):
num=factorial(4*k)*(1103+26390*k)
denum=(factorial(k)**4)*(396**(4*k))
value=num/denum
return value
import math
def pi():
k=0
value=update_res(k)
res=value
while value>1e-16:
k=k+1
value=update_res(k)
res=res+value
return 2*math.sqrt(2)*res/9801
이제 됐다. 코드는 아래서부터 짰지만, 돌리기는 위에서부터 돌리면 된다.
더이상 새로 만들어야만 하는 것이 없으므로 결과를 보자.
pi() # 0.3183098861837907
1/math.pi # 0.3183098861837907
개인적으로 군대에선 초코파이보다 몽쉘 좋아했음
'비단뱀과 알 > 미세 팁' 카테고리의 다른 글
[R] 네임스페이스 어쩌고 오류 메모 (0) | 2023.10.24 |
---|---|
[R] Signac / Seurat ; Single Cell RNA-ATAC Joint Analysis 소개 및 패키지 설치 오류 몇 가지 (0) | 2023.01.13 |
[R] 로또 번호를 점지해보자 (feat. Random sampling) (0) | 2022.11.23 |