반응형

 

월리스(Wallis)의 곱

 

월리스의 곱은 홀수, 짝수를 두 번씩 분모, 분자에 써서 무한 곱을 하는 형태입니다.  (분모 1은 한 번만)

이 값은 놀랍게도 수렴합니다. 그리고 이 값을 계산하기 위해서는 이것이 sin의 n제곱 적분과 관련이 있다는 것을 알아야 합니다. (이것을 처음 생각한 사람은 대단하지요.) 

 

먼저 sin의 적분을 통해 공식을 만들고 W와의 관련성을 생각해 봅시다. sin의 n승의 적분을 계산합니다.

(부분적분으로 왼쪽 sin을 적분하고 오른쪽 sin^(n-1)을 미분하는 파트로 정함)

오른쪽끝 부분을 왼쪽으로 넘겨 공통부분으로 묶어주면,

  (가장 앞에 마이너스가 빠졌네요. 추가..)

드디어 sin의 n제곱의 적분의 일반형으로 공식같은 것을 만들었습니다. 그런데 이 공식과 월리스의 곱이랑은 언듯보기에 아무 관계없어 보입니다. 좀 더 정리해 볼까요?

이렇게 놓으면

(가장 앞에 마이너스가 빠졌네요. 추가..)

위 적분 공식은 적분구간에 관계없이 항상 성립합니다. 그렇다면 적분 구간을 적당히 조절하면 왼쪽의 복잡한 식을 없애고, 분자,분모 1씩 차이나는 분수들의 연속적인 곱 형태로 바꿀 수 있을 것 같습니다.

 이번엔 이렇게 적분 구간을 주어 I를 다시 정의해 봅시다. 이렇게 되면 왼쪽 파트가 항상 0이되어 아래와 같이됩니다.

이렇게 정리됩니다.

분자,분모가 1씩 차이나고 n이 2씩 감소되면서 반복되는 형태입니다. 홀수, 짝수로 나누어 이것도 공식으로 만들어봅시다.

이러한 공식이 나옵니다. 

을 각각 구해보면, 

 

따라서 대입하여 정리하면

 

이렇게 정리해 놓고 보니, 월리스의 곱과 아주 유사하게 전개됩니다.

분자를 짝수만 놓게 해보고 곱하면 뭔가 나올 것 같습니다. 

에 역수를 구합니다.

위 두 개를 곱하면, W의 형태가 보이게 됩니다.

 

위와 같이 월리스의 곱이 정리되어 나옵니다. 여기서 또 오른쪽 부분의 극한값을 구해야 합니다.

은 sin(x)배를 더 한 쪽이 더 작습니다. (왜냐면 0~pi/2 구간에서 sin(x)는 0과 1사이의 값입니다. 0과1사이 값을 곱하면 곱할수록 원래값보다 작아집니다.) 그리고  적분값은 각각  그래프를 그리고 적분구간에 해당되는 넓이와 같기 때문에 이 함수들을 적분해도 함수의 대소관계와 같습니다. 따라서 

은 

보다 작거나 같게 됩니다. 마찬가지로 

는 

보다도 작거나 같습니다. (왜 같다고도 했는지는 극한값이라서 그렇습니다.)

그런데 

는 공식에 따라서

여기서 n을 극한으로 보내면 

이 됩니다.

위 대소관계 

 에서 보게되면  

이므로 가운데 끼인 

도 

과 같게 되는 것입니다. (샌드위치 정리)

따라서  ,  ,   

 

이렇게 월리스의 곱은 파이의 반이됩니다. 유리수들로 이루어진 값들의 무한 곱이 무리수가 되는 것이지요.

 


cf) 팁 

sin의 n승의 적분을 적분구간

 인 경우 아래 공식을 이용하면 쉽게 계산이 됩니다.  

n을 분모로 놓고, 분자는 하나 적은 n-1 곱하기  분모 n-2, 분자 n-3 곱하기... 반복. 계속 1씩 감소하면서 적어주면 됩니다. 마지막에만 주의해 주면 됩니다.

 

ex1)

ex2)

 


+파이썬으로 돌려보기

i값이 1, 2, ... n 까지 변해가면서 W값을 계산합니다.

v1 = 2i / (2i-1) = 2/1, 4/3, 6/5, ..., 2n/(2n-1)

v2= 2i / (2i+1 ) = 2/3, 4/5, 6/7, ..., 2n/(2n+1)

# wallis.py

import numpy as np

 

def wall(n):

W=1

for i in range(1,n+1):

v1=(2*i)/(2*i-1)

v2=(2*i)/(2*i+1)

W=W*v1*v2

return W

 

 

print('Wallis loop(10)=', wall(10))

