Calculating the Square Root using the Babylon Algorithm - java

For my assignment, I am supposed to use a 'Tolerance Flag'. Yet, I was able to complete the task with what I have so far. What does my teacher mean by tolerance flag?
Use a tolerance flag and make your variables a member of the double class.
const double TOLERANCE = 5e-8;
double x = 2.0;
_
My Work:
public class Sqrt_of_Two {
public static void main(String[] args) {
final double TOLERANCE = 5e-8;
double x = 2;
do{
x = (x + 2/x) / 2;
System.out.println(x);
}while( Math.ceil(x*x) > 2);
}
}
OUTPUT:
1.5
1.4166666666666665
1.4142156862745097
1.4142135623746899
1.414213562373095

I suppose it means something like:
while(Math.abs(x*x - 2) > TOLERANCE);
which outputs:
1.5
1.4166666666666665
1.4142156862745097
1.4142135623746899

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

Java power of number calculation problem with big numbers [duplicate]

This question already has an answer here:
Why in one case multiplying big numbers gives a wrong result?
(1 answer)
Closed 2 years ago.
I am new to Java and when I was trying to find power of number without Math.pow method I realized the answer was not right. And I want to learn why?
public class Main() {
int x = 1919;
int y = x*x*x*x;
public static void main(String[] args) {
System.out.println(y);
}
}
Output: 2043765249
But normally answer is: 13561255518721
If you go step by step, you'll see that at a moment the value becomes negative, that's because you reach Integer.MAX_VALUE which is 2^31 -1
int x = 1919;
int y = 1;
for (int i = 0; i < 4; i++) {
y *= x;
System.out.println(i + "> " + y);
}
0> 1919
1> 3682561
2> -1523100033
3> 2043765249
You may use a bigger type like double or BigInteger
double x = 1919;
double y = x * x * x * x;
System.out.println(y); // 1.3561255518721E13
BigInteger b = BigInteger.valueOf(1919).pow(4);
System.out.println(b); // 13561255518721
You're using an int for the answer, you're getting a numeric overflow.
Use double or long or BigInteger for y and you'll get the right answer.
public class Main {
public static void main(String[] args) {
System.out.println(Math.pow(1919, 4));
System.out.println((double) 1919*1919*1919*1919);
}
}
Outputs the same value.
Use long instead of int
public class Main{
public static void main(String[] args) {
long x = 1919;
long y = x*x*x*x;
System.out.println(y);
}
}
Read about variables in Java.

Approximate a derivative for a continuous function throughout certain step intervals

