Poisson Distrubtion using Normal Approximation in Java - java

If you are unsure of what "Poisson Distrubtion using Normal Approximation" means, follow this link and check the texts inside the yellow box.
https://onlinecourses.science.psu.edu/stat414/node/180
Here, is the simple snapshot of the math from the link.
P(Y≥9) = P(Y>8.5) = P(Z>(8.5−6.5)/√6.5) = P(Z>0.78)= 0.218
So to get the value in .218, we use Simpson's integration rule which
integrates the function(Implemented in method named "f" from code below) from "negative
infinity" to the value that equals to this >> "((8.5−6.5)/√6.5))"
R successfully gives the correct output. But in Java when i implemented the code
below copied from "http://introcs.cs.princeton.edu/java/93integration/SimpsonsRule.java.html"
I get "0.28360853976343986" which should have been ".218" Is it any how because of the negative infinity value I am using, which is "Double.MIN_VALUE"
This is the code in Java. See at the very end for my INPUTS in the main method.
* Standard normal distribution density function.
* Replace with any sufficiently smooth function.
**********************************************************************/
public static double f(double x) {
return Math.exp(- x * x / 2) / Math.sqrt(2 * Math.PI);
}
/**********************************************************************
* Integrate f from a to b using Simpson's rule.
* Increase N for more precision.
**********************************************************************/
public static double integrate(double a, double b) {
int N = 10000; // precision parameter
double h = (b - a) / (N - 1); // step size
// 1/3 terms
double sum = 1.0 / 3.0 * (f(a) + f(b));
// 4/3 terms
for (int i = 1; i < N - 1; i += 2) {
double x = a + h * i;
sum += 4.0 / 3.0 * f(x);
}
// 2/3 terms
for (int i = 2; i < N - 1; i += 2) {
double x = a + h * i;
sum += 2.0 / 3.0 * f(x);
}
return sum * h;
}
// sample client program
public static void main(String[] args) {
double z = (8.5-6.5)/Math.sqrt(6.5);
double a = Double.MIN_VALUE;
double b = z;
System.out.println(integrate(a, b));
}
Anybody has any ideas? I tried using Apache math's "PoissonDistribution" class's method "normalApproximateProbability(int x)". But the problem is this method takes an "int".
Anyone has any better ideas on how do I get the correct output or any other code. I have used another library for simpson too but I get the same output.
I need this to be done in Java.

I tried to test the code by writing another method that implements Simpson's 3/8 rule instead of your integrate function. It gave the same result as the one you obtained at first time. So i think the difference arises most probably from rounding errors.

Related

Why are my cos(x) outputs out of bound 1 and -1?

My task is to implement the cos(x) function withou using Math. library and with the taylor polynom, my code looks like this:
public class Cosinus {
public static void main(String[] args) {
/*if(args.length == 0){
System.out.println("ERROR: Geben Sie ein Argument für x ein!");
return;
}*/
double x = 5;
double summand1 = (x*x) / 2;
double summand2 = (x*x*x*x) / (2*3*4);
double summand3 = (x*x*x*x*x*x) / (2*3*4*5*6);
double summand4 = (x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8);
double summand5 = (x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10);
double summand6 = (x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12);
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14);
//double summand8 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
//double summand9 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
//double summand10 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
double cosinusFunktion = (((((((1 - summand1) + summand2) - summand3) + summand4) - summand5) + summand6) - summand7);
System.out.println(cosinusFunktion);
}
}
For x = 1, 2, 3, and 4 Y is between 1 and -1
but with x = 5 it goes too -4 and if the x are even getting bigger this continues too 1287918274.
I cant solve this task but tthe task says it is enough to implement this funktion iwth the taylor polynom and the first 11 summand. I tried this too, but then even with x = 1 the bounds are broken. How can i solve this, so x = 42.5 is in bound of -1 and 1?
Tried more summands to make the result more excact, but the bounds get broken even more.
tried implement the periodicity of x-2*PI, but I dont know where to put it and results get messed up eeven more.
you are getting an integer overflow for the factorial in the summand7 line
as a simple fix you can change the line to:
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / ((double) 2*3*4*5*6*7*8*9*10*11*12*13*14);
The Taylor expansion will always blow up for larger inputs. However, since:
sin(x) = sin(x + n*2*pi) // for any integer n
You can simply pre-process you input with a modulus function to prevent your output from blowing up.
I can't test compile right now, but if memory serves, you would add one of the following lines prior to computing your first summand:
x = x%(Math.PI*2)
Or, if you can't use Math
x = x%((double)3.14159265358979323846*2)

