Computing Pi Using Leibniz Series what is delta(difference in running computation)? - java

I have to compute pi to six decimal precision using the leibniz series and I managed to do it except the assigment has some restrictions.
pi / 4 = 1 -1/3 + 1/5 - 1/7 ....
"
cannot utilize the math library π in your computation - direct or indirect. Use ONLY the delta (difference) of your running computation to determine when to stop your loop
"
I do not understand what this means by difference of your running computation. Another way I was told was "When your computed value ceases to change then your loop can stop"
package com.company;
public class Main {
public static void main(String[] args) {
double series = 0;
double denominator = 1;
double numerator = 1;
double pi;
double testingPi;
double formattedTestingPi = 0;
double formattedMathPi = Math.round(Math.PI * 1000000.0) / 1000000.0;
int max = 1200000;
int iterations = 0;
for(int i = 1; i < max;i++)
{
if((i % 2) != 0)
{
series = series + (numerator/denominator);
}
else if((i % 2) == 0)
{
series = series + ((numerator/denominator) * -1);
}
denominator = denominator + 2;
testingPi = series * 4;
formattedTestingPi = (Math.round(testingPi * 1000000.0))/1000000.0;
if( formattedTestingPi == formattedMathPi)
{
iterations = i;
i = max;
System.out.println("We stop");
}
}
pi = series * 4;
System.out.println("Number of Iterations :" + iterations);
System.out.println("Unformatted Series :" + series);
System.out.println("Unformatted Math Library PI:" + Math.PI);
System.out.println("Unformatted Computed PI:" + pi);
System.out.println("Formatted Computed PI:" + formattedTestingPi);
System.out.println("Formatted Math Library PI:" + formattedMathPi);
}
}
I do not want the solution to the assignment, I just want to know
what does delta of computation mean and how is it different what I'm doing right now?
Output
Number of Iterations :1181461
Unformatted Series :0.7853983749998679
Unformatted Math Library PI:3.141592653589793
Unformatted Computed PI:3.1415934999994715
Formatted Computed PI:3.141593
Formatted Math Library PI:3.141593

Related

Trying to calculate a factorial e^x, x being what the user enters, having trouble with the formula

I am in a Java class and it's still early in the class. The assignment is to:
e^x Approximations
The value ex can be approximated by the following sum:
1 + x + x^2/2! + x^3/3! + …+ x^n/n!
The expression n! is called the factorial of n and is defined as: n! = 1*2*3* …*n.
Write a program that takes a value of x as input and outputs four approximations of ex done using four different values of n: 5, 10, 50, and 100. Output the value of x the user entered and the set of all four approximations into the screen.
Sample formula use: calculating e^7 using approximation with n = 5
1 + 7 + 7^2/2! + 7^3/3! + 7^4/4! + 7^5/5!
I've got all the rest to work, including getting n to be 5, 10, 50 and 100. I thought I had the factorial formula figured out and I used the number 4 like the sample we were show and my numbers done match. Could really use another set of eyes.
Here's my code with forumla (x is the value the user enters and n is the 5, 10, 50 and 100):
/**
* myFact takes in x and calculates the factorial
* #param x
* #param n
* #return the factorial as a long
*/
public static long myFact(int x, int n) {
//declare variables
long sum = x;
for (int i=2; i <= n; i++) {
sum += ((Math.pow(x, i))/i);
}
return (sum + 1);
}
}
Here's the main class where I am calling the function. The error I suppose could be there too:
public static void main(String[] args) {
//declare variable for user input and call method to initialize it
int x = getNumber();
long fact;
int n;
//Output first line
System.out.println("N\t approximate e^" + x);
for (n = 5; n <= 100; n *= 2) {
if (n == 10) {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
n += 15;
} else {
fact = myFact(x, n);
System.out.println(n + "\t " + fact);
}
}
}
Thanks for taking a look at this, it's taken me hours to get this as the teacher gave us very little help.
You did a mistake in
sum += ((Math.pow(x, i))/i);
here you need to calculate the i!. Add below method in your code
public static int fact(int i){
int fact = 1;
for (int n = i; n > 0; n--) {
fact = fact * n;
}
return fact;
}
Also change sum += ((Math.pow(x, i))/i) to
sum += ((Math.pow(x, i))/fact(i));