I am looking to write a method in Java which finds a derivative for a continuous function. These are some assumptions which have been made for the method -
The function is continuous from x = 0 to x = infinity.
The derivative exists at every interval.
A step size needs to be defined as a parameter.
The method will find the max/min for the continuous function over a given interval [a:b].
As an example, the function cos(x) can be shown to have maximum or minimums at 0, pi, 2pi, 3pi, ... npi.
I am looking to write a method that will find all of these maximums or minimums provided a function, lowerBound, upperBound, and step size are given.
To simplify my test code, I wrote a program for cos(x). The function I am using is very similar to cos(x) (at least graphically). Here is some Test code that I wrote -
public class Test {
public static void main(String[] args){
Function cos = new Function ()
{
public double f(double x) {
return Math.cos(x);
}
};
findDerivative(cos, 1, 100, 0.01);
}
// Needed as a reference for the interpolation function.
public static interface Function {
public double f(double x);
}
private static int sign(double x) {
if (x < 0.0)
return -1;
else if (x > 0.0)
return 1;
else
return 0;
}
// Finds the roots of the specified function passed in with a lower bound,
// upper bound, and step size.
public static void findRoots(Function f, double lowerBound,
double upperBound, double step) {
double x = lowerBound, next_x = x;
double y = f.f(x), next_y = y;
int s = sign(y), next_s = s;
for (x = lowerBound; x <= upperBound ; x += step) {
s = sign(y = f.f(x));
if (s == 0) {
System.out.println(x);
} else if (s != next_s) {
double dx = x - next_x;
double dy = y - next_y;
double cx = x - dx * (y / dy);
System.out.println(cx);
}
next_x = x; next_y = y; next_s = s;
}
}
public static void findDerivative(Function f, double lowerBound, double
upperBound, double step) {
double x = lowerBound, next_x = x;
double dy = (f.f(x+step) - f.f(x)) / step;
for (x = lowerBound; x <= upperBound; x += step) {
double dx = x - next_x;
dy = (f.f(x+step) - f.f(x)) / step;
if (dy < 0.01 && dy > -0.01) {
System.out.println("The x value is " + x + ". The value of the "
+ "derivative is "+ dy);
}
next_x = x;
}
}
}
The method for finding roots is used for finding zeroes (this definitely works). I only included it inside my test program because I thought that I could somehow use similar logic inside the method which finds derivatives.
The method for
public static void findDerivative(Function f, double lowerBound, double
upperBound, double step) {
double x = lowerBound, next_x = x;
double dy = (f.f(x+step) - f.f(x)) / step;
for (x = lowerBound; x <= upperBound; x += step) {
double dx = x - next_x;
dy = (f.f(x+step) - f.f(x)) / step;
if (dy < 0.01 && dy > -0.01) {
System.out.println("The x value is " + x + ". The value of the "
+ "derivative is "+ dy);
}
next_x = x;
}
}
could definitely be improved. How could I write this differently? Here is sample output.
The x value is 3.129999999999977. The value of the derivative is -0.006592578364594814
The x value is 3.1399999999999766. The value of the derivative is 0.0034073256197308943
The x value is 6.26999999999991. The value of the derivative is 0.008185181673381337
The x value is 6.27999999999991. The value of the derivative is -0.0018146842631128202
The x value is 9.409999999999844. The value of the derivative is -0.009777764220086915
The x value is 9.419999999999844. The value of the derivative is 2.2203830347677922E-4
The x value is 12.559999999999777. The value of the derivative is 0.0013706082193754021
The x value is 12.569999999999776. The value of the derivative is -0.00862924258597797
The x value is 15.69999999999971. The value of the derivative is -0.002963251265619693
The x value is 15.70999999999971. The value of the derivative is 0.007036644660118885
The x value is 18.840000000000146. The value of the derivative is 0.004555886794943564
The x value is 18.850000000000147. The value of the derivative is -0.005444028885981389
The x value is 21.980000000000636. The value of the derivative is -0.006148510767989279
The x value is 21.990000000000638. The value of the derivative is 0.0038513993028788107
The x value is 25.120000000001127. The value of the derivative is 0.0077411191450771355
The x value is 25.13000000000113. The value of the derivative is -0.0022587599505241585
The main thing that I can see to improve performance in the case that f is expensive to compute, you could save the previous value of f(x) instead of computing it twice for each iteration. Also dx is never used and would always be equal to step anyway. next_x also never used. Some variable can be declare inside the loop. Moving the variable declarations inside improves readability but not performance.
public static void findDerivative(Function f, double lowerBound, double upperBound, double step) {
double fxstep = f.f(x);
for (double x = lowerBound; x <= upperBound; x += step) {
double fx = fxstep;
fxstep = f.f(x+step);
double dy = (fxstep - fx) / step;
if (dy < 0.01 && dy > -0.01) {
System.out.println("The x value is " + x + ". The value of the "
+ "derivative is " + dy);
}
}
}
The java code you based on (from rosettacode) is not OK, do not depend on it.
it's expecting y (a double value) will become exactly zero.
You need a tolerance value for such kind of tests.
it's calculating derivative, and using Newton's Method to calculate next x value,
but not using it to update x, there is not any optimization there.
Here there is an example of Newton's Method in Java
Yes you can optimize your code using Newton's method,
Since it can solve f(x) = 0 when f'(x) given,
also can solve f'(x) = 0 when f''(x) given, same thing.
To clarify my comment, I modified the code in the link.
I used step = 2, and got correct results.
Check how fast it's, compared to other.
That's why optimization is used,
otherwise reducing the step size and using brute force would do the job.
class Test {
static double f(double x) {
return Math.sin(x);
}
static double fprime(double x) {
return Math.cos(x);
}
public static void main(String argv[]) {
double tolerance = .000000001; // Our approximation of zero
int max_count = 200; // Maximum number of Newton's method iterations
/*
* x is our current guess. If no command line guess is given, we take 0
* as our starting point.
*/
double x = 0.6;
double low = -4;
double high = 4;
double step = 2;
int inner_count = 0;
for (double initial = low; initial <= high; initial += step) {
x = initial;
for (int count = 1; (Math.abs(f(x)) > tolerance)
&& (count < max_count); count++) {
inner_count++;
x = x - f(x) / fprime(x);
}
if (Math.abs(f(x)) <= tolerance) {
System.out.println("Step: " + inner_count + ", x = " + x);
} else {
System.out.println("Failed to find a zero");
}
}
}
}

Java while loop variable jumps for initial value

