I am writing a program that prints 100 random coordinates within a circle. The circle has the radius 10 and its center is located at (0,0). However, some of the coordinates y:value is incorrectly calculated when I'm using: y = Math.sqrt(100 -x^2) The result is like off... Why is that ? (See picture) For positive y:values, they get too big sometimes and its because of the math.sqrt calculation with doubles.
package RKap14;
import ZindansMethods.ZindanRandom;
public class Dot {
public double x;
public double y;
public static void main(String[] arg)throws Exception {
//Create the array with null fields?
Coord[] c;
//Decide how many fields
c = new Coord[100];
//Create an object of class Coord in each slot of the array
for(int i = 0; i<c.length; i++) {
c[i] = new Coord();
}
//Assign random coordinates for each field x & y
for(int i = 0; i<c.length; i++) {
c[i].x = ZindanRandom.randomized(-10,10);
//Since sometimes Java calculates wrong and gives numbers above 10 and below -10...
while(c[i].x > 10 || c[i].x < -10)
c[i].x = ZindanRandom.randomized(-10,10);
c[i].y = ZindanRandom.randomized(-Math.sqrt(100-c[i].x*c[i].x), Math.sqrt(100-c[i].x*c[i].x));
}
//Print out the coordinates in form: (x,y),(x1,y1)...(x99,y99)
for (int i = 0; i<c.length; i++) {
System.out.print("(" + c[i].x + "," + c[i].y + ")" + ",");
}
}
}
class Coord {
double x;
double y;
}
The random method I am using:
//Gives random number a to b. For example -10 <= x <= 10
public static double randomized (double a, double b) {
return (a-1+Math.random()*Math.abs(b-a+1)+1);
}
I don't know what to try. I tried doing this program with a trigonometric approach but I'd rather understand why the calculator is doing its job wrongfully. Are there too many decimals? Can I do something about it ?
Circle test
your random function is generating numbers outside the given range
for example if you substitute the values into your equation and and use 1 as the value returned from Math.random() you will get 101.
Try the following random function instead:
public static double randomized(double min, double max)
return Math.random() * (max - min) + min;
}
Related
I'm trying to get my program to out the first 500 values for this formula: -12*ln(1-x) where x is the return of double next(). I don't know what I'm doing wrong because I can't get the right output. The random number uses this formula x(i+1) = (a * x(i) + c) mod k
public class myRnd {
// Linear values for x(i+1) = (a * x(i) + c) % k
final static int a = 7893;
final static int c = 3517;
final static int k = 8192;
// Current value for returning
int x;
int y;
int z;
public myRnd() {
// Constructor simply sets value to half of k
x = (125*k) /1024;
//y = (125*k) /1024;
}
double next() {
// Calculate next value in sequence
x = (a * x + c) % k;
// Return its 0 to 1 value
return (double)x / k;
}
public static void main(String[] args) {
int situation;
double sec_answer;
// Create a new myRnd instance
myRnd r = new myRnd();
// Output 53 random numbers from it
for (int i = 0; i < 53; i++) {
System.out.println (r.next());
}
System.out.println("random variable");
for(int b = 0; b < 500; b++){
sec_answer = (-12)*Math.log(1- r.next());
System.out.println(sec_answer);
}
}
}
I suppose these are the first 5 values you're expecting from your program in each loop!
0.9302978515625
0.270263671875
0.6204833984375
0.90478515625
0.8985595703125
random variable
31.962289651479345
3.78086405322487
11.626283246646423
28.21943313114782
27.45940262908609
In your main method you have only one instance of the class:
// Create a new myRnd instance
myRnd r = new myRnd();
This initialization is propagated to both for loops.
Simple Solution: Add another instance / initialization of myRnd for the second for loop, as an example you could reuse the same variable as r = new myRnd(); before the second loop.
So in my code, it seems that in the fillRandomArray method, instead of getting an array of 100 random numbers, I just get straight zeros and I don't know how to fix it. It seems to me that the problem has to do with the first for loop, or potentially the declaration of the double array in the public class statistical model.
import javax.swing.*;
import java.util.*;
import java.util.Arrays;
public class statisticalModel {
//Initates a place for the normal curve to be placed.
static double Ho;
//Real proportion of data statistic.
static double Ha;
//Estimated real proportion of data statistic.
static int Pop;
//Population size.
static int Zscore;
//Z score, or the amount of standard deviations away from the mean.
//Z score = sqrt(P(1-p)/N)
static double stdDev;
//Standard Deviation, follows the 65, 95, 99 model. 65 percent of all scores
//fall in one standard deviation of the mean. 95 percent of all scores fall
//within two standard deviations of the mean. 99 percent of all scores fall
//within three standard deviations of the mean.
static double mean;
//The average of all the scores of the array.
static double variance;
//The average difference between sets of values within the array.
static double[] meanScores = new double[100];
//Array meant to generate a set of random values within the normal curve of
//the model, following the 65, 95, 99 rule.
static String desiredValue = "";
//This is a string set to the user's command. Tells whether or not the value should
//be lower than, higher than, or not equal to Ho.
static Scanner sc = new Scanner(System.in);
//Scanner to take in values listed above.
static int size = 100;
//Variable that measures the size of the array.
static int temporary;
//Value Holder for For Loops, While Loops, If Statements, etc.
static double pValue;
//P Value which represents how far a statistic deviates from the expected mean of a population.
public static void main(String args[])
{
runStatisticalMethod();
}
public static void runStatisticalMethod()
{
takeInData();
calculateStats();
System.out.println(Arrays.toString(meanScores));
explainSolution();
}
public static void takeInData()
{
System.out.println("Please enter your desired Ho");
Ho = sc.nextDouble();
System.out.println("Please enter your desired Ha");
Ha = sc.nextDouble();
System.out.println("Please enter your desired population size");
Pop = sc.nextInt();
System.out.println("Thanks for entering your data. Your data will be compiled below");
}
//Fills the array meanScores with random integers.
public static void fillRandomArray()
{
for (int z = 0; z < 100; z++) {
meanScores[z] = (Math.random() * 100) + (stdDev * 3);
}
assignStdDev();
for (int x = 0; x < 99; x++) {
for (int y = 0; y < 99; y++) {
if (meanScores[y] >= meanScores[y + 1]) {
double valueHolder1 = meanScores[y];
double valueHolder2 = meanScores[y + 1];
meanScores[y + 1] = valueHolder1;
meanScores[y] = valueHolder2;
}
}
}
}
public static void assignStdDev()
{
for (int x = 5; x >= 5 && x <= 95; x++) {
meanScores[x] -= (stdDev * Math.random());
}
for (int x = 31; x >= 31 && x < 66; x++) {
meanScores[x] -= (stdDev * Math.random());
}
}
//Calculates a set of statistics including standard deviation, z-score, mean,
//interquartile range, probability, and variance.
public static void calculateStats()
{
//Calculates the Mean of the inputted variables and normal curve.
int sum = 0;
for (int a = 0; a < 100; a++) {
sum += a;
}
mean = sum / size;
//Calculate the Variance of the inputted variables and normal curve.
for (int b = 0; b < 100; b++) {
temporary += (b - mean) * (b - mean);
}
variance = temporary / size;
//Calculate the Standard Deviation of the inputted variables and normal curve.
stdDev = Math.sqrt(variance);
//Calculate the P-Value and use the p value to determine whether or not the hypothesis is valid.
pValue = (Ha - Ho) / (stdDev / Math.sqrt(Pop));
}
//This method explains the numbers generated in terms of statistics and analyzes
//if the hypothesis is probably. If not, a possible solution is proposed with
//regards to what should be changed. Also explains the curve of the graph.
public static void explainSolution()
{
if (Math.abs(pValue) < .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to show information that your Ha is possibly correct, thus failing to reject your hypothesis");
} else if (Math.abs(pValue) > .05) {
System.out.println(
"Based on the information you have given me, the hypothesis test seems to lack information to show that your Ha is possibly correct, thus rejecting your hypothesis");
}
}
}
My question is why isn't the code generating the amount of numbers that the users enters? Right now the code is only generating one number. Here is the original question given to me:
"In your main method, prompt the user for a number n. Write a method
called assessRandomness that generates a random number between 1 and
100 'n' times and return the percentage of times the number was less than
or equal to 50. Call your assessRandomness method from main and display
the result to the user from main. Do not interact with the user from
within the assessRandomness method."
output:
How many random numbers should I generate? 10
<assume the random numbers generated were 11 7 50 61 52 3 92 100 81 66>
40% of the numbers were 50 or less
my code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("how many random numbers should I generate?: ");
int number = in.nextInt();
assessRandomness(number);
}
public static double assessRandomness(int n){
int random = (int)(Math.random()*100);
int randomNumbersLessthan50 = 0;
if (random <= 50)
{
double getPercentage = random/randomNumbersLessthan50;
}
else
{
System.out.println(random);
}
return random;
}
I don't see any kind of loop within assessRandomness.
Try
for(int x = 1; x <= n; x++){ ... }
as first line in assessRandomness, it should finally look like
public static double assessRandomness(int n){
int counterLessThan50 = 0;
for ( int x = 1; x <= n; x++)
if( (int)(Math.random()*100) <= 50 ) counterLessThan50++;
return (double) counterLessThan50 / n;
}
There's no repetition in your code to do something n times.
Here's one way to do it in one line using a stream:
public static double assessRandomness(int n) {
return Stream.generate(Math::random).limit(n).map(r -> r * 100 + 1).filter(r -> r <= 50).count() / (double)n;
}
Note that converting Math.random() to a number in the range 1-100 is pointless; this will give the same result:
public static double assessRandomness(int n) {
return Stream.generate(Math::random).limit(n).filter(n -> n < .5).count() / (double)n;
}
And is easier to read.
At the moment, your assessRandomness method never uses the variable n.
At first you should initialize a variable which counts the number of created randoms that are bigger than 50 (this will be your retutn value). You should then do a loop from 0 until n. For each loop run you should create a random value between 0 and 100. Then you should check wether the value is bigger than 50. If so, count up your previously created variable. When the loop has finished, return the count variable and print it in the main method.
This should help you understand better how to do something like this.
public static void main(String[] args) {
System.out.println("how many random numbers should I generate?: ");
Scanner in = new Scanner(System.in);
int number = in.nextInt();
int[] arrayPlaceHolderInMainMethod = new int[number];
arrayPlaceHolderInMainMethod = generateRandomNumberArray(number);
assessRandomness(arrayPlaceHolderInMainMethod);
}
public static void assessRandomness(int[] inputArray) {
int randomNumbersLessthan50 = 0;
int randomNumbersGreaterthan50 = 0;
int random = 0;
for (int i = 0; i < inputArray.length; i++) {
random = inputArray[i];
}
if (random <= 50) {
randomNumbersLessthan50 += 1;
} else {
randomNumbersGreaterthan50 += 1;
}
System.out.println(">50: " + randomNumbersGreaterthan50 + " Less: " + randomNumbersLessthan50);
}
public static int[] generateRandomNumberArray(int numberPickedByUser) {
int[] arrayOfRandomNumbers = new int[numberPickedByUser];
for (int i = 0; i < numberPickedByUser; i++) {
arrayOfRandomNumbers[i] = (int) (Math.random() * 100 + 1);
}
return arrayOfRandomNumbers;
}
This is the formula that can be used to calculate the square root of a number.
result=(guess+(number/guess))/2;
For example, I need to get the square root of 9. First, I need to make a guess. For this one, it's 6. Although, I know that the square root of 9 is 3, I chose 6 to show how the program should work.
that makes...
result=(6+(9/6))/2 which is equal to 3.75.
To get the actual square root of 9, I need to make the result the new guess.The program should continue as...
result=(3.75+(9/3.75))/2 which is equal to 3.075.
This process should continue till difference between result and the result after it is equal to 0. For example
result=(3+(9/3))/2 is always equal to 3.
When the value of result is passed to guess, the next result will also be 3. That means 3 is the square root of nine.
Here's my code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double result=0;
while(Math.abs(guess-ans)!=0){
result=(guess+(num/guess))/2;
guess=result;
}
System.out.print(result);
}
}
Output
3.75
My problem is I can't compare the value of result and the previous result. Since guess is equal to result, the program immediately since guess and result are already equal. How can I fix it?
Just exchange the two statements in the while loop (and the initializations to avoid a division by zero):
public static void calcRoot(){
double num=9;
double guess=0;
double result=6;
while(Math.abs(guess-result)!=0){
guess=result;
result=(guess+(num/guess))/2;
}
System.out.print(result);
}
The trick is to have the old value still in guess and the new one in result when the test is executed.
And you should not test for != 0, due to rounding errors this may not be achieved. Better test for some small value >= 1e-7
To compare the result with the previous result you need to keep both of them in a variable.
This does a binary chop.
public static double sqrt(double ans) {
if (ans < 1)
return 1.0 / sqrt(1.0 / ans);
double guess = 1;
double add = ans / 2;
while (add >= Math.ulp(guess)) {
double guess2 = guess + add;
double result = guess2 * guess2;
if (result < ans)
guess = guess2;
else if (result == ans)
return guess2;
add /= 2;
}
return guess;
}
public static void main(String[] args) {
for (int i = 0; i <= 10; i++)
System.out.println(sqrt(i) + " vs " + Math.sqrt(i));
}
prints
0.0 vs 0.0
1.0 vs 1.0
1.414213562373095 vs 1.4142135623730951
1.7320508075688772 vs 1.7320508075688772
2.0 vs 2.0
2.236067977499789 vs 2.23606797749979
2.449489742783178 vs 2.449489742783178
2.64575131106459 vs 2.6457513110645907
2.82842712474619 vs 2.8284271247461903
3.0 vs 3.0
3.162277660168379 vs 3.1622776601683795
and
for (int i = 0; i <= 10; i++)
System.out.println(i / 10.0 + ": " + sqrt(i / 10.0) + " vs " + Math.sqrt(i / 10.0));
prints
0.0: 0.0 vs 0.0
0.1: 0.31622776601683794 vs 0.31622776601683794
0.2: 0.4472135954999581 vs 0.4472135954999579
0.3: 0.5477225575051662 vs 0.5477225575051661
0.4: 0.6324555320336759 vs 0.6324555320336759
0.5: 0.7071067811865476 vs 0.7071067811865476
0.6: 0.7745966692414834 vs 0.7745966692414834
0.7: 0.8366600265340758 vs 0.8366600265340756
0.8: 0.894427190999916 vs 0.8944271909999159
0.9: 0.9486832980505138 vs 0.9486832980505138
1.0: 1.0 vs 1.0
Just create another variable to store the value of the previous guess.
This is the code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double prevGuess=0;
double result=0;
while(Math.abs(guess-prevGuess)!=0){
result=(guess+(num/guess))/2;
prevGuess = guess;
guess=result;
}
System.out.print(result);
}
}
For performance,following this code:
public static double sqrt(double num) {
double half = 0.5 * num;
long bit = Double.doubleToLongBits(num);
bit = 0x5fe6ec85e7de30daL - (bit >> 1);
num = Double.longBitsToDouble(bit);
for (int index = 0; index < 4; index++) {
num = num * (1.5f - half * num * num);
}
return 1 / num;
}
About the magic number 0x5fe6ec85e7de30daL,you can see the FAST INVERSE SQUARE ROOT
Let's see the performance,the test code:
double test = 123456;
//trigger the jit compiler
for (int index = 0; index < 100000000; index++) {
sqrt(test);
}
for (int index = 0; index < 100000000; index++) {
Math.sqrt(test);
}
//performance
long start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
sqrt(test);
}
System.out.println("this:"+(System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
Math.sqrt(test);
}
System.out.println("system:"+(System.currentTimeMillis() - start));
System.out.println(sqrt(test));
System.out.println(Math.sqrt(test));
and the result is:
this:3327
system:3236
this result:351.363060095964
system result:351.363060095964
public static double sqrt(double number)
{
double dd=number, sqi, sqrt=0;
long i, b=0, e=0, c=1, z, d=(long)number, r=0, j;
for (i=1l, sqi=1; ; i*=100l, sqi*=10)
{
if (i>dd)
{
i/=100;
sqi/=10;
j=i;
break;
}
}
for (z=0l; z<16; dd=(dd-(double)(r*i))*100, j/=100l, sqi/=10, z++)
{
r=(long)(dd/i);
d=(e*100l)+r;
int a=9;
for (c=((b*10l)+a)*a; ; a--)
{
c=((b*10l)+a)*a;
if (c<=d)
break;
}
//if (a>=0)
// System.out.print(a);
e=d-c;
sqrt+=a*sqi;
if (number==sqrt*sqrt && j==1)
break;
//if (j==1)
// System.out.print('.');
b=b*10l+2l*(a);
}
return sqrt;
}
Sorry for the undefined variable names....but this program really works!
This program is based on long division method of finding square root
I'm having difficulty writing a program to solve this exercise from a Java text book:
Write a method raiseRealToPower that takes a floating-point value x and an integer
k and returns xk. Implement your method so that it can correctly calculate the result
when k is negative, using the relationship
x^(-k) = 1 / x^k.
Use your method to display a table of values of πk for all values of k from –4 to 4.
I didn't done this part with PI, i know that, if my programs starts to work... this is what i done... tell me please, what is wrong.
import acm.program.*;
public class vjezba55 extends ConsoleProgram {
private static final double PI = 3.14159253;
public void run() {
double x = readDouble ("x: ");
double k = readDouble ("k: ");
println ("x^k = " + raiseDoublePower(x,k));
}
/* Method that counts x^k */
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
double total = 1;
for (int i= 0; i>k; i--) {
total = (double) 1 / x;
}
return total;
}
}
}
Take a look at your loop code. You are just recalculating total from scratch on each iteration, rather than updating the previous result.
I don't understand the part in the question regarding PI, but your method may be much simpler (according to using the relationship x^(-k) = 1 / x^k):
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
return 1 / Math.pow(x, -k);
}
}