2013-02-22 3 views
0
pi/2 = 1 + 1/3 + (1*2)/(3*5) + (1*2*3)/(3*5*7) + ... 

자, 다시 시도해보십시오.파이를 사용하여 파이를 계산하려면 시리즈를 사용하십시오.

최대 오류를 pi 값의 매개 변수로 사용하고 pi 값과 그 지점으로 이동하는 데 필요한 반복 횟수를 계산하는 함수를 작성해야합니다. 재귀 알고리즘을 사용할 수 없습니다.

는 지금까지 내가 가진 :

def piEuler (x): 
    count = 0.0 
    approx = 0.0 
    approx2 = 1.0 
    error = math.pi/2 - approx2 
    while error > x: 
     count = count + 1 
     approx3 = approx + approx2 
     error = math.pi/2 - approx3 
     #print error 
     approx = approx + approx2 
     approx2 = approx2 * count/(count + 2) 
     #print approx2 
    final = math.pi - error 
    return final, count 

문제는 프로그램이 음의 값을 반환한다는 것입니다. 오류는 0으로 수렴되어야합니다. 시리즈의 근사값을 얻기 위해 pi의 허용 된 값에서 오류를 뺄 수 있어야합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

+0

분모 항목이 올바르지 않습니다. 'k = 1,2, .., n/2'에 대해'3 * 5 * ... * (2 * k + 1)'의 산물을 계산해서는 안됩니까? 3 * 4 * 5 * ... * n을하고있는 것처럼 보입니다. 이것은 더 큰 숫자를 줄 것이고 왜 그 시리즈가'pi/2'보다 큰 숫자로 합산되어서 오차항을 절대 값으로 증가시키는지를 설명 할 것입니다 (그러나 실제 값은 감소합니다, 즉 음수가됩니다). –

+0

@JoelCornett 답변으로 게시해야합니다. –

+0

@ Jon-Eric : 좋은 전화. –

답변

1

알고리즘을 잘못 구현 한 것으로 보입니다. pi/2 = 1 + 1/3 + (1*2)/(3*5) + (1*2*3)/(3*5*7) + ...을 수행하는 대신 코드가 pi/2 = 1 + 1/3 + (1*2)/(3*4) + (1*2*3)/(3*4*5) + ... 인 것처럼 보입니다.

분모가 작아지기 때문에 합계를 더 많이 늘리면 오버 슛이 발생하고 결과적으로 부정적인 오류가 발생합니다.

문제는이 라인에있다 :

approx2 = approx2 * count/(count + 2) 

당신이 볼 수 있듯이, count도 때, count + 2도있을 것입니다. 쉽게 수정으로 변경하는 것입니다 : 여기

approx2 = approx2 * count/(2 * count + 1) 

가 작동하는 예 알고리즘이지만, 용어보다는 절대 오차 (멀리 모든 것을주고 싶지 않을 것이다) 사이의 상대 오차를 사용) :

from __future__ import division 

def half_pi(max_err=10**-6, max_iter=10000): 
    partial_sum = cur_term = 1 
    n = 1 
    while abs(t) > max_err and n < max_iter: 
     cur_term = cur_term * (n/(2 * n + 1)) 
     partial_sum += cur_term 
     n += 1 
    return partial_sum, n 
+0

정의 된 approx2 및 몇 가지 사소한 버그가 변경되어 완벽하게 작동했습니다. 음수는 시리즈가 0으로 수렴 할 때 결코 문제가되지 않습니다. 그것은 무한히 가까워 질 것입니다. 도와 주셔서 감사합니다. –

2

이 작동 :

import math 

def piEuler(x): 

    halfpi = math.pi/2.0 
    count  = 0 
    approx = 1.0 
    divisor = 1 
    numerator = 1 
    while True: 
     count  += 1 
     numerator *= count 
     divisor *= 2*count + 1 
     approx += float(numerator)/float(divisor) 
     error  = halfpi - approx 

     if error < x: 
      return (math.pi - error), count 

기본적인 차이점은 :

  1. 테스트/침입 루프의 종료 조건을 전환함으로써, I는 두 번째 항의 수동 계산을 제거 할 시리즈
  2. int 및 float 데이터 유형을 신중하게 사용하십시오 (이 문제 일 수 있습니다)
  3. 더 나은 디버깅을위한 변수 이름 지정
0

당신은 다시 시도해야 루틴 순서에서 가장 작은 용어, approx2 코드에서는 오류보다 크게 갖도록.

또한 마지막 오류 계산에 'math.pi'가 있습니다. 수학이어야하나요 .pi/2?

오류의 성질도 진동하는 것처럼 보입니다!

+0

반대로 부분 합계가 단조 증가하는 경우 오류는 단조 감소합니다. –

관련 문제