print('Wallis loop(50)=', wall(50))

print('Wallis loop(100)=', wall(100))

print('Wallis loop(1000)=', wall(1000))

print('Wallis loop(10000)=', wall(10000))

print('Wallis loop(100000)=', wall(100000))

print('pi/2=', np.pi/2)

 

결과 확인

# python3 wallis.py

Wallis loop(10)= 1.5338519033217486

Wallis loop(50)= 1.5630394501077045

Wallis loop(100)= 1.5668937453140788

Wallis loop(1000)= 1.5704038730151892

Wallis loop(10000)= 1.5707570593409275

Wallis loop(100000)= 1.5707923998284614

pi/2= 1.5707963267948966

 
 

점점 pi/2에 수렴해 갑니다.

 

'Math' 카테고리의 다른 글

[이상한 수학] pi = 0?  (1) 2019.04.03
root i, 허수 i의 루트. 이게 말이 돼?  (0) 2019.04.01
적분팁 (Integration Tip). 이것만 알아도 적분속도향상.  (3) 2019.03.29
integral sec(x)  (0) 2019.03.28
integral csc(x)  (0) 2019.03.27
반응형


+ 적분팁 (Integration Tip)

-적분할 때 어떻게 접근하는게 빠를까?

아래 순서대로 접근해보면 도움이 많이 될 것이다. 1번이 안되면 2번으로 2번도 안되면 3번으로 등등 ...


1. 삼각 치환

아래 루트형태가 있을 때는 삼각함수로 치환한다.

로 치환한다. 

왜 그렇게 치환했는가?? 무조건 외우는건 금방 잊어 버린다. 왜 그런지 연상을 해야 잊어버려도 다시 유추하여 생각해 낼 수 있다.

생각해 보자... 보통 치환시키는 것은 치환한 것을 미분한 값이 나와야 치환한 의미가 있다.

치환한 x를 미분하면  .  쎄타 월드로 변경했을 때 미분한 값이 cos이 튀어 나온다.   그리고, x를 sin으로 치환하여 1-sin^2 형태가되어 루트를 씌우면 cos이 튀어 나오는  거랑 통하게 된 것이다.

이렇게 발상하면 지극히 당연히 sin으로 치환하는게 좋겠다는 생각이 든다.


로 치환한다.

루트 형태에서 1+tan^2은 sec^2이 되어 sec가 튀어나올 것이고, x를 미분하면 sec^2이 될 것이다. 비슷하다. 다른 항에 따라 잘될 수도 안될 수 도 있다.


로 치환한다.

루트형태에서 sec^2-1꼴이 나올 것이고, 여기서 루트를 씌우면 결국 tan가 튀어나올 것이고, x를 미분하면 sec * tan가 튀어나오게 된다. 이것도 주변 항에 따라 가능여부가 결정된다. 가장 좋은 것은 sec항이 있어준다면 럭키가 된다. 


2. 부분 적분

 이렇게 설명하기도 하고

 이렇게 설명하기도 한다. 똑같은 거다.

f'(x)를 dv라고 생각하고 f(x)를 v로 보면 된다. u는 g(x)이고, du는 g'(x)이다.

여기서 항상 고민인것은 어느 파트(dv)를 적분하고 어느 파트(u)를 미분할 것이지 선택하는 것이다. (어떤 것을 dv로 놓고 어떤 것을 u로 볼것인가?)

보통은 미분할 항(u)을 LIATE 순서로 선정한다..  그 의미는.

Logarithmic(ln), Inverse trigonometric (arctan, arcsin, ..) , Algebraic (5x^2, 3, ..) , Trigonometric(sin, cos..) , Exponential(10^x, e^x)

로그, 인버스, 대수, 삼각, 지수 

예를 들어 x e^x 를 적분한다고 하면, 대수와 지수함수가 나오므로 대수가 먼저 순서라그 대수인 x를 미분하고 e^x를 적분한다. 그렇게 하려면 x를 g(x) or u로 보고, e^x를 f'(x) or dv로 본다.


3. 유리 함수는 분모를 인수분해하여 부분분수형태로 접근한다.

분수꼴인 경우 분모를 인수분해하고 인수항들을 각각 분모로 하는 항들의 합인 형태로 변환한다. 분자는 a, b, c 등으로 놓고 통분했을때 원래의 형태가 맞게 나오게 방정식을 세워서 풀면된다.

예를 들면


4. 무리 함수는 루트부분을 치환한다. 통째로 할수도 있고 루트 x만 치환할 수도 있다. 

n제곱근과 m제곱근의 형태가 모두 나오면 n,m의 최소공배수 제곱근을 치환해 본다.

