2017-12-27 8 views
1

Brent-Salamin algorithm의 변형을 R에 구현하려고합니다. 처음 25 번의 반복에서는 잘 작동하지만 예기치 않게 작동하여 부정적인 결과를 반환합니다.R에서 파이를 계산하는 알고리즘 구현

제가 구현하려는 알고리즘은 다음과 같습니다

n은 현재 반복이다
initial values: 
x_0 = 1; y_0 = 1/sqrt(2); z_0 = 1/2 

x_n = (x_n-1 + y_n-1)/2 
y_n = sqrt(x_n-1 * y_n-1) 
z_n = z_n-1 - 2^n * (x_n^2-y_n^2) 

p_n = (2 * x_n^2)/z_n 

.

더 아름답게 서식이 지정된 수식은 here입니다.

내가 알아 낸 코드는 다음과 같습니다

mypi <- function(n){ 

    x = 1 
    y = 1/sqrt(2) 
    z = 1/2 
    iteration = 0 

    while(iteration < n){ 
    iteration = iteration + 1 

    newx = (x + y)/2 
    y = sqrt(x * y) 
    x = newx 
    z = z-(2^iteration * (x^2 - y^2)) 
    p = (2 * x^2)/z 
    } 

    return(p) 
} 

출력 : 내가 R에 새로운 오전 그래서으로

> mypi(10) 
[1] 3.141593 
> mypi(20) 
[1] 3.141593 
> mypi(50) 
[1] -33.34323 

, 내 코드에 버그가 있거나 알고리즘입니까?

+0

경우'에서 오는 i' 않습니다 준다? – AdamO

+0

@AdamO'iteration'이 아니라'i'가 아닌'iteration'으로되어 있습니다. –

+1

약 20 분 동안 코드를 가지고 놀고 나면 정확한 대답이 없으며 설명 이외에 하나가 있는지 확실하지 않습니다. 부동 소수점 산술 연산의 한계 때문일 수 있습니다. 음수를보기 시작하기 전에 거의 50 번 반복 해 보았습니다. 나는 많은 반복을 한 후에'z'의'2^iteration' 용어가 너무 커지고'x^2 - y^2' 용어가 너무 작아 져서 반올림 등이 시작될 것이라고 생각합니다. 음수는 그냥 인공물입니다. –

답변

11

위키 페이지에 작성된 알고리즘과 일치하지 않기 때문에 코드가 단순히 망가집니다. 원래 올바른 버전은 다음과 같습니다

mypi <- function(n){ 

    x = 1 
    y = 1/sqrt(2) 
    z = 1/4 
    p <- 1 

    iteration = 0 

    while(iteration < n){ 
    iteration = iteration + 1 

    newx = (x + y)/2 
    y = sqrt(x * y) 
    # x = newx 
    # z = z-(2^iteration * (x^2 - y^2)) 
    z = z- p* (x-newx)^2 
    p = 2*p 
    x = newx 
    } 

    (newx + y)^2/(4*z) 
} 

> mypi(10) 
[1] 3.141593 
> mypi(20) 
[1] 3.141593 
> mypi(50) 
[1] 3.141593 
+0

좋은 캐치 ... 코드 자체의 정확성을 검사 할 생각이 없었습니다 +1 –

+0

답장을 보내 주셔서 감사합니다. 내 질문의 첫 번째 문장에서 쓴 것처럼 알고리즘의 변형을 구현하려고했지만 결과로 인해 정확성에 대해 확신 할 수 없었습니다. 이것은 내가 R 코드에 버그가 있거나 문제가 알고리즘 자체인지 확인하기 위해 질문 끝에 질문했습니다! 25 개 이상의 반복에 대해 변형이 잘못되었지만 변형의 구현이 괜찮 으면 내 질문에 대답하고 나에게 매우 도움이 될 것입니다. 그래서 '잘못된'알고리즘의 구현 내에서 문제를 발견 했습니까? – amadeusamadeus

+0

@amadeusamadeus 알고리즘을 디버깅하려면 math.stackexchange.com에있는 사람들이 여러분을 도울 수 있어야한다고 생각합니다. 나는 이것을 어떻게 파생 시켰는지 100 % 확신하지 못했습니다 ... $ * pi $의 분수를주는 아크 탄젠트 값에 대한 Householder의 알고리즘처럼 보이는 * 종류의 * 것입니다. 어쨌든 알고리즘은 아름답게 형식화 된 수식과 일치하므로 문제는 없습니다. 마지막으로 고려해야 할 사항 : 대부분의 알고리즘은 완료된 고정 반복을 기반으로하지 않고 목표 정밀도를 달성 할 때 종료됩니다. 50 반복은 부동 소수점 정밀도의 한계에 도달 할 수 있습니다 ... – AdamO