How to calculate the percentage increasment in java

I want to calculate the increase of percentage of a variable from type int while using another variable from type int for the percentage (50 percent).
thanks in advance for anyone who is willing to help.
`
int a = 3;
int percentage = 3 / 2;
// here I get 3 instead of 4 which is the required answer.
a = a * percentage;
System.out.println(a);
// but here I get the required answer normally.
a = 3;
a = a * 3 / 2;
System.out.println(a);
`
"Percentage" is just a weird of "this value that generally is between 0 and 1 should be rendered by multiplying by 100 and adding a % symbol afterwards". In other words, it's purely a way to display a thing. 50% means 0.5.
int cannot represent 0.5. double sort of can (double and float aren't perfectly accurate). In addition / is integer division if both the left and right side are ints. So, we need to do a few things:
int a = 3;
double b = 1.0 * 3 / 2; // without that 1.0 *, it wouldn't work
System.out.println(b); // prints "1.5"
double c = a * b;
System.out.println(c); // prints 4.5.
int d = ((int) (a * b) + 0.1);
System.out.println(d); // prints 4
Because doubles aren't entirely accurate, and (int) rounds down, adding a small delta (here, 0.1) is a good idea. Otherwise various values will surprise you and go wrong (say, your math ends up at 3.99999999, solely because double is not perfectly accurate, then casting that to int gets you a 3).

Generate random numbers in a specific range with a standard deviation?

I already know how to generate random numbers in a range. I can do this by using
rand.nextInt((max - min) + 1) + min;
The problem is that I would also like to set a standard deviation for these numbers. The numbers also need to be positive and they are not between 0 and 1
EDIT I removed the ThreadLocalRandom class because I cannot set a seed in that class and these random numbers should be reproducible in a different system.
Choosing the standard deviation (or variance) for a bounded distribution can only be done subject to constraints that depend on the selected distribution and the bounds (min, max) of your interval. Some distributions may allow you to make the variance arbitrarily small (e.g. the Beta distribution), other distributions (like the Uniform distribution) don't allow any flexibility once the bounds (min, max) have been set. In any case, you'll never be able to make the variance arbitrarily large -- the bounds do prevent this (they'll always enter the expression for the distribution's variance).
I'll illustrate this for a very simple example that can be implemented without requiring any 3rd party libraries. Let's assume you want a symmetric distribution on the interval (min, max), symmetry implying that the mean E(X) of the distribution is located in the middle of the interval: E(X) = (min + max)/2.
Using Random's nextDouble as in x = a + (b - a) * rnd.nextDouble() will give you a uniformly distributed random variable in the interval a <= x < b that has a fixed variance Var(X) = (b - a)^2 / 12 (not what we want).
OTH, simulating a symmetric triangular distribution on the same interval (a, b) would give us a random variate whith the same mean but with only half the variance: Var(X) = (b - a)^2 / 24 (also fixed, so also not what we want).
A symmetric trapezoidal distribution with parameters (a < b < c < d) lies somewhere in the middle of a Uniform and a triangular distribution on the interval (a, d). The symmetry condition implies d - c = b - a, in the following I'll refer to the distance b - a as x or as "displacement" (I've made up that name, it's not a technical term).
If you let x approach 0.0 from above, the trapezoidal will begin to look very similar to a uniform distribution and its variance will tend to the maximum possible value (d - a)^2 / 12. If you let x approach the maximum possible value (d - a)/2 from below, the trapezoidal will look very similar to a symmetric triangle distribution and its variance will approach the minimum possible value of (d - a)^2 / 24) (but note that we should stay away a little from these extreme values in order not to break the variance formula or our algorithm for the trapezoidal).
So, the idea is to construct a trapezoidal distribution with a value for x that yields the standard deviation you want, given the condition that your targeted standard deviation must lie inside the open range (roughly) given by (0.2041(d - a), 0.2886(d - a)). For convenience let's assume that a = min = 2.0 and d = max = 10.0 which gives us this range of possible stddevs: (1.6328, 2.3088). Let's further assume that we want to construct a distribution with a stddev of 2.0 (which, of course, has to be in the admissible range).
Solving this requires 3 steps:
1) we need to have a formula for the variance given min, max and an admissible value for the displacement x
2) we need to somehow "invert" this expression to give us the value of x for our target variance
3) once we know the value of x we must construct a random variable that has a symmetric trapezoidal distribution with the parameters (min, max, x)
Step 1:
/**
* Variance of a symmetric trapezoidal distribution with parameters
* {#code a < b < c < d} and the length of {#code d - c = b - a}
* (by symmetry) identified by {#code x}.
*
* #param a support lower bound
* #param d support upper bound
* #param x length of {#code d - c = b - a}, constrained to lie in the open
* interval {#code (0, (d-a)/2)}
* #return variance of the symmetric trapezoidal distribution defined by
* the triple {#code (a, d, x)}
*/
static double varSymTrapezoid(double a, double d, double x) {
if (a <= 0.0 || d <= 0.0 || a >= d) {
throw new IllegalArgumentException();
}
if (x <= 0.0 || x >= (d - a) / 2) {
throw new IllegalArgumentException();
}
double b = a + x;
double c = d - x;
double b3 = pow(b, 3);
double c3 = pow(c, 3);
double ex2p1 = pow(b, 4) / 4 - a * b3 / 3 + pow(a, 4) / 12;
double ex2p2 = (c3 / 3 - b3 / 3) * (d - c);
double ex2p3 = pow(c, 4) / 4 - d * c3 / 3 + pow(d, 4) / 12;
double ex2 = (ex2p1 + ex2p2 + ex2p3) / ((d - b) * (d - c));
return ex2 - pow((a + d) / 2, 2);
}
Note that this formula is only valid for symmetric trapezoidal distributions. As an example, if you call this method with a displacement of 2.5 (varSymTrapezoid(2.0, 10.0, 2.5)) it'd give you back a variance of approximately 3.0416 which is too low (we need 4.0), meaning that a displacement of 2.5 is too much (higher displacements give lower variances).
The variance expression is a 4th order polynomial in x that I'd rather not want to solve analytically. However, for a target x in the admissible range this expression is monotonically decreasing, so we can construct a function that crosses zero for our target variance and solve this by simple bisection. This is
Step 2:
/**
* Find the displacement {#code x} for the given {#code stddev} by simple
* bisection.
* #param min support lower bound
* #param max support upper bound
* #param stddev the standard deviation we want
* #return the length {#code x} of {#code d - c = b - a} that yields a
* standard deviation roughly equal to {#code stddev}
*/
static double bisect(double min, double max, double stddev) {
final double eps = 1e-4;
final double var = pow(stddev, 2);
int iters = 0;
double a = eps;
double b = (max - min) / 2 - eps;
double x = eps;
double dx = b - a;
while (abs(dx) > eps && iters < 150 && eval(min, max, x, var) != 0.0) {
x = ((a + b) / 2);
if ((eval(min, max, a, var) * eval(min, max, x, var)) < 0.0) {
b = x;
dx = b - a;
} else {
a = x;
dx = b - a;
}
iters++;
}
if (abs(eval(min, max, x, var)) > eps) {
throw new RuntimeException("failed to find solution");
}
return x;
}
/**
* Function whose root we want to find.
*/
static double eval(double min, double max, double x, double var) {
return varSymTrapezoid(min, max, x) - var;
}
Calling the bisect method with the desired value 2.0 for the standard deviation (bisect(2.0, 10.0, 2.0)) gives us the needed displacement: ~ 1.1716. Now that the value for x is known, the final thing we have to do is to construct a suitably distributed random variable which is
Step 3:
It is a well-known fact of probability theory that the sum of two independent uniformly distributed random variables X1 ~ U[a1, b1] and X2 ~ U[a2, b2] is a symmetric trapezoidally distributed random variable on the interval [a1 + a2, b1 + b2] provided that either a1 + b2 < a2 + b1 (case 1) or a2 + b1 < a1 + b2 (case 2). We have to avoid the case a2 + b1 = a1 + b2 (case 3) since then the sum has a symmetric triangular distribution which we don't want.
We'll choose case 1 (a1 + b2 < a2 + b1). In that case the length of b2 - a2 will be equal to the "displacement" x.
So, all we have to do is to choose the interval boundaries a1, a2, b1 and b2 such that a1 + a2 = min, b1 + b2 = max, b2 - a2 = x and the above inequality is fullfilled:
/**
* Return a pseudorandom double for the symmetric trapezoidal distribution
* defined by the triple {#code (min, max, x)}
* #param min support lower bound
* #param max support upper bound
* #param x length of {#code max - c = b - min}, constrained to lie in the
* open interval {#code (0, (max-min)/2)}
*/
public static double symTrapezoidRandom(double min, double max, double x) {
final double a1 = 0.5 * min;
final double a2 = a1;
final double b1 = max - a2 - x;
final double b2 = a2 + x;
if ((a1 + b2) >= (a2 + b1)) {
throw new IllegalArgumentException();
}
double u = a1 + (b1 - a1) * rnd.nextDouble();
double v = a2 + (b2 - a2) * rnd.nextDouble();
return u + v;
}
Calling symTrapezoidRandom(2.0, 10.0, 1.1716) repeatedly gives you random variables that have the desired distribution.
You could do very similar things with other, more sophisticated, distributions like the Beta. This would give you other (usually more flexible) bounds on the admissible variances but you'd need a 3rd party library like commons.math for that.
abs, pow, sqrt in the code refer to the statically imported java.lang.Math methods and rnd is an instance of java.util.Random.