Calculating PI with an special Algorithm

I have to calculate PI with this special algorithm for school:
pi = 4*(1/1 - 1/3 + 1/5 - 1/7 ... 1/n)
I've been trying a lot of things but it seems like I only get a never-ending loop because the condition for it is false, or my code is too complicated. The result I have to get is the calculated PI (only 6 decimals)=(the Algorithm for it).
Here's the code I've already tried:
public void PI()
{
double n=1.0;//while 3 counter
double z=1.0;//while 3 denominator
int i=0;//numerator for while 3
double pi=1.0;//Result
double x=0.0;//Calculated fractions
double y=1.0;//denominator for double x
double q=1; //Help for while 2
int f=0;//Help for while 3
while(new Double(Math.round(1000000.0*pi)).compareTo(new Double(Math.round(1000000.0*Math.PI)))==-1||new Double(Math.round(1000000.0*pi)).compareTo(new Double(Math.round(1000000.0*Math.PI)))==1) //while 1
{
while(new Double(Math.round(1000000.0*(4*x))).compareTo(new Double(Math.round(1000000.0*Math.PI)))==-1||new Double(Math.round(1000000.0*pi)).compareTo(new Double(Math.round(1000000.0*Math.PI)))==1)//while 2
{
if (q==1)
{
x+=0.1/y;
q++;
}
y+=2;
if(q==2)
{
x-=0.1/y;
q--;
}
y+=2;
i++;
}
pi=x*4.0;
}
while(f<=i)//while 3
{
System.out.println(n+"/"+z);
z+=2;
f++;
}
}
Your code looks overcomplicated. Try this:
/**
* Returns PI estimation based on equation:
* {#code PI' = 4*(1/1 - 1/3 + 1/5 - 1/7 ... 1/m)}
*
* #param n number of fractions in sum.
*/
public static double piEstimate(int n) {
double sum = 0;
for (int i = 0; i < n; i++) {
double fraction = (double) 1/(i*2+1);
int sign = (i % 2 == 0) ? 1 : -1;
sum += sign * fraction;
}
return 4*sum;
}
public static void main(String[] args) {
System.out.println("PI = " + piEstimate(10000));
}
you should add a System.out.println to see how the pi variable evolves in your second loop.

java compute pi to 6 significant figurs

