Reputation: 47
I am using mclaurins series to calculate arccos(x^2-1) but when i compare it to a result of math.acos it differs. Here is my code:
public class Maclaurin {
public static int factorial(int fact) {
if(fact==0)
return 1;
return fact*factorial(fact-1);
}
public static void main(String[] args) {
int i, j;
double function = 0, x,result;
x=0;
for (int n = 0; n < 8; n++) {
function=((factorial(2*n))/(Math.pow(4, n)*Math.pow(factorial(n),2)*(2*n+1)))*Math.pow((Math.pow(x, 2)-1),2*n+1);
result=(Math.PI/2)-function;
System.out.println("x= "+x+" y= "+result);
System.out.println("Test "+Math.acos(Math.pow(x, 2)-1));
x+=0.13;
}
}
}
Programm output. test is a value calculated with Math.arccos and it differs from y calculated with mclaurins formula:
x= 0.0 y= 2.5707963267948966
Test 3.141592653589793
x= 0.13 y= 1.7291549939933966
Test 2.9574849820283498
x= 0.26 y= 1.6236496851024964
Test 2.771793621843802
x= 0.39 y= 1.5848621264898726
Test 2.5828078861333155
x= 0.52 y= 1.5725761587226181
Test 2.3885331918392687
x= 0.65 y= 1.5708496332463704
Test 2.1864594293995867
x= 0.78 y= 1.570796415168701
Test 1.9731661516473589
x= 0.91 y= 1.5707963267948972
Test 1.7435543826662978
EDIT:New code where calculations are in maclaurin function and i call it from main function. works good for all values except first 3: package maclaurin;
public class Maclaurin {
private static double x;
//public static int factorial(int fact) {
// if(fact==0)
// return 1;
// return fact*factorial(fact-1);
//}
public static double factorial(int fact) {
if(fact==0)
return 1;
return fact*factorial(fact-1);
}
public static void main(String[] args)
{
x = 0;
for (int i=0;i<8;i++)
{
maclaurin(x);
x=x+0.14;
}
}
public static void maclaurin(double value){
double function = 0, x, result;
x =value;
for (int n = 0; n < 20; n++) {
function += ((factorial(2 * n)) / (Math.pow(4, n) * Math.pow(factorial(n), 2) * (2 * n + 1)))
* Math.pow((Math.pow(x, 2) - 1), 2 * n + 1);
}
result = (Math.PI / 2) - function;
System.out.println("x= " + x + " y= " + result);
System.out.println("Test " + Math.acos(Math.pow(x, 2) - 1));
}
}
Upvotes: 0
Views: 278
Reputation: 2876
I think you don't understand, what maclaurin series (taylor's series) is actually do. It can calculate an approximate value. You will get the exact value only for n -> ∞. Since we can't calculate that, we need to define some n and stop our calculation there. You have to add every single part of the summ to get the actual value. So basically you should iterate over n and ADD the calculated value to function
and after the loop you can calculate result
:
public static void main(String[] args){
double x = 0;
for(int i = 0;i < 8;i++){
System.out.println("x: " + x + " maclaurin: " + maclaurin(x));
System.out.println("Test: " + Math.acos(Math.pow(x, 2) - 1));
x += 0.14;
}
}
public static double maclaurin(double x){
double function = 0;
for (int n = 0; n < 10; n++) {
function += ((factorial(2 * n)) / (Math.pow(4, n) * Math.pow(factorial(n), 2) * (2 * n + 1)))
* Math.pow((Math.pow(x, 2) - 1), 2 * n + 1);
}
return (Math.PI / 2) - function;
}
this way I got pretty close values:
x: 0.0 maclaurin: 2.962490972738185
Test: 3.141592653589793
x: 0.14 maclaurin: 2.8972172328920296
Test: 2.9432779368601296
x: 0.28 maclaurin: 2.7366715068800485
Test: 2.7429790581451043
x: 0.42000000000000004 maclaurin: 2.5381695201901326
Test: 2.5385256934250617
x: 0.56 maclaurin: 2.3273181153351756
Test: 2.327323409412957
x: 0.7000000000000001 maclaurin: 2.105981109221438
Test: 2.1059811170704963
x: 0.8400000000000001 maclaurin: 1.8696239609917407
Test: 1.8696239609918046
x: 0.9800000000000001 maclaurin: 1.6104066839613247
Test: 1.6104066839613247
it seems, that result is not as good for x close to 0. You can increase n
to get better results, but at some point you will get NaN
, since factorial
will overflow at some point.
don't forget to change factorial
like @Brick suggested:
public static double factorial(int fact) {
if(fact==0)
return 1;
return fact*factorial(fact-1);
}
if you wonder how to calculate factorial
in an iterative way, here is an example(it actually doesn't matter in this particular case, but hey, we are here to learn new things, right?):
public static double factorial(int fact) {
double result = 1;
while(fact > 1){
result *= fact--;
}
return result;
}
EDIT: changed fact
parameter to int
EDIT2: wrapped maclaurin
function and added more values
EDIT3: added iterative factorial
Upvotes: 2
Reputation: 4252
The factorial of 16, which appears in your loop, is greater than MAX_INT
.
I get:
>> factorial(16)
2.0923e+013
>> 2^31
2.1475e+009
in Octave. You need to do an analytic simplification to keep that in range or use double
instead of int
there.
Upvotes: 2