Approximating Pi in java using Gauss-Legendre algorithm [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Just started picking up java and tried to write a simple piece of code to display an approximation of Pi based on the Gauss-Legendre algorithm; the result I get in the command line from the code below is -33.343229... which seems very odd to me. I am aware that my code is not complete as I do not have a restriction on the number of digits after the decimal point, which I was going to try and get from using BigDecimal. I don't quite understand what I am supposed to do with it though after reading the documentation!
Does anyone have any idea if there are any current mistakes I can fix and also how to implement a restriction on the number of digits after the decimal point? Thank you!
class calculatePi {
public static void main(String[] args) {
calculatePi x = new calculatePi();
double y = x.approxPi(3); //3 iterations
System.out.print(y);
}
double approxPi(int i) {
double a = 1; //The initial conditions for the iteration
double b = 1 / Math.sqrt(2);
double t = 1/4;
double p = 1;
double a1 = 0; //The internal n+1 terms for the iteration
double b1 = 0;
double t1 = 0;
double p1 = 0;
while (i > 0) {
a1 = (a + b) / 2;
b1 = Math.sqrt(a*b);
t1 = t - p*(a - a1)*(a - a1);
p1 = 2*p;
a = a1;
b = b1;
t = t1;
p = p1;
i = i - 1;
}
double applepie = ((a + b)*(a + b))/(4*t);
return applepie;
}
}

double t = 1/4; does an integer division for 1/4, which results in 0. Try 1/4.0.

Related

Optimisation in Java Using Apache Commons Math

I'm trying to minimise a value in Java usingcommons-math. I've had a look at their documentation but I don't really get how to implement it.
Basically, in my code below, I have a Double which has the expected goals in a soccer match and I'd like to optimise the probability value of under 3 goals occurring in a game to 0.5.
import org.apache.commons.math3.distribution.PoissonDistribution;
public class Solver {
public static void main(String[] args) {
final Double expectedGoals = 2.9d;
final PoissonDistribution poissonGoals = new PoissonDistribution(expectedGoals);
Double probabilityUnderThreeGoals = 0d;
for (int score = 0; score < 15; score++) {
final Double probability =
poissonGoals.probability(score);
if (score < 3) {
probabilityUnderThreeGoals = probabilityUnderThreeGoals + probability;
}
}
System.out.println(probabilityUnderThreeGoals); //prints 0.44596319855718064, I want to optimise this to 0.5
}
}
The cumulative probability (<= x) of a Poisson random variable can be calculated by:
In your case, x is 2 and you want to find lambda (the mean) such that this is 0.5. You can type this into WolframAlpha and have it solve it for you. So rather than an optimisation problem, this is just a root-finding problem (though one could argue that optimisation problems are just finding roots.)
You can also do this with Apache Commons Maths, with one of the root finders.
int maximumGoals = 2;
double expectedProbability = 0.5;
UnivariateFunction f = x -> {
double sum = 0;
for (int i = 0; i <= maximumGoals; i++) {
sum += Math.pow(x, i) / CombinatoricsUtils.factorialDouble(i);
}
return sum * Math.exp(-x) - expectedProbability;
};
// the four parameters that "solve" takes are:
// the number of iterations, the function to solve, min and max of the root
// I've put some somewhat sensible values as an example. Feel free to change them
double answer = new BisectionSolver().solve(Integer.MAX_VALUE, f, 0, maximumGoals / expectedProbability);
System.out.println("Solved: " + answer);
System.out.println("Cumulative Probability: " + new PoissonDistribution(answer).cumulativeProbability(maximumGoals));
This prints:
Solved: 2.674060344696045
Cumulative Probability: 0.4999999923623868

Why is String-String concatenation quicker than String-long concatenation? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In Java, the following code:
long x = 123;
String s = "abc" + x;
takes a significantly more runtime than:
long x = 123;
String s = "abc" + String.valueOf(x);
I got to know this through leetcode. I was trying to solve the following problem: https://leetcode.com/problems/fraction-to-recurring-decimal/
Here is the exact code for my solution:
public String fractionToDecimal(int numerator, int denominator) {
long n = numerator, d = denominator;
boolean isNegative = (n * d < 0);
if(n < 0) n = -n;
if(d < 0) d = -d;
long q = n / d;
long r = n % d;
if(r == 0) return (isNegative ? "-" : "") + q;
StringBuilder sb = new StringBuilder();
if(isNegative) sb.append('-');
sb.append(q).append('.');
Map<Long, Integer> found = new HashMap<>();
int index = sb.length();
while(r > 0 && !found.containsKey(r)){
found.put(r, index++);
n = r * 10;
q = n / d;
r = n % d;
sb.append(q);
}
if(r > 0) {
sb.insert(found.get(r), "(");
sb.append(')');
}
return sb.toString();
}
When I click on Submit it takes as long as 7 milliseconds to complete.
But if I literally just change line no. 8 from + q to + String.valueOf(q) the runtime plummets down to just 1 millisecond. Please feel free to copy paste the code on leetcode to try it out there and see this change in runtime for yourself, if necessary.
This is highly confusing to me. Why is this happening? As per my understanding, in both the cases, compiler first converts the long to a String, and then concatenates those two Strings together, right? So, under the hood, isn't concatenating a String and a long exactly the same as concatenating two Strings together? Then why does one take more time to run than the other? Any insight would be highly appreciated. TIA.
Note: this answer was written before the question was changed. It used to include the expressions shown below.
"abc" + 123 is a constant expression - the concatenation is done at compile-time so "abc123" ends up in the constant pool.
"abc" + String.valueOf(123) is not a constant expression. The concatenation happens at execution time, which is obviously rather more expensive than just using the compile-time concatenation result.
So I'd expect the result to be the opposite of what you've actually reported in the question.

sum of the digits of the number 2^1000 in java [duplicate]

This question already has answers here:
Sum of the digits of the number 2^1000 [closed]
(11 answers)
Closed 3 years ago.
import java.math.*;
public class PowerDigitSum {
public static void main(String[] args) {
double[] digits ;
digits = new double[302];
double i = Math.pow(2, 1000);
double c = 301;
double c1 = 0;
double d = 0;
while(c>=0) {
c1 = Math.pow(10, c);
d = Math.floor(i/c1);
i = i - d*c1;
digits[(int)c] = (int)d;
c = c-1;
}
double sum = 0;
c = 0;
while (c<302) {
sum = sum+digits[(int)c];
c= c+1;
}
System.out.println(sum);
}
}
The output is 1281 but that's not correct according to projecteuler. What am I doing wrong?
You can't do correct math with double values that large due to their limited nature.
You could probably fix your code with BigDecimal, but it is much easier using BigInteger. Hint: it has a pow method, and you can work out the digit sum starting from toString.

Find Cube Root of Number (without using cbrt()) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
My code works perfectly for some floating value such as 125.5:
public class NewClass {
public static void main(String[] args){
Scanner Input = new Scanner(System.in);
NewClass ob = new NewClass();
double n = Input.nextDouble();
double cbrt = ob.Cbrt(n);
System.out.println(cbrt);
}
public double GetSquareRoot(double n, double low, double high) {
double cbrt = (low + high) / 2;
if (cbrt*cbrt*cbrt > n)
return GetSquareRoot(n, low, cbrt);
if (cbrt*cbrt*cbrt < n)
return GetSquareRoot(n, cbrt, high);
return cbrt;
}
public double Cbrt(double n) {
NewClass ob = new NewClass();
return ob.GetSquareRoot(n, 0, n);
}
}
It does not give correct answer when input is:
0.008
or 0.125
or 50
or 100
Then I am getting java.lang.StackOverflowError.
When input is 125.5 or 125 or 8 it gives the correct solution.
Can someone help me?
The error is that this line:
return ob.GetSquareRoot(n, 0, n);
(which is, of course, misnamed) tries to find a solution between 0 and n. However, if 0 < n < 1, then n1/3 > n, so you will never find a solution in the interval (0, n). You'll need to make a special case of this; for example, if 0 < n < 1, you can search the interval (n, 1) instead.
Also, using 0 and n as the bounds won't work for negative numbers, so if you want to make your method more complete and handle those cases, you'll need special cases for those too (probably different for -1 < n < 0 and n < -1).
MORE: After seeing your comment about StackOverflowError, it's occurred to me that you have an additional problem: that you're expecting an exact result. When you put in 0.008, the cube root is 0.2. However, neither 0.008 nor 0.2 can be represented exactly as a floating-point number. The consequence is that if you let cbrt = whatever value is closest to 0.2 that can be represented, then cbrt*cbrt*cbrt won't be exactly 0.008. It can't be exactly 0.008 anyway, since 0.008 can't be represented as a double; however, if n is whatever value is closest to 0.008, then it's likely that cbrt*cbrt*cbrt will not be exactly equal to n, due to roundoff errors. For a calculation like this, it's important that you not compare doubles for equality; instead, compare them using an "epsilon" value, or a margin of error. Thus, after
double cbrt = (low + high) / 2;
you should have something like
if (Math.abs(cbrt*cbrt*cbrt - n) < EPSILON)
return cbrt;
where EPSILON is some small value such as 1E-10. (I've sometimes seen code where EPSILON is computed to be a relative value, i.e. abs(n * RELATIVE_EPSILON), instead of an absolute value.)
Another way to avoid StackOverflowError is to quit when low and high become really close, because by that point you're not going to gain much more accuracy, and you need to make sure you exit the algorithm even if the value of cbrt*cbrt*cbrt is a little bit off. Something like
if (high - low < EPSILON)
return cbrt;
See also What's wrong with using == to compare floats in Java?.
//How about My Solution - Without Recursive
import java.util.Scanner;
public class CubeRoot {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.next();
Boolean negative = false;
if (str.startsWith("-")) {
str = str.substring(1);
negative = true;
}
if (str.indexOf(".") > 0) {
// find the poisition of '.'
int pPos = str.length() - 1 - str.indexOf(".");
String plainStr = (str.substring(0, str.indexOf('.')).concat(str.substring(str.indexOf('.') + 1)));
StringBuffer cStr = new StringBuffer(cubeRoot(plainStr));
if (cStr.toString().equalsIgnoreCase(plainStr))
System.out.println("couldn't compute Cube Root for this :(");
else {
if (cStr.length() > pPos / 3) // devide 3 times to put the '.'
cStr.insert(cStr.length() - pPos / 3, ".");
else {
int cStrLength = cStr.length();
for (int i = 0; i <= pPos / 3 - cStrLength; i++)
cStr = new StringBuffer("0").append(cStr.toString());
cStr.insert(cStr.length() - pPos / 3, ".");
}
String append = (negative) ? new String("-") : new String("");
System.out.println(append + cStr.toString());
}
} else {
System.out.println("Not a floating num");
}
}
private static String cubeRoot(String d) {
Long l = new Long(d);
for (int i = 0; i < l; i++) {
if (i * i * i == l) {
return String.valueOf(i);
}
}
return d;
}
}

Is there a way to show the step by step computation of a calculation in Java?

I am currently building an Android app that has a calculator that not only shows the result, but also shows how it reached that result?
Is there any library or any way that I could show a step by step computation for the result of the code below?
int a = 5;
int b = 6
int c = 7;
int d = 8;
int result = a + (b * c) / d;
edit: By the way, it's a calculator for physics so I have lots of formulas. I'm using exp4j to parse a string formula as an expression. Here's a sample
//For formula velocity = (finalVelocity - initialVelocity) / time
String formula1 = "(finalVelocity - initialVelocity) / time";
Double result1 = new ExpressionBuilder(formula)
.variables("finalVelocity", "initialVelocity", "time")
.build()
.setVariable("finalVelocity", 4);
.setVariable("initialVelocity", 2);
.setVariable("time", 2)
.evaluate();
//Sample Output
//velocity = (4 - 2) / 2
//velocity = 2 /2
//velocity = 1
//For formula finalVelocity = (velocity * time) + initialVelocity
String formula2 = "(velocity * time) + initialVelocity";
Double result12 = new ExpressionBuilder(formula)
.variables("velocity", "time" "initialVelocity")
.build()
.setVariable("velocity", 4);
.setVariable("time", 2)
.setVariable("initialVelocity", 0)
.evaluate();
//Sample Output
//finalVelocity = (4 * 2) + 0
//finalVelocity = 8 + 0
//finalVelocity = 8
With many formulas, I'm trying to eliminate printing each step per formula. I'm trying to find a way to have a function that would print the steps for any formula.
Considering you will be using BODMAS to solve that problem, you could consider simply printing each step:
int a = 5;
int b = 6;
int c = 7;
int d = 8;
int ans = (b * c);
System.out.println(ans)
ans /= d;
System.out.println(ans)
ans += a;
System.out.println(ans)
To do this, you can build a function which searches for brackets first and solves the equations in the according to BODMAS(Brackets first, then Division, then Multiplication, then Addition, and finally Subtraction).
Considering you take the equation as a string, you first search for (), then solve / and print answers followed by *, + and -.

Categories