Ayah Al-Harthy
Ayah Al-Harthy

Reputation: 123

How to fix "PI recursive function" code to work with all values of n?

I'm working on a code that calculates PI with n terms. However, my code only works correctly with some values of n.

This piece of code even numbers do not work and when I switch up the negative sign the odd numbers do not work.

double PI(int n, double y=2){

    double sum = 0;
    if (n==0){
        return 3;
    }else if (n % 2 != 0){
        sum =  (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;

    }else{
        sum=  -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2)  ;
    }
    return sum;
} 

  int main(int argc, const char * argv[]) {
    double n = PI (2,2);
    cout << n << endl;
   }

For n = 2 I expected a result of 3.1333 but I got a value of 2.86667 This is the formula for calculating PI , y is the denominator and n is the number of terms enter image description here

Upvotes: 0

Views: 127

Answers (2)

davidlowryduda
davidlowryduda

Reputation: 2559

Firstly, I will assume that a complete runnable case of your code looks like

#include <iostream>
using namespace std;

double PI(int n, double y=2){

    double sum = 0;
    if (n==0){
        return 3;
    }else if (n % 2 != 0){
        sum =  (4/(y*(y+1)*(y+2)))+(PI (n - 1 ,y+2)) ;

    }else{
        sum=  -(4/(y*(y+1)*(y+2)))+PI (n - 1,y+2)  ;
    }
    return sum;
}

int main(int argc, const char * argv[]) {
  double n = PI (2,2);
  cout << n << endl;
}

I believe that you are attempting to compute pi through the formula

(pi - 3)/4 = \sum_{k = 1}^{\infty} (-1)^{k+1} / ((2k(2k+1)(2k+2)),

(where here and elsewhere I use LaTeX code to represent mathy things). This is a good formula that converges pretty quickly despite being so simple. If you were to use the first two terms of the sum, you would find that

(pi - 3)/4 \approx 1/(2*3*4) - 1/(4*5*6)  ==>  pi \approx 3.13333,

which you seem to indicate in your question.

To see what's wrong, you might trace through your first function call with PI(2, 2). This produces three terms.

  1. n=2: 2 % 2 == 0, so the first term is -4/(2*3*4) + PI(1, 4). This is the wrong sign.
  2. n=1: 1 % 2 == 1, so the second term is 4/(4*5*6), which is also the wrong sign.
  3. n=0: n == 0, so the third term is 3, which is the correct sign.

So you have computed

3 - 4/(2*3*4) + 4/(4*5*6)

and we can see that there are many sign errors.

The underlying reason is because you are determining the sign based on n, but if you examine the formula the sign depends on y. Or in particular, it depends on whether y/2 is odd or even (in your formulation, where you are apparently only going to provide even y values to your sum).

You should change y and n appropriately. Or you might recognize that there is no reason to decouple them, and use something like the following code. In this code, n represents the number of terms to use and we compute y accordingly.

#include <iostream>
using namespace std;

double updatedPI(int n)
{
  int y = 2*n;
  if (n == 0) { return 3; }
  else if (n % 2 == 1)
  {
    return 4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
  }
  else
  {
    return -4. / (y*(y + 1)*(y + 2)) + updatedPI(n-1);
  }
}

int main() {
  double n = updatedPI(3);
  cout << n << endl;
}

Upvotes: 3

Daniel Langr
Daniel Langr

Reputation: 23497

The only problem with your code is that y is calculated incorrectly. It has to be equal to 2 * n. Simply modifying your code that way gives correct results:

Live demo: https://wandbox.org/permlink/3pZNYZYbtHm7k1ND

That is, get rid of the y function parameter and set int y = 2 * n; in your function.

Upvotes: 0

Related Questions