For the following simple while loop, once in every 5 runs, I get a list of wrong values for x, as if the values jump suddenly:
package test;
public class test_old {
public static void main(String [] args) {
double r0 = 0.1;
double r = 10;
double k = 0.05;
double x = 0;
double Tt = 0;
double T = 0;
while (Tt<=30) {
double xi = Math.random();
T = Math.log(1/xi)/(k*x + r0 + r);
Tt = Tt + T;
x = x + 1;
System.out.println(x);
}
}
}
Instead of getting 1.0, 2.0, 3.0, .. etc (usually around 4 values until Tt is bigger than 30), I sometimes get a list of x values that seems to go on for ever starting at for example 89462.0, or 19945.0. The list of x values is correctly incremented by 1, but it never stops.
I am a beginner using Eclipse.
Thank you everyone for your time!
Math.random () give values 0.0<=v<1.0
so if random gives you something like
v=0.99999999, log(1/v)=0.00000000001...
continue the calculation Tt=0+0.00000000001 will take like forever to be >30
just to test replace
double xi = Math.random();
by
double xi = 0.999999999999;
and run again
I don't know why this happen but it seems that the random gives you values like 0.9999...
so to avoid this you have to insure that random gives you smaller value
you can use this post
Math.random() explained

How can I modify my if statement so that the values print out after every full second?

So basically, I have a variable, time, and would like the program to print the other values for every full second.
For example if I plug in 100, it should print out 20 seconds only.
import java.util.Scanner;
public class CannonBlaster {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
final double DELTA_T = 0.01; //initiating all variables
final double G = 9.81;
double s = 0.0;
double time = 0.0;
double second = 0;
System.out.println("What's the initial velocity?: ");//asking for the initial velocity
double v =input.nextDouble();
while (s >= 0.0) //while loop is used. As long as the height isn't negative it will continue to go.
{
s += v * DELTA_T; //demonstrates the change of velocity and position for every .01 second.
v -= G * DELTA_T;
time += DELTA_T;
System.out.println("The time is: "+time+" "+(double) Math.floor(time)+" "+Math.round(time * 1000) / 1000);
second=Math.round(time * 1) / 1;
if ((double) Math.floor(time) ==time)
{
System.out.println("Approximated position: "+ s);
System.out.println("Formula's position: "+(100.0 * time - (time*time * G) / 2.0)); //prints out the formula values and the loop values.
}
}
}
Excuse the mess, it's just I've been trying different ways to get to work, but found none so far.
The problem is that double doesn't have the kind of accuracy you're looking for, so it doesn't count by an even .01 each iteration as your output clearly shows. The solution is to use BigDecimal. I rewrote the program a bit...
package test;
import java.math.BigDecimal;
import java.util.Scanner;
public class CannonBlaster {
private static final double G = 9.81;
private static final BigDecimal DELTA_T = new BigDecimal(0.01);
private static final double DELTA_T_DOUBLE = DELTA_T.doubleValue();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double s = 0.0;
BigDecimal time = new BigDecimal(0.0);
double time_double = 0.0;
System.out.println("What's the initial velocity?: ");// asking for the
// initial
// velocity
double v = input.nextDouble();
// As long as the height isn't negative it will continue to go.
while (s >= 0.0)
{
s += v * DELTA_T_DOUBLE;
v -= G * DELTA_T_DOUBLE;
time = time.add(DELTA_T);
time_double = time.doubleValue();
if (time.doubleValue()%1==0) {
System.out.printf("Approximated position at t=%3ds is %10.6f.\n", time.intValue(), s);
// prints out the formula values and the loop values.
System.out.println("Formula's position: " + formula(time_double));
}
}
}
private static double formula(double x){
return 100.0 * x - (x * x * G) / 2.0;
}
}
The problem is that your time step, DELTA_T, is not exactly representable as a double value. Each iteration accumulates this small error, and you can see this in the time values that get printed out.
Usually it's preferable to avoid this problem when comparing two floating point numbers by comparing the absolute difference between the two numbers to some "small" value, where "small" is defined by the problem / magnitude of numbers you are working with. DELTA_T fits pretty well here, so you could use this comparison for a per-second time step:
if (Math.abs(time - Math.round(time)) < DELTA_T)
{
// Other code here
}
Alternatively, for a more generalized time step, in PRINT_INTERVAL:
final double PRINT_INTERVAL = 0.1;
// Other code...
if (Math.abs(time / PRINT_INTERVAL - Math.round(time / PRINT_INTERVAL)) < DELTA_T)
{
// Other code here
}

Categories