Essentially i want to find an estimate of pi by throwing a dart at the unit circle. So I want to throw a dart a the positive x and y quadrant of the unit circle , each dart thrown will give me a random position in the x and y direction that is less that 1. I then need to find the distance from the origin from that point. The approximation of pi will come from when the distance of the dart from the origin is less than 1 when calculated, this will count as a hit, anything else will count as a miss. Using this number pi is found by (#hits/#of tosses)*4 since i will only be looking at 1/4 of the circle .I then want to print a table with different results depending on how many darts are thrown. my code is below, I'm confused on a lot of things, mainly how do I collect all the data and print it all, I was thinking of using an ArrayList of arrays of ints since it will not be limited to the amount of trials I want to do but I am unsure on how to proceed. Any help is useful, thanks!
public static void main(String[]args){
int[] darts_Thrown = {10, 100, 1000, 10000, 100000,1000000};
// for( int i = 0; i < points.length; i++){
// System.out.print(points[i]);
// }
for (int i = 0; i < darts_Thrown.length;i++){
for (int j = 0; j < darts_Thrown[i]; j++){
int test = 0;
double [] points = getPoint();
// distanceToOrigin(points[0],points[1]);
// getHits();
test++;
System.out.printf("%d",test);
}
System.out.printf("%n%s", "hi ");
}
}
public static double[] getPoint()//code to generate x and y and return them in a double array
{
double[] point_X_Y = {Math.random(),Math.random()};
return point_X_Y;
}
public static double distanceToOrigin(double x,double y) //code to compute distance from point (x,y) to origin (0,0)
{
double distance = Math.sqrt((Math.pow(x,2))+(Math.pow(y,2))); // used to find distance from origin
return distance;
}
public static int getHits(int n)
{
int hits = 0;
int misses=0;
//double distance = distanceToOrigin(points[0], points[1]);
//if (distance < 0){
// hits++;
// return hits;
// }
// else{
// misses++;
//return misses;
// }
// return 0;
//code to get hits given n= number of darts
}
}
The formula #hits/#tosses is correct in thought, but it's gotta be too small, since it can't possibly be larger than 1. It turns out that that formula will approximate the value of PI/4, so the approximation of PI is #hits/#tosses*4.
For each trial, it isn't really practical to "collect all the data and print it all", if you want to get a reasonable approximation of PI by the end, because it's going to take a million or so trials to get at all close. I found that 1M trials gives a pretty good result, and 10M often gives you the right result to 4 decimal places. There's no use in printing even a few 100 individual trials, much less 1M of them. So I think all you can really print is the trial number, the number of throws, the number of hits, and the final approximation of PI. Here's code that does that:
public class Test {
public static void main(String[]args){
int[] darts_Thrown = {10, 100, 1000, 10000, 100000, 1000000, 10000000};
for (int i = 0; i < darts_Thrown.length;i++){
int hits = 0;
for (int j = 0; j < darts_Thrown[i]; j++){
double [] points = getPoint();
double distance = distanceToOrigin(points[0],points[1]);
if (distance <= 1.0)
hits++;
}
double pi_est = (double)hits / darts_Thrown[i] * 4.0;
System.out.printf("Trial: %d Throws: %d Hits: %d Approximation of PI (hits/throws*4): %.4f\n",
i, darts_Thrown[i], hits, pi_est);
}
}
public static double[] getPoint()//code to generate x and y and return them in a double array
{
final double[] doubles = {Math.random(), Math.random()};
return doubles;
}
public static double distanceToOrigin(double x,double y) //code to compute distance from point (x,y) to origin (0,0)
{
double distance = Math.sqrt((Math.pow(x,2))+(Math.pow(y,2))); // used to find distance from origin
return distance;
}
}
Result:
Trial: 1 Throws: 10 Hits: 8 Approximation of PI (hits/throws*4): 3.2000
Trial: 2 Throws: 100 Hits: 79 Approximation of PI (hits/throws*4): 3.1600
Trial: 3 Throws: 1000 Hits: 773 Approximation of PI (hits/throws*4): 3.0920
Trial: 4 Throws: 10000 Hits: 7800 Approximation of PI (hits/throws*4): 3.1200
Trial: 5 Throws: 100000 Hits: 78409 Approximation of PI (hits/throws*4): 3.1364
Trial: 6 Throws: 1000000 Hits: 785250 Approximation of PI (hits/throws*4): 3.1410
Trial: 7 Throws: 10000000 Hits: 7852455 Approximation of PI (hits/throws*4): 3.1410
The formula is pretty easy to derive. For a circle with radius 1 centered at the origin, 1/4 of it will be in the quadrant x=0-1, y=0-1. The points inside that circle are 1 unit from the origin or closer, so those are all 'hits'. A 1/4 of a circle of radius 1 has an area of PI * r^2 / 4 = PI * 1^2 / 4 = PI/4. The entire target area is x * y = 1 * 1 = 1. So hits/throws = (PI/4)/(1) = PI/4. Multiply both sides by 4 to get PI = hits/throws * 4.
Related
I wrote this little program to calculate pi.
While playing with the code and trying to find the most exact result, I found a point where my computer couldn't calalculate a result. It could do 33554430 repetitions within seconds, but if i increased the for loop to 33554431 it didn't output anything.
So is 33554430 a special number?
public class CalculatePi{
public static void main(String[] args){
float pi=0;
int sign=1;
for(float i=1; i <= 33554430; i+=2){
pi += (sign*(1.0/i));
sign*= -1;
}
pi *= 4;
System.out.println(pi);
}
}
You are getting and endless loop, because during the comparison i <= 33554431, the int value 33554431 is promoted to a float value which is "too precise" for float and will actually equal to 33554432.
Then, when you try to increase the value by +2, the float just isn't precise enough to increment from the value 33554432. To illustrate my point:
float f = 33554432;
System.out.println(f); //33554432
f += 2;
System.out.println(f); //33554432
So the value f doesn't increase due to its precision limitation. If you'd increase it by, say 11, you'd get 33554444 (and not 33554443) as that is the closest number expressible with that precision.
So is 33554430 a special number?
Sort of, not 33554430 but rather 33554432. First "special number" for float is 16777217, which is the first positive integer that cannot be represented as a float (equals 16777216 as float). So, if you'd increment your i variable by 1, this is the number you'd get stuck on. Now, since you are incrementing by 2, the number you get stuck on is 16777216 * 2 = 33554432.
public class CalculatePi{
public static void main(String[] args){
float pi=0;
int sign=1;
for(float i=1; i <= 33554431; i+=2){
pi += (sign*(1.0/i));
sign*= -1;
if( i > 33554410) System.out.println(i);
}
pi *= 4;
System.out.println(pi);
System.out.println((float)33554431);
System.out.println((float)33554432);
System.out.println((float)33554434);
}
}
You compare float with int in for loop. When you convert 33554431 (it's int value) to float you get 3.3554432E7.
It's about accuracy, precision. When you run:
System.out.println((float)33554431); // -> 3.3554432E7
System.out.println((float)33554432); // -> 3.3554432E7
System.out.println((float)33554434); // -> 3.3554432E7
All 3 prints 3.3554432E7, it means that when you increase float value of 33554432 by 2, you get 3.3554432E7, exactly this same value, and your loop runs forever.
Your loop increments by 2 each time.
2 * 33554430 = 67108860
2 ^ 26 = 67108864
Maybe Java stores floating point numbers in a 32bit system by using 26bits for the mantissa and 6 bits for the exponent?
This version works for both. It's the float loop variable causing problems:
public static void main(String[] args){
float pi=0;
int sign=1;
for(int i=1; i <= 33554430; i+=2){
pi += (sign*(1.0/(float)i));
sign*= -1;
}
pi *= 4;
System.out.println(pi);
}
Probably this is due this issue:
The finite nonzero values of any floating-point value set can all be
expressed in the form s · m · 2(e - N + 1), where s is +1 or -1, m is
a positive integer less than 2N, and e is an integer between Emin =
-(2K-1-2) and Emax = 2K-1-1, inclusive, and where N and K are parameters that depend on the value set.
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
So I am trying to design a multilayered neural network with 3 input neurons 3 hidden neurons and 1 output neuron.
I plan on making it learn the 3 bit xor pattern. b1 xor b2 xor b3 kind of a table.
Right now I am trying to teach it the following table.
0d,0d,0d =>0d
0d,0d,1d =>1d
0d,1d,0d =>1d
0d,1d,1d =>0d
1d,1d,0d =>0d
1d,1d,1d =>1d
hidden[] is the weights between hidden layer and the output layer
input[] is the weights between input and hidden layer.
Ignore the D's
Here's the code and it converges after barely 10 epochs with 0.1 learning rate and the value of error is down to infinity :|
class neuron{
double hidden[] = {1d,1d,1d};
double input[][] = { {1d,1d,1d},{1d,1d,1d},{1d,1d,1d}};
double learning = 0.1;
double bias = 1d;
public double[] react(double a,double b,double c){
double h1 = a*input[0][0] + b*input[0][1] + c*input[0][2];
double h2 = a*input[1][0] + b*input[1][1] + c*input[1][2];
double h3 = a*input[2][0] + b*input[2][1] + c*input[2][2];
//System.out.println(input[0][0]);
double total[] = new double[4];
total[0] = h1*hidden[0] + h2*hidden[1] + h3*hidden[2] + bias;
total[1] = h1; total[2] = h2; total[3] = h3;
return total;
}
public void learn(double a,double b, double c, double ideal){
double actual[] = react(a,b,c);
double error = ideal - actual[0];
System.out.println(error);
error *= learning;
for( int i = 0; i < 3; i++ )
hidden[i] += error * actual[i+1];
bias += error;
for( int i = 0; i < 3; i++ ){
input[i][0] += error * actual[i+1] * a;
input[i][1] += error * actual[i+1] * b;
input[i][2] += error * actual[i+1] * c;
}
}
}
public class multilayer{
public static void main(String argz[]){
neuron a = new neuron();
for( int i = 0; i < 20; i++){
a.learn(0d,0d,0d,0d);
a.learn(0d,0d,1d,0d);
a.learn(0d,1d,0d,0d);
a.learn(0d,1d,1d,0d);
a.learn(1d,1d,0d,0d);
a.learn(1d,1d,1d,1d);
}
System.out.println(a.react(0d,0d,0d)[0] >=0.5 ? 1 : 0);
System.out.println(a.react(0d,0d,1d)[0]>=0.5 ? 1 : 0);
System.out.println(a.react(0d,1d,0d)[0]>=0.5 ? 1 : 0);
System.out.println(a.react(1d,1d,0d)[0]>=0.5 ? 1 : 0);
System.out.println(a.react(0d,1d,1d)[0]>=0.5 ? 1 : 0);
System.out.println(a.react(1d,1d,1d)[0]>=0.5 ? 1 : 0);
}
}
I knocked off a hidden neuron and it still converges to infinity all the weights !!
First of all, you should add a bias input for each of your hidden units too. Each non-input unit in an artificial neural network should have a bias input, it will help the unit to converge faster.
Second, you should change the weights in opposite direction (you should subtract error from weights). The main reason that you're converging to infinity is this. Because, the more bigger your weights are, the more bigger your error will be. By adding the error to the weight you're creating a chain reaction resulting weights (and error) converging to infinity.
Third, your learning algorithm is completely wrong :) specially the part that you calculate input weights regarding to error and their inputs.
In a multi-layer neural network, you should use error back propagation algorithm (EBP). This algorithm changes each weight regarding to its share in the final error. In order to find changing rate it uses derivative of output error. For more information about EBP check this question.
This easy program program computes an estimate of pi by simulating dart throws onto a square.
Сonditions: Generate a random floating-point number and transform it so that it is between -1 and 1.
Store in x. Repeat for y. Check that (x, y) is in the unit circle, that is, the distance between (0, 0) and (x, y) is <= 1.
After this, need to find the ratio hits / tries is approximately the same as the ratio circle area / square area = pi / 4. (square is 1 per 1).
Code:
public class MonteCarlo {
public static void main(String[] args)
{
System.out.println("Number of tries");
Random generator = new Random(42);
Scanner in = new Scanner(System.in);
int tries = in.nextInt();
int hits = 0;
double x, y;
for (int i = 1; i <= tries; i++)
{
// Generate two random numbers between -1 and 1
int plusOrMinus = generator.nextInt(1000);
if (plusOrMinus > 500) x = generator.nextDouble();
else x = -generator.nextDouble();
plusOrMinus = generator.nextInt(10000);
if (plusOrMinus > 5000) y = generator.nextDouble();
else y = -generator.nextDouble();
if (Math.sqrt((x * x) + (y * y)) <= 1) // Check whether the point lies in the unit circle
{
hits++;
}
}
double piEstimate = 4.0 * hits / tries;
System.out.println("Estimate for pi: " + piEstimate);
}
}
Testing output:
Actual output Expected output
-----------------------------------------------
Number of tries Number of tries
1000 1000
- Estimate for pi: 3.176 Estimate for pi: 3.312
Actual output Expected output
-----------------------------------------------------
Number of tries Number of tries
1000000 1000000
- Estimate for pi: 3.141912 Estimate for pi: 3.143472
Maybe, does exist other approaches to find this solution?
Any suggestions.
For generating the random double between -1 and 1, try:
generator.nextDouble() * 2 - 1
BTW: If you keep initializing your random with a static seed, you'll always get the same result. Otherwise, if you are concerned that your result is not good enough, keep in mind that the Monte Carlo is only an approximation. After all, it's based on random numbers, so the result will vary from the sample solution ;-)
A generalized solution to turn a Uniform(0,1) into a Uniform(a,b) (where a < b) is
(b - a) * generator.nextDouble() + a
As #winSharp93 pointed out, you should expect variation but you can quantify the margin of error as a statistical confidence interval. If you calculate
halfWidth = 1.96 * Math.sqrt(piEstimate * (4.0 - piEstimate) / tries);
then the actual value of pi should fall between piEstimate - halfWidth and piEstimate + halfWidth 95% of the time. You can see from the halfWidth calculation that the range containing pi will shrink (but not linearly) as the number of tries is increased. You can adjust the confidence level from 95% to other values by replacing 1.96 with an alternative scale value out of a Standard Normal table.
I'm trying to convert the math presented on this paper:
http://www.bouncingchairs.net/pskalman-lategecco.pdf
Around page 3 forward into working code. The algorithm itself is given
around page 6, but I don't speak greek or math; so for the time being I'm stuck.
If I understand the code, it should run down like this:
vt = particle velocity, 1d array
vbest = best particle velocity 1d array
v_prime = 1d storage array
v_hat = 1d storage array
alpha = 0.45
sigma = 0.60
denom = float
denom_best = float
Prep:
for(int i = 0; i < vt.length; i++)
{
denom += vt[i] ^ 2
denom_best += vbest[i] ^ 2
}
denom = denom ^ (1/2)
denom_best = denom_best ^ (1/2)
Equation 7:
for(int i = 0; i < vt.length; i++)
{
v_prime[i] = alpha * (vt[i]/denom) + (1 - alpha) * (vbest[i]/denom_best)
}
Equation 8:
for(int i = 0; i < vt.length; i++)
{
v_hat[i] = Rand_Gauss(v_prime[i], sigma) //gaussian random number with
//v_prime[i] average, and sigma StDev
}
Equation 9:
for(int i = 0; i < vt.length; i++)
{
vt[i] = (alpha * denom + (1 - alpha) * denom_best) * v_hat[i]
}
Is this even close to what the math is saying?
Thanks in advance,
-JW
I think you might be missing the calls to "norm(...)". Normalizing a vector is just dividing each component of the vector by the length. In Equation 9, they calculate the weighted sum of the lengths of vt and vbest and multiply that average length by norm(vbar). You're just multiplying it by vbar directly.
The intent behind that equation seems to be to create a new vector v_{t+1} whose length is the average length of vt and vbest. However, vhat could be any length at all, so the multiplication in Equation 9 most of the time won't give you the correct answer unless you force the length of the vhat vector to be exactly one. That's what the vector norm does.
The norm is just the components of the vector divided by the length. So replace your code for equation 9 with something like this:
vtlen=0
for(int i=0; i<vt.length; i++)
{
vtlen+=vt[i]*vt[i];
}
vtlen=sqrt(vtlen);
for(int i=0; i<vt.length; i++)
{
vt[i] = (alpha * denom + (1 - alpha) * denom_best) * (v_hat[i] / vtlen);
}
You've also ignored the norm operation in Equation 7. I haven't read the paper, but it may not be strictly necessary here as the weights sum to one and the vectors are already normalized. I'd have to spend a bit more time to convince myself one way or the other, but it certainly wouldn't hurt to go ahead and normalize that calculated v' vector too.