I'm having trouble with this program, we are supposed to compute pi to six significant figures, WITHOUT ROUNDING and WITHOUT using math library constant, the program should also show the number of iterations it took to reach 6 sig fig accuracy as well as the math constant in the output, so far I'm just trying to get my head around computing pi, I'm completely lost on how to get six 6 figs with or without rounding, not to mention how to iterate how many iterations it took to reach 6 sig figs pls help.
"Write an algorithm and program to compute π, using the formula described in the text PI/4 =1-(1/3)+(1/5)-(1/7)+(1/9)...." Output will include your computed value for π, the math library constant expected value for π and the number of iterations it took to reach six-significant digit accuracy. The number of iterations could exceed 250,000. Make your output clean and easy to read for comparing results.
This is the code I have so far to compute pi but even this I'm not sure is right.
public static void main(String[] args) throws Exception {
Double pi=1.0;
int s=1;
for (double j=3.0; j<100.0; j=j+2)
{
if (s % 2 == 0)
pi = pi + (1/j);
else
pi = pi - (1/j);
s = s + 1;
}
System.out.println(4*pi);
So there is presumably a way to make an a priori estimate of error using the alternating series theorem. But suppose you do not know the theorem or trust your math (if you do, just change 100.0 above to the right number. 800000.0 as estimated above would work, just barely). Here is something a little safer, perhaps, though it might be better to check the goodness of the estimate only every 1000 times through the loop, not each time?
Double pi=1.0; Boolean closeEnough=false;
int s=1;
for (double j=3.0; (!closeEnough); j=j+2)
{
if (s % 2 == 0)
pi = pi + (1/j);
else
pi = pi - (1/j);
if (Math.abs(4/(j+2))<0.000005)
closeEnough=true;
s = s + 1;
}
Ideally you should encapsulate your calculation in a class:
public class PI {
private double estimate = 1.0;
private int iteration = 0;
public double getEstimate() {
return 4 * estimate;
}
public void iterate() {
double ratio = 1.0 / (iteration * 2 + 3);
if (iteration % 2 == 0)
estimate -= ratio;
else
estimate += ratio;
iteration++;
}
}
Then the loop becomes pretty trivial:
PI pi = new PI();
while (Math.round(pi.getEstimate() * 1e5) != Math.round(Math.PI * 1e5))
pi.iterate();
For me this took 130,657 iterations
consider
String piStr = "3.14159";
Double pi=1.0;
int s=1;
double j=3.0;
String lcl = "";
String upToNCharacters = "";
while (true)
{
if (s % 2 == 0)
pi = pi + (1/j);
else
pi = pi - (1/j);
s = s + 1;
j=j+2;
lcl = "" + 4 * pi;
upToNCharacters = lcl.substring(0, Math.min(lcl.length(), 7));
if (upToNCharacters.equals(piStr)) {
break;
}
}
System.out.println(upToNCharacters);
System.out.println("after " + s);
output
3.14159
after 136121

Java - Odd error message when converting double to BigDecimal

In a program, a double is being converted to BigDecimal. This returns a very strange error message.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
This returns
Exception in thread "main" java.lang.NumberFormatException
What is causing this error message? Does BigDecimal.valueOf(double) not work correctly since this is referenced through another method?
Full program
/**************************************************************************
**
** Euler-Riemann Zeta Function
**
**************************************************************************
** XXXXXXXXXX
** 06/20/2015
**
** This program computes the value for Zeta(s) using the standard form
** of Zeta(s), the Riemann functional equation, and the Cauchy-Schlomilch
** transformation. A recursive method named riemannFuncForm has been created
** to handle computations of Zeta(s) for s < 2. Simpson's method is
** used to approximate the definite integral calculated by the
** Cauchy-Schlomilch transformation.
**************************************************************************/
import java.util.Scanner;
import java.math.*;
public class ZetaMain {
// Main method
public static void main(String[] args) {
ZetaMain();
}
// Asks the user to input a value for s.
public static void ZetaMain() {
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta " +
"Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater " +
"than 1.");
}
start = System.currentTimeMillis();
if (s == 1)
System.out.println("The zeta function is undefined for Re(s) " +
"= 1.");
else if (s < 2) {
BigDecimal val = BigDecimal.valueOf(riemannFuncForm(s));
System.out.println("Value for the Zeta Function = "
+ val.toEngineeringString());
}
else
System.out.println("Value for the Zeta Function = "
+ BigDecimal.valueOf(getStandardSum(s)).toString());
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form of the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
// Returns the value calculated by the Standard form of the Zeta function.
public static double getStandardSum(double s){
return standardZeta(s);
}
// Approximation of the Gamma function through the Lanczos Approximation.
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851,
-1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7};
int g = 7;
// Implements Euler's Reflection Formula.
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)
*gamma(1-s));
s -= 1;
double a = p[0];
double t = s + g + 0.5;
for(int i = 1; i < p.length; i++){
a += p[i] / (s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)
*Math.exp(-t)*a;
}
/* Riemann's Functional Equation - Directly calculates the value of
Zeta(s) for s < 2.
1. The first if statement handles the case when s < 0 and s is a
multiple of 2k. These are trivial zeroes where Zeta(s) is 0.
2. The second if statement handles the values of 0 < s < 2. Simpson's
method is used to numerically compute an approximation of the
definite integral.
3. The third if statement handles the values of -1 < s < 0. Recursion
is used alongside an approximation through Simpson's method.
4. The last if statement handles the case for s <= -1 and is not a
trivial zero. Recursion is used directly against the standard form
of Zeta(s).
*/
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*
(Math.sin((Math.PI*s)/2))*gamma(1-s);
if(s == 1.0 || (s <= -1 && s % 2 == 0) )
return 0;
else if (s >= 0 && s < 2)
return getSimpsonSum(s);
else if (s > -1 && s < 0)
return term*getSimpsonSum(1-s);
else
return term*standardZeta(1-s);
}
// Returns the function referenced inside the right hand side of the
// Cauchy-Schlomilch transformation for Zeta(s).
public static double function(double x, double s) {
double sech = 1 / Math.cosh(x); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(x, s)) * squared);
}
// Simpson's rule - Approximates the definite integral of f from a to b.
public static double SimpsonsRule(double a, double b, double s, int n) {
double simpson, dx, x, sum4x, sum2x;
dx = (b-a) / n;
sum4x = 0.0;
sum2x = 0.0;
// 4/3 terms
for (int i = 1; i < n; i += 2) {
x = a + i * dx;
sum4x += function(x,s);
}
// 2/3 terms
for (int i = 2; i < n-1; i += 2) {
x = a + i * dx;
sum2x += function(x,s);
}
// Compute the integral approximation.
simpson = function(a,s) + function(a,b);
simpson = (dx / 3)*(simpson + 4 * sum4x + 2 * sum2x);
return simpson;
}
// Handles the error for for f(x) = t^s * sech(t)^2. The integration is
// done from 0 to 100.
// Stop Simspson's Method when the relative error is less than 1 * 10^-6
public static double SimpsonError(double a, double b, double s, int n)
{
double futureVal;
double absError = 1.0;
double finalValueOfN;
double numberOfIterations = 0.0;
double currentVal = SimpsonsRule(a,b,s,n);
while (absError / currentVal > 0.000001) {
n = 2*n;
futureVal = SimpsonsRule(a,b,s,n);
absError = Math.abs(futureVal - currentVal) / 15;
currentVal = futureVal;
}
// Find the number of iterations. N starts at 8 and doubles
// every iteration.
finalValueOfN = n / 8;
while (finalValueOfN % 2 == 0) {
finalValueOfN = finalValueOfN / 2;
numberOfIterations++;
}
System.out.println("The number of iterations is "
+ numberOfIterations + ".");
return currentVal;
}
// Returns an approximate sum of Zeta(s) through Simpson's rule.
public static double getSimpsonSum(double s) {
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*
(gamma(1+s)));
System.out.println("Did Simpson's Method.");
return constant*SimpsonError(0, 100, s, 8);
}
}
Would I have to change all of my double calculations to BigDecimal calculations in order to fix this?
Nope. All you would need to do is to catch and handle the NumberFormatException appropriately. Or, test for NaN and Inf before attempting to convert the double.
In this case, you are only using BigDecimal for formatting in "engineering" syntax. So another alternative would be to do the formatting directly. (Though I haven't found a simple way to do that yet.)
This error occurs with you because BigDecimal.valueOf(value) does not accept "NaN" "Not a Number" as parameter and the following expression will return NaN
Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)
this Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2)) will evaluate -0.0
and this function gamma(1-s) will evaluate "Infinity"
So -0.0 * Infinity equal NaN in java
please see this to know When can Java produce a NaN.
When can Java produce a NaN?

