Ramanujan's Series

Hello,

So I'm trying to write a program that will estimate the value of an integral using Ramanujan's Series equation, but I seem to be getting stuck on something and I'm not sure what it is. I've created the the factorial function to look for the factorial of a number and the term function which is the last summation of the equation.
(His equation can be found here https://en.wikipedia.org/wiki/Logarithmic_integral_function
it is the last equation under Series Representation. And FYI, instead of finding the sum to infinity, it will be 5 instead. And the value of x will be 1000. L(i) should be about 319, but I keep getting nan. **I am not prompting for inputs because I am inputing a text file using the command line**


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 #include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
using namespace std;

double factorial(long n){
    double factor = 0;
    for(long i = n; i > 1; i--){
        factor *= i;
        
    }
    return factor;
}

double term(long num){
    double sum = 0;
    for(double k = 0; k<floor((num-1)/2); k++){
        sum += 1/((2*k)+1);
    }
    return sum;
}


int main(){
    const double gamma = 0.577215664901532;
    long number, x, iter;
    cin >> number;
    double L;
    for(double i = 1; i < number; i++){
        cin >> x >> iter;
        while(i < iter){
            L = gamma + log(log(x)) + sqrt(x)*(((pow(-1,i-1)*(pow(log(i),i)))/((factorial(i)*pow(2,i-1))))*term(i));
        }
    }
}
Last edited on
Hi,

In function factorial the variable factor is not initialised. The compiler told me that - you should set the warning levels high enough so you get those messages too. It's a golden rule to always initialise your variables to something - even when you are using it on the next line. Also, consider using a debugger, it would have shown that problem almost straight away.

Also, you should avoid using doubles in for loop conditions, they are not represented exactly.

Hope this helps a bit :+)
Thanks for the tips! Is my logic wrong somewhere? The output is inf and I need it to be 319!
Edit:

I misread line 32.

With C++ the declaration of variable can often be delayed until one has a sensible value to assign to it.

TheIdeasMan wrote:
Also, consider using a debugger, it would have shown that problem almost straight away.


You haven't done that have you? It's a really good idea to learn that, it will save you days of staring at code. Hopefully there is a GUI one in your IDE :+) They are easy to use.

It's also a good idea to prompt for input. You std::cin the x variable twice.

The STL has a std::tgamma function if you are allowed to use it.
Last edited on
I forgot to mention that I am inputting a file that has the format:
1
2
3
4
5
6
7
8
7
1000 5
1000 15
1000 30
1000000 5
1000000 15
1000000 30
100000000 30


So I cin>> x >> iter inside the loop for it to be able to read those numbers as pairs. Also the number variable is the number of cases that the loop is running so in case that number would be 7.

And I'm using xcode on my Mac and I'm not quite sure how to use the debugger on it yet!!

Thanks for the response!
Last edited on
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<iostream>
#include<cmath>

int neg(int); // calculates -1^n
int factorial(int);
double sigma(double);

int main()
{
    const double gamma = 0.5772156649;
    double x = 1000;
    
    std::cout << "Answer: " << gamma + log(log(x)) + sqrt(x) *  sigma(x) << std::endl;
    
    return 0;
}

int neg(int aNumber)
{
    if ( aNumber % 2 == 0)
        return 1;
    else
        return -1;
}

int factorial(int aNumber)
{
    int n = aNumber;
    int f = 1;
    
    while ( n > 0)
    {
        f *= n;
        n--;
    }
    
    return f;
}

double sigma(double aX)
{
    const int limit = 10; // this limits the number of iterations
    
    double part1 = 0;
    double part2 = 0;
    double product = 0;
    
    for( int n = 1; n <= limit; n++ )
    {
        part1 = neg(n - 1) * pow(log(aX), n) / ( (double)factorial(n) * pow(2.0, n-1) );
        
        part2 = 0;
        for ( int k = 0; k <= (n-1)/2; k++)
            part2 += 1 /( 2 * (double)k +1 );
        
        product += part1 * part2;
    }
    
    return product;
}


li(1000) = 175.683


http://keisan.casio.com/exec/system/1180573428 li(1000) = 177.609...
Last edited on
closed account (48T7M4Gy)
The li(1000) = 319 approx is for 5 iterations as the OP stated.

FWIW I found it useful to break the calculations up into easily testable parts and functions. I haven't checked type conflicts/truncations fully but I know this program is very sensitive to the number of iterations. The floor function isn't needed - small free bonus. :)
Last edited on
Thanks! I'll try to play around with it and let you guys know how it goes!.

But on the side question, why do you need a neg and sigma function? it is possible to keep it to just factorial and term function since it's on the requirement to keep it to just those two?

Again, Thank you!
Last edited on
closed account (48T7M4Gy)
From my point of view there were no restrictions on how many and what type of functions there were other than having a main() function of course.

The ones I have chosen are for convenience. So you can have 0 or any number of other functions depending on what restrictions you are under and what is convenient, especially for developing, testing and refining the code.

The main reason you're having trouble is your factor in factorial is always zero and there is only one summation (Greek sigma in the Wikipedia equation) not two in your L calculation.
Last edited on
Topic archived. No new replies allowed.