Integer division using recursion--and a few other interesting limitations

I am trying to solve a puzzle in Java for my own edification. I am told there is a solution by the guy who designed the puzzle, but I'm not able to find it myself.
Here's the puzzle:
Implement the following method in Java
/**
* Divides a natural number by two.
*
* #param n
* The number to be divided
* #updates n
* #ensures n = floor(n/2)
*/
private static void split(NaturalNumber n) {...}
The NaturalNumber class is simply a class that stores a natural number
using a string. ( That is, it can store numbers much larger than
Integer.MAX_VALUE. )
The class provides these instance methods and inherited
methods, as well as the NaturalNumber.isZero() method, which
returns true if the instance's internal string value is "0", false
otherwise.
It's worth noting that the NaturalNumber.divideBy10() method
essentially pops the rightmost digit off the number, returns it as an
int and updates the instance's internal value.
Do not use static properties on the main class to store values.
Similarly, do not write static helper methods.
Do not convert n to some other data type and operate on that. Do not use external libraries.
Furthermore, split() must be implemented using recursion.
I have the following near solution worked out:
private static void split(NaturalNumber n) {
// Initialize local variables.
String stringBuffer = "";
int numerator = 0;
int quotient = 0;
int remainder = 0;
int thisDigit = n.divideBy10();
if (n.isZero()) {
quotient = thisDigit / 2;
remainder = thisDigit % 2;
n.transferFrom(new NaturalNumber2(quotient * 10 + remainder));
} else {
split(n);
numerator = n.divideBy10() * 10 + thisDigit;
quotient = numerator / 2;
remainder = numerator % 2;
if (!n.isZero()) {
stringBuffer += n.toString();
}
stringBuffer += Integer.toString(quotient * 10 + remainder);
n.transferFrom(new NaturalNumber2(stringBuffer));
}
}
The above simply performs long division. But the last frame in the call stack needlessly appends the remainder of its operation onto the end of the solution.
I have seen solutions to similar problems that recursively subtract two from n, counting how many times two must be subtracted for n to become zero. But those solutions rely on the method having a return value; this puzzle requires there be no return value.
I can also see how to solve the puzzle using one function call to split() and internal loops. But I am told the solution must not rely on loops to operate on n.
Does anyone out there have any insight into a solution?
Suppose the digits of n are a...yz. If y is even, then the digits of n / 2 are the concatenation of a...y / 2 and z / 2. If y is odd, let Y = y - 1. Then the digits of n / 2 are the concatenation of a...Y / 2 and 1z / 2.
We can implement this as follows:
private static void split(NaturalNumber n) {
int z = n.divideBy10();
int y = n.divideBy10();
if (n.isZero()) {
// Base case.
int result = (y * 10 + z) / 2;
n.multiplyBy10(result / 10);
n.multiplyBy10(result % 10);
} else if (y % 2 == 0) {
n.multiplyBy10(y);
split(n);
n.multiplyBy10(z / 2);
} else {
n.multiplyBy10(y - 1);
split(n);
n.multiplyBy10((10 + z) / 2);
}
}
Incidentally, these method names are awful, and making NaturalNumbers mutable is a weird design choice.

