PDA

View Full Version : cool math homework assignment

BobMcGee123
01-21-2007, 04:53 PM
Well you can move this to whatever board you want. Anyway I'm taking a course called 'engineering mathematics.' It's kind of the equivalent of a linear algebra course. My professor is an eccentric old lady that is way too smart to teach math to humans.

Our assignment over the weekend was to write in excel a command to evaluate the series for 'e' and 'pi' and to see how many terms in the series it took to get a certain number of decimal places accuracy. She suggested trying a couple of hundred terms, so of course I wrote a program that evaluates PI using 50 million terms. Kind of neat. Here are the results, the series for 'e' converged pretty quickly, not true for PI.

E after 20 terms in the series: 2.718281828459045500000000000000

PI after 1000 terms in series: 3.142593654340044100000000000000

PI after 50000000 terms in series: 3.141592673590250900000000000000

Here's the program for it

#include <iostream>
#include <fstream>
#include <math.h>

using namespace std;

double factorial(double input)
{
if(input > 0)
return input * factorial(input-1);
else return 1;
}

double e_term(double which_term)
{
return 1.0 / (factorial(which_term));
}

double pi_term(double which_term)
{
int i_term;
_asm
{
fld which_term;
fistp i_term;
}

double sgn = pow(-1.0,i_term+1);
double denom = 1.0 / ((2.0 * which_term)-1);
return 4 * sgn * denom;
}

int main(void)
{
std::ofstream fout;
fout.open("results.txt");
fout.precision(50);
cout.precision(50);

double summation = 0.0;
for(double which_term = 0; which_term < 20; ++which_term)
{
summation += e_term(which_term);
fout << summation << "\n";
}

fout << "\n\n\n\n\n\n\n";

summation = 0;
for(which_term = 1; which_term < 1000; ++which_term)
{
summation += pi_term(which_term);
}
cout << "PI after 1000 terms in series: " << summation << "\n";
fout << "\nPI after 1000 terms in series: " << summation << "\n\n";

summation = 0;
for(which_term = 1; which_term < 50000000; ++which_term)
{
summation += pi_term(which_term);
}

cout << "PI after 50000000 terms in series: " << summation << "\n";
fout << "\nPI after 50000000 terms in series: " << summation << "\n\n";
return 0;
}

Sang-drax
01-21-2007, 07:17 PM
Your series for e will converge extremly fast because the terms get really small very fast (factorial in the denominator).

Since the series you're using for pi is an alternating one, it is very easy to give an estimation how close to pi you are. After the first term your estimation is too big and after the second one it is too small and so on. So an upper bound of the error is the last term you added. That way you can know for sure how many digits are correct.

Happy_Reaper
01-22-2007, 08:02 AM
Further, I believe there are faster converging series to Pi, but none as straightforward as your method, though.

Sang-drax
01-22-2007, 11:50 AM
Here's a cool way of calculating pi:

*Select two random numbers in the interval [-1...1]
*Count the number of times you end up within the unit disc. sqrt(x^2 + y^2) <= 1
*The ratio between this number and the total amound tends to the ratio of the unit disc to the area of the square (4).

double calculatePi(int nTimes)
{
double nWithin = 0;
for (int n=1; n<= nTimes; ++n) {
double x = random(-1,1);
double y = random(-1,1);
if (x*x + y*y <= 1)
nWithin++;
}
return 4 * (nWithin/nTimes);
}

This method converges very slowly.

Sang-drax
01-22-2007, 12:09 PM
And here is a good method of calculating pi:

#include <iostream>
#include <iomanip>
using namespace std;

double calculatePi(int nTimes)
{
double halfpi = 1; //First term is 1
double numerator = 1;
double denominator = 1;

for (double k=1; k<= nTimes; ++k)
{
numerator *= k;
denominator *= 2*k + 1;
halfpi += numerator/denominator;
}
return 2 * halfpi;
}

int main()
{
cout << "Pi is approximately " << setprecision(15) << calculatePi(10) << " with 20 terms." << endl;
cout << "Pi is approximately " << calculatePi(50) << " with 50 terms." << endl;
cin.get();
}

The results:

Pi is approximately 3.14110602160138 with 20 terms.
Pi is approximately 3.14159265358979 with 50 terms.

The formula is attached as an image.

BobMcGee123
01-22-2007, 02:39 PM
Yeah, I saw the method that you suggested, I think on wikipedia. Glad you posted the source. She wanted us to use this particular method to demonstrate the idea in Sang drax's first reply, that the estimate goes above and then below, oscillating (it tied into this week's lecture).

Thanks for the replies.

Sang-drax
01-22-2007, 05:31 PM
Yup, I found that formula on Wikipedia as well.

BobMcGee123
01-23-2007, 05:02 PM
whoa wait what does the double !! mean

Sang-drax
01-23-2007, 05:18 PM
One would think that it means the factorial of the factorial, but it doesn't. It means that only every other factor should be used in the product.
5!! = 5 * 3 * 1
6!! = 6 * 4 * 2

In this case, both the factorial and the !! is calculated very quickly using the previous term cleverly.

BobMcGee123
01-23-2007, 06:13 PM
Oh, that makes sense. Yeah, I initially thought 'factorial of the factorial' but then that didn't quite make sense.

Gracias!

manutd
01-23-2007, 06:26 PM
I assume the factorial of the factorial would be like: (5!)!

BobMcGee123
01-23-2007, 07:20 PM
We have already established that it is not.

Happy_Reaper
01-23-2007, 08:04 PM
I'd actually never seen that notation before, but it's a fun tidbit of info.

manutd
01-23-2007, 08:05 PM
No, I know 5!! is not factorial of a factorial, but do the parentheses make a difference?

Happy_Reaper
01-23-2007, 08:08 PM
I believe they would. I still think parentheses have a higher precedence than the !! operator.

Mario F.
01-23-2007, 08:21 PM
I believe so.

Not that I'm a maths expert, but the correct notation for factorial I seem to remember, is not !, but n!. The distinction is only made apparent exactly when trying to define the factorial of a factorial. That would then become (n!)!. I seem to remember there was another instance when n! as being the correct notation made a difference. Just can't recall what...