예를 들면 2제곱근 x + 3제곱근 x 이런 형태이면 6제곱근 x를 치환해 본다.


5. 지수함수를 치환한다. ( t = e^x )


6. 삼각함수들이 섞인 경우.

이것은 여러가지 접근해 시도해봐야 한다. 왕도는 없다.

sin, cos, tan, sec, csc, cot 들의 미분형태, 적분 형태를 어느 정도 알아야 한다. 외우기 힘들면 유도할 수 있어야 한다. 

sin, cos 배각 ( sin 2t = 2sin t cos t , cos 2t = cos^2 - sin^2 = 1-2 sin^2 = 2 cos^2 - 1)

cos^2 t = (1+cos2t) / 2

sin^2 t = (1-cos2t) / 2

1=sin^2+cos^2. 

분자 분모에 어떤 삼각함수를 곱할지..

무엇을 치환할 것인지. 치환할 부분을 미분하면 형태의 항이 나오게 되어 지워지는 부분이 있을지 등등...

짝수배 제곱의 형태이면 반각 공식등이 잘 먹히고   (sin^2 x = (1-cos 2t ) / 2 )

홀수배 제곱의 형태이면 하나를 분리하여 생각해 본다. ( sin^3 x  = sin x * sin^2 x )


7. inverse 삼각함수가 섞인 경우.

inverse함수를 원래 함수로 바꿔서 이것은 직각삼각형을 그려보면 다른 삼각함수들의 값을 쉽게 구할 수 있다.

arctan x = y 라면 tan y = x 가 되고, 직각 삼각형을 만들어 보고, 밑변을 1, 대변을 x, 끼인각을 y로 보면 된다. 빗변은 피타고라스로 구한다. 이제 cos y, sin y 를 쉽게 구할 수 있다.



'Math' 카테고리의 다른 글

root i, 허수 i의 루트. 이게 말이 돼?  (0) 2019.04.01
월리스(Wallis)의 곱. 이젠 이해할 수 있다.  (1) 2019.04.01
integral sec(x)  (0) 2019.03.28
integral csc(x)  (0) 2019.03.27
최소제곱법  (0) 2019.03.26
반응형


+ Python에서 Enum 사용하기


C나 C++에서 편하게 쓰던 enum이 python에서는 기본으로 없고 쓰기가 좀 불편합니다.

열거형(enum)은 상수와 같이 지정된 값을 이름을 부여하여 코드내에 가독성이 좋게 사용하기 위해 씁니다.

C로 예를 들면 상수타입을 그대로 쓸수도 있지만, 아래와 같이 불편합니다.

const int APPLE=1

const int BANANA=2

const int GRAPE=3

각각 값을 지정해 줘서 써도 되지만 번거롭습니다. 그래서 enum을 쓰죠.

enum Fruit {

APPLE=0,BANANA, GRAPE } ;

각 항마다 =1, =2 이렇게 값을 지정할수도 있고, 생략하면 순차적으로 이전 항보다 1씩 증가합니다. 

#include <stdio.h>


enum _fruit {

APPLE=0,

BANANA, GRAPE

};


int main()

{

enum _fruit a,b ;

a=APPLE ;

b=BANANA;

printf("a=%d\n", a) ;

printf("b=%d\n", b) ;

return 0 ;

}


C에서 보통은 좀 더 쓰기 편하기 typedef로 정의해서 사용하죠.

typedef enum _fruit {

APPLE=0,

BANANA, GRAPE

} FRUIT;


int main()

{

FRUIT a,b ;

a=APPLE ;

b=BANANA;

printf("a=%d\n", a) ;

printf("b=%d\n", b) ;

return 0 ;

}



파이썬에서는 enum을 아래와 같이 쓴다. 별도로 모듈을 임포트해줘야 한다. 

import enum


class Fruit(enum.Enum):

APPLE=0 

BANANA=1 

GRAPE=2


print(Fruit.APPLE)

print(Fruit.BANANA.value)

print(Fruit.GRAPE.value)


실행결과

Fruit.APPLE

1

2


값을 가져오려면 별도로 .value 프로퍼티를 써야 한다.

enum 변수값을 모두 각각 지정해 주어야 한다. 불편하다.


모듈 임포트 할 필요없이 별도로 함수를 만들어 enum을 쓰는 것이 편하다. 인덱스는 0부터 시작. 

def enum(*sequential, **named):

    enums = dict(zip(sequential, range(len(sequential))), **named)

    return type('Enum', (), enums)


Fruit = enum('APPLE','BANANA','GRAPE')


print(Fruit.APPLE)

print(Fruit.BANANA)

print(Fruit.GRAPE)


실행결과
0
1
2


+ Recent posts