Arithmetic problems with java longs

I have two equations: x * x - D * y * y = 1 and x = sqrt(1 + D * y * y).
Both are algebraic manipulations of the other.
Given D, I need to solve for the smallest integer value of x so that y is also an integer. I loop through possible y values, plug them into the second equation and test if x is an integer. If it is, I return x.
The problem I have is when x, y, and D are plugged into the 1st equation, it does not equal 1.
These are some problematic values:
1. x=335159612 y=42912791 D=61
2. x=372326272 y=35662389 D=109
My intuition is that java's Math.sqrt method does not calculate such a small decimal, however BigDecimal does not have a square root method.
Is my math just wrong? If not, what can I do to accurately calculate x and y?
Edit: Here is the root of the problem along with the method that tests if a double is a a natural number.
public static void main(String[] args){
long x = 335159612, D = 61, y = 42912791;
System.out.println(Math.sqrt(D * y * y + 2)); // 3.35159612E8
System.out.println(x * x - D * y * y); // 3
}
public static boolean isNatural(double d){
return d == (int)d;
}
Be careful with precisions in 'double'.
As per IEEE 754-1985 the double precision provides 16 digits (15,9 to be absolutely precise).
E.g.
a) SQRT(112331965515990542) is
335159611.99999999701634694576505237017910
Which, when converted into double, gives 3.3515961199999999E8
b) SQRT(112331965515990543)
335159611.99999999850817347288252618840968
Which, when converted into double, gives 3.3515961199999999E8.
So, as per IEEE 754-1985 definition, those values are equal.
Apparently, any further logical/mathematical checks will be, generally speaking, inaccurate.
To overcome this limitation I recommend BigMath package from www.javasoft.ch
import ch.javasoft.math.BigMath;
import java.math.BigDecimal;
class Tester {
public static void main(String[] args) {
long D = 61L, y = 42912791L;
double a = Math.sqrt(D * y * y + 1);
double b = Math.sqrt(D * y * y + 2);
System.out.println(a);
System.out.println(b);
System.out.println(a == b);
BigDecimal bda = BigMath.sqrt(new BigDecimal(D * y * y + 1), 32);
BigDecimal bdb = BigMath.sqrt(new BigDecimal(D * y * y + 2), 32);
System.out.println(bda.toString());
System.out.println(bdb.toString());
System.out.println(bda.equals(bdb));
}
}
Result:
3.35159612E8
3.35159612E8
true
335159611.99999999701634694576505237017910
335159611.99999999850817347288252618840968
false
P.s. to completely ruin your faith in standard Java maths try this:
System.out.println(0.9200000000000002);
System.out.println(0.9200000000000001);
You will see:
0.9200000000000002
0.9200000000000002
This kind of Diophantine's equations is known as Pell's equations.
Wiki.
Mathworld.
Both links contain clues - how to solve this equation using continued fractions.
I think it would be nice to apply some math instead of brutforce/
If sqrt is the issue, use the first equation instead. If x is an integer, x^2 will also be an integer; if x is not an integer, then x^2 would also not be an integer, as long as you are using BigDecimals with sufficient scale for your math and not doubles.

Categories

Resources