Converting a float into a string fraction representation

In Java, I am trying to find a way to convert a float number into a fraction string. For example:
float num = 1.33333;
String numStr = Convert(num); // Should return "1 1/3"
float num2 = 1.333;
String numStr2 = Convert(num2); // Should also return "1 1/3"
float num3 = 0.5;
String numStr3 = Convert(num3); // Should return "1/2"
float num4 = 2.25;
String numStr4 = Convert(num4); // Should return "2 1/4"
Any ideas how to do this in Java?
The simplest approach might be to use trial and error.
public static String toFraction(double d, int factor) {
StringBuilder sb = new StringBuilder();
if (d < 0) {
sb.append('-');
d = -d;
}
long l = (long) d;
if (l != 0) sb.append(l);
d -= l;
double error = Math.abs(d);
int bestDenominator = 1;
for(int i=2;i<=factor;i++) {
double error2 = Math.abs(d - (double) Math.round(d * i) / i);
if (error2 < error) {
error = error2;
bestDenominator = i;
}
}
if (bestDenominator > 1)
sb.append(' ').append(Math.round(d * bestDenominator)).append('/') .append(bestDenominator);
return sb.toString();
}
public static void main(String... args) {
System.out.println(toFraction(1.3333, 1000));
System.out.println(toFraction(1.1428, 1000));
for(int i=1;i<100000000;i*=10) {
System.out.println("PI "+i+": "+toFraction(3.1415926535897932385, i));
}
}
prints
1 1/3
1 1/7
PI 1: 3
PI 10: 3 1/7
PI 100: 3 14/99
PI 1000: 3 16/113
PI 10000: 3 16/113
PI 100000: 3 14093/99532
PI 1000000: 3 140914/995207
PI 10000000: 3 244252/1725033
Look into chain fractions. This allows you to determine denominator and fraction within a given accuracy.
For Pi you can get 22/7 or 355/113 depending on when you choose to stop.
This might be of help:
http://www.merriampark.com/fractions.htm
Otherwise you'd need some way of telling Convert() how far out you want to take things. Maybe a maximum reduced demoninator or something like that. That way you'll get "1 1/3" for both of the first two examples you have above rather than "1 33333/100000" for the first and "1 333/1000" for the second.
Extract the fractional part of the number (for example, ((int) 0.5 + 1) - 0.5, then divide one by the result (1 / 0.5). You'll get the denominator of the fraction. Then cast the float to an int, and you'll get the integer part. Then concatenate both.
It's just a simple solution, and will work only if the numerator of the fraction is 1.
double n = 1.2f;
int denominator = 1 / (Math.abs(n - (int) n - 0.0001)); //- 0.0001 so the division doesn't get affected by the float point aproximated representation
int units = (int) n;
int numerator = units * denominator + 1;
System.out.println("" + numerator + "/" + denominator); //6/5
System.out.println("" + units + " 1/" + denominator); //1 1/5
Assume you have "0.1234567", then count how many numbers after the decimal point (which is 7). then multiply the number with 10 ^ 7, now you have "1234567".
divide 1234567 over 10 ^ 7. Then, simplify the fraction using the GCD of the two numbers.
0.1234567 * 10000000 = 1234567
=> 1234567 / 10000000
=> System.out.println(1234567 / gcd(1234567,10000000) + "/" + 10000000/gcd(1234567,10000000));
Modified the FOR loop to break the loop, when the best denominator is already identified.
if (error2 == 0) break;
public static String toFraction(double d, int factor) {
StringBuilder sb = new StringBuilder();
if (d < 0) {
sb.append('-');
d = -d;
}
long l = (long) d;
if (l != 0) sb.append(l);
d -= l;
double error = Math.abs(d);
int bestDenominator = 1;
for(int i=2;i<=factor;i++) {
double error2 = Math.abs(d - (double) Math.round(d * i) / i);
if (error2 < error) {
error = error2;
bestDenominator = i;
if (error2 == 0) break;
}
}
if (bestDenominator > 1)
sb.append(' ').append(Math.round(d * bestDenominator)).append('/') .append(bestDenominator);
return sb.toString();
}
public static void main(String... args) {
System.out.println(toFraction(1.3333, 1000));
System.out.println(toFraction(1.1428, 1000));
for(int i=1;i<100000000;i*=10) {
System.out.println("PI "+i+": "+toFraction(3.1415926535897932385, i));
}
}

Categories

Resources