returning infinity in my for loop? - java

Right now when I run my code it returns infinity in the std dev and variance. How do I fix this?
When I take the //VARIANCE and //STD DEV out of the for loop it gives me a value but it's not the right one. So I'm thinking it's because when you take it out of the for loop "i" isn't working correctly? I know "i" is the problem because it's supposed to be "for the number of elements in the number list, take each element and subtract the average and square it." How do I achieve it?
#Override
public String calculate() throws Exception {
//String firstConfidenceInterval = String.valueOf(SRC_Calc_Type.CI(PH, CV, N));
double total = 0.0;
double total1 = 0.0;
int i;
String delims = ",";
String[] tokens = nums.split(delims);
for(i = 0; i < tokens.length; i++) {
total += (Double.parseDouble(tokens[i]));// SUM
}
double average = total / i; //average
total1 += (Math.pow((i - average), 2) / i); //VARIANCE
double std_dev = Math.pow(total1, 0.5); //STDDEV
return String.valueOf("Sum: " + total + //Works
"\nMean: " + average + //Works
"\nStandard Deviation: " + std_dev + //works
"\nVariance: " + total1); //works
//"\nNumbers Sorted: " + "( " + " )"
}

You need a second loop to calculate the variance
double variance=0;
for(String token : tokens) {
double value = Double.parseDouble(token);
variance += Math.pow(value-average,2);
}
variance = variance/tokens.length;

You are misunderstanding how to calculate the variance and the standard deviation. You don't subtract the average from the number of elements.
You need to calculate the differences of each individual sample from the mean, square them all, then add all of the squares.
double variance = 0.0;
for (i = 0; i < tokens.length; i++)
{
// It would be better to parse the tokens once and
// place them into an array; they are referenced twice.
double diff = Double.parseDouble(tokens[i]) - average;
variance += diff * diff;
}
// of (tokens.length - 1) for "sample" variance
variance /= tokens.length;
Then you can take the square root for the standard deviation.
double std_dev = Math.sqrt(variance);

Replace i with tokens.length() everywhere outside the loop. In the futute, to avoid errors like this, always initialize variables when you declare them, and always declare them in the narrowest scope. fot(int I=0 ... in this case. Note, that your formula for variance is wrong. This is not how you computer variance.

Related

My code doesn't calculate min and max numbers

I'm trying to write a code which will show the highest, lowest, the difference of them and the average of inputted 30 numbers.
But its not working and is showing the same result for both min and max numbers. Here is the code.
public class aa {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] daystemp = new int[30];
int i = 0;
int dayHot = 0;
int dayCold = 0;
while(i < daystemp.length){
daystemp[i] = input.nextInt();
i++;
}
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
i++;
}
}
System.out.println(maxTemp);
int minTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] < minTemp) {
minTemp = daystemp[i];
dayCold = i + 1;
i++;
}
}
System.out.println(minTemp);
int diff = maxTemp - minTemp;
System.out.println("The difference between them is"+diff);
double sum = 0;
while(i < daystemp.length) {
sum += daystemp[i];
i++;
}
double average = sum / daystemp.length;
System.out.println("Average was"+average);
}
}
After the first loop (the input loop), i value is daystemp.length (i.e. 30).
It's never reset to 0. So each while loop condition is false.
Add i=0 before the loops and do i++outside the ifblocks or your code will never end.
example:
i=0;
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
}
i++;
}
A few notes about this solution:
By declaring the cumulative total double, no casting is required.
Because Java knows you want to convert int to double automatically if you assign an int to a declared double. Similary the fact that you want to express a result as double is implied when dividing a double by an int, such as when the average is taken. That avoids a cast also. If you had two ints and you wanted to produce a double you'd need to cast one or more of them, or in cases like a print statement where the compiler can't deduce the optimal type for the parameter, you'd need to explicitly cast to covert an int value to a double.
Not sure what OS you're running this on. The ideal situation would be to make it work on all platforms without requiring people type a magic word to end input (because how tacky). The easiest way to end input is to use the OS-specific end of input (end of file) key combination, and for Linux it's CTRL/D, which is how I explained it in the prompt. On another OS with a different end of input sequence you could just change the prompt. The trickiest would be if it is supposed to be truly portable Java. In that case I'd personally investigate how I could figure out the OS and/or End of File character or key combination on the current OS and modify the prompt to indicate to end input with whatever that is. That would be a bit of and advanced assignment but a very cool result.
Example illustrates use of a named constant to determine the array and is used limit the amount of input (and could be used to limit loop count of for loops accessing the array).
By setting the min and max to very high and low values respectively (notice the LOW value assigned to max and HIGH value assigned to min, those ensure the first legit temp entered will set the min and max and things will go from there).
Temperature Maximum, Minimum, Average and Difference Calculator
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args) {
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temps for up to 1 month of days (end with CTRL/D):");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("High temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}

Java loop required

I'm quite new to coding, as you all can see from the clumsy code below. However, looking at this code you can see what I'm getting at. The code basically does what its supposed to, but I would like to write it as a loop to make it more efficient. Could someone maybe point me in the right direction? I have done some digging and thought about recursion, but I haven't been able to figure out how to apply it here.
public static void main(String[] args) {
double a = 10;
double b = 2;
double c = 3;
double avg = (a + b + c)/3;
double avg1 = (avg + b + c)/3;
double avg2 = (avg1 + b + c)/3;
double avg3 = (avg2 + b + c)/3;
System.out.println(avg+ "\n" + avg1+ "\n"+ avg2 + "\n"+ avg3);
}
Functionally, this would be equivalent to what you have done:
public static void main(String[] args) {
double a = 10;
double b = 2;
double c = 3;
double avg = (a + b + c)/3;
System.out.println(avg);
for (int i=0; i<3; i++) {
avg = (avg + b + c)/3;
System.out.println(avg);
}
}
But also you should know that shorter code does not always mean efficient code. The solution may be more concise, but I doubt there will be any change in performance.
If you mean shorter code with efficieny you can do it like this.
public static void main(String[] args) {
double a = 10;
double b = 2;
double c = 3;
for (int i = 0; i < 4; i++) {
a = (a + b + c) / 3;
System.out.println(a);
}
}
I have no idea what this calculation represents (some sort of specialised weighted average?) but rather than use repetition and loops, you can reach the exact same calculation by using a bit of algebra and refactoring the terms:
public static double directlyCalculateWeightedAverage(double a, double b,
double c) {
return a / 81 + 40 * b / 81 + 40 * c / 81;
}
This reformulation is reached because the factor a appears just once in the mix and is then divided by 34 which is 81. Then each of b and c appear at various levels of division, so that b sums to this:
b/81 + b/27 + b/9 + b/3
== b/81 + 3b/81 + 9b/81 + 27b/81
== 40b/81
and c is treated exactly the same.
Which gives the direct calculation
a/81 + 40b/81 + 40c/81
Assuming your formula does not change, I'd recommend using this direct approach rather than resorting to repeated calculations and loops.
Your problem can be solved by 2 approaches: iterative (with a loop) or recursive (with a recursive function).
Iterative approach : for loop
The for loop allow you to repeat a group of instructions au given number of times.
In your case, you could write the following :
double a = 10, b = 2, c = 3;
double avg = a;
for (int i = 0; i < 4; i++) {
avg = (avg + b + c) / 3;
System.out.println(avg);
}
This will print the 4 first results of your calculation.
In my example, I overwrite the variable avg to only keep the last result, which might not be what you want. To keep the result of each loop iteration, you may store the result in an array.
Recursive approach
In Java, there is no such thing as a standalone function. In order to use recursion, you have to use static methods :
private static double recursiveAvg(double avg, int count) {
// Always check that the condition for your recursion is valid !
if (count == 0) {
return avg;
}
// Apply your formula
avg = (avg + 2 + 3) / 3;
// Call the same function with the new avg value, and decrease the iteration count.
return recursiveAvg(avg, count - 1);
}
public static void main(String[] args) {
// Start from a = 10, and repeat the operation 4 times.
double avg = recursiveAvg(10, 4);
System.out.println(avg);
}
Always check for a condition that will end the recursion. In our example, it's the number of times the operation should be performed.
Note that most programmers prefer the iterative approach : easier to write and read, and less error prone.

How do I accept and output both Doubles and Ints in an Array?

import java.util.Scanner;
public class PeopleWeights {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
final int NUM_VALS = 5;
int [] personsWeight = new int[NUM_VALS];
int i = 0;
for (i = 0; i < NUM_VALS; ++i) {
System.out.print("Enter weight " + (i + 1) + ": ");
System.out.println();
personsWeight[i] = scnr.nextInt();
}
double sumVal = 0.0;
for (i = 0; i < NUM_VALS; ++i) {
sumVal = sumVal + personsWeight[i];
}
double avgVal = 0.0;
for (i = 0; i < NUM_VALS; ++i) {
avgVal = sumVal / NUM_VALS;
}
double maxVal = 0.0;
for (i = 0; i < NUM_VALS; ++i) {
maxVal = personsWeight[0];
if (maxVal < personsWeight[i]) {
maxVal = personsWeight[i];
}
}
System.out.println();
System.out.println(personsWeight[1] + " " + personsWeight[2] + " "
+ personsWeight[3] + " " + personsWeight[4] + " " + personsWeight[5]);
//I know that this can be cleaner but this is where the
//problem occurs with a InputMismatchException.
//I know it's caused by the double being introduced
//but don't know how to fix it.
System.out.println("Total weight: " + sumVal);
System.out.println("Average weight: " + avgVal);
System.out.println("Max weight: " + maxVal);
return;
}
}
The inputs are as follows:
236 ,
89.5 ,
142 ,
166.3 ,
93 .
I want to handle the output numbers just as they are input. Double or Int.
Is there anyway I can make the Array accept both types of numbers in the scanner or would I have to resort another way that it works?
You can determine initially if the inputted number is Double or Integer using hasNextInt() or hasNextDouble() methods of Scanner class.
if (scnr.hasNextInt()) {
int n = scnr.nextInt();
//your code to handle `integer` case
}
else if(scnr.hasNextDouble()) {
double d = scnr.nextDouble();
//your code to handle `double` case
}
FYI, you can also keep everything as double. It will handle both ints and doubles and will execute without any error.
An array can define only one type, you can define double there, like double [] personsWeight = new double[NUM_VALS]; and when you input an int type, like 236, it will be accepted as a double into Array, output as double too.
The simplest way I can think to solve this is to take in String objects from the Scanner and then convert them to their actual type (you can detect that it's a double if the String contains a period) when you need to use their value for any calculation.
When you have a list of numbers that all represent the same kind of value (such as weight, money amount, test score, etc.), pick one type that's appropriate for all the values that you'd want to handle. For weight, assuming you want to handle non-integers, choose a floating-point type (i.e. double). For money, you might choose BigDecimal; for test scores, you might choose int unless you expect someone might get half a point deducted for something, then you'd choose double. The point is, there is almost never a reason to keep different numeric types for the same kind of value.
There is almost never a reason to care about what format the input is in--i.e. do you really care whether a weight in the input has a decimal point or not? No, you only care about the value itself. This confuses some newer programmers--they equate the value of the number with its representation as a string. But almost always, only the value matters. There's no difference between the numbers 236, 236.0, 236.00000, 2.36e2, and 0xec--the value is the same, and the representation doesn't matter. [Yes, I know that if you use these different forms in your Java program, some will be treated as int and some as double, which could make a difference. But the numbers here are in the input file, not in the code.]
So just make the weight a double and don't worry about integers.
double[] personsWeight = new double[NUM_VALS];
int i = 0;
for (i = 0; i < NUM_VALS; ++i) {
System.out.print("Enter weight " + (i + 1) + ": ");
System.out.println();
personsWeight[i] = scnr.nextDouble();
}

Averaging multiple results of a method?

So, I have a method that is looping through and returning these numbers automatically :
6527.6 6755.6 7009.9 7384.7 7775.9 8170.7 8382.6 8598.8 8867.6 9208.2 9531.8 9821.7 10041.6 10007.2 9847.0 10036.3 10263.5 10449.7 10699.7
I would like to average the first number to the second number, the second to the third number, and so on. What ways should I go about doing this? Adding all these doubles to an array? Or is there a way to get a running total in order to do this?
The problem I'm having is that I can only seem to get all or none of these doubles, not specific ones.
So the output would be the results of something like (6527.6+6755.6)/2, (6755.6+7009.9)/2, and so on. Just printing them, nothing else.
Edit : Code from the parser here : http://pastebin.com/V6yvntcP
What you are describing is known as moving average.
Some formal explanation is here:
http://en.wikipedia.org/wiki/Moving_average
[...] simple moving average (SMA) is the unweighted mean of the previous n data [...]
You want to compute moving average for n = 2.
Below is simple code that do this:
public static void main(String[] args) {
List<Double> list = Arrays.asList(6527.6, 6755.6, 7009.9, 7384.7, 7775.9, 8170.7);
for (int i = 1; i < list.size(); i++) {
double avg = (list.get(i) + list.get(i - 1)) / 2;
System.out.println("avg(" + (i - 1) + "," + i + ") = " + avg);
}
}
And second approach without List or array:
Double prev = null;
// inside loop:
double curr = getMethodResult(...);
if (prev != null) {
double avg = (curr + prev) / 2;
}
prev = curr;
// end of loop
Create and array of double and just do some traversing and swapping and its done. Check it out:
double[] array = { 6527.6, 6755.6, 7009.9, 7384.7, 7775.9, 8170.7 };
double avg = 0;
double sum = 0.0;
double temp = 6527.6;
for (int i = 0; i < array.length - 1; i++) {
sum = temp + array[i + 1];
avg = sum / 2;
System.out.println("(" + temp + "+" + array[i + 1] + ")/2" + "= "
+ avg);
temp = avg;
}

Algorithm to find all possible values of A^5 + B^5 + C^5?

im trying to write an algorithm that will find all the possible values of A^5 + B^5 + C^5 when the user inputs a number 'N'.
For example if N=100 I want to make an array that contains all the possible values where each slot in the array contains a number that was found by plugging in numbers between 1-100 for A^5 + B^5 + C^5. So one of the positions in the array contains 1 from (1^5 + 1^5 + 1^5). Another position in the array contains
the number 355447518 (from 19^5 + 43^5 + 46^5). So there will be 100^3 elements in my array.
public long[] possibleValues(int n)
{
long[] solutionSet = new long[(int) Math.pow(n, 3)];
for(int i=1;i<=n;i++)
{
solutionSet[i] = ((long) Math.pow(i, 5) + (long) Math.pow(i, 5) + (long) Math.pow(i, 5));
//testing purposes
System.out.println(i +"^5 " + "+" + i+"^5 " + "+" + i+"^5" + "=" + solutionSet[i]);
}
return solutionSet;
}
thats what I have so far, but my problem is that it doesn't do all the permutations of N. What is the best way to get all possible permutations of N? Am i making this more complicated than necessary? How would I arrange all possible (A, B, C)'s ?
Use nested forloops:
index=0;
for (int i=1;i<=n;i++){
for (int j=1;i<=n;j++){
for (int k=1;i<=n;k++){
solutionSet[index++] = ((long) Math.pow(i, 5) + (long) Math.pow(j, 5) + (long) Math.pow(k, 5));
}
}
}
You can calculate all powers quicker by using an array containing all fifth powers up to N.
You're using i for all 3 terms, thus you're essentially calculating permutations of
A^5 + A^5 + A^5 = 3A^5.
You need a 3-dimensional array and 3 for loops.
public long[][][] possibleValues(int n)
{
long[][][] solutionSet = new long[n+1][n+1][n+1];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
{
solutionSet[i][j][k] = ((long) Math.pow(i, 5) + (long) Math.pow(j, 5) + (long) Math.pow(k, 5));
//testing purposes
System.out.println(i +"^5 " + "+" + j+"^5 " + "+" + k+"^5" + "=" + solutionSet[i][j][k]);
}
return solutionSet;
}
If you indeed only want a 1-dimensional array, you'll do something similar to the above, just have a separate variable for the index:
Since you probably don't want excessive repetition of values, you can probably start j from i and k from j.
public long[] possibleValues(int n)
{
long[] solutionSet = new long[n*n*n];
int c = 0;
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
for(int k = j; k <= n; k++)
{
solutionSet[c] = ((long) Math.pow(i, 5) + (long) Math.pow(j, 5) + (long) Math.pow(k, 5));
//testing purposes
System.out.println(i +"^5 " + "+" + j+"^5 " + "+" + k+"^5" + "=" + solutionSet[c]);
c++;
}
return solutionSet;
}
Some significant optimizations can still be done:
Math.pow isn't particularly efficient, as Peter mentioned.
For the first version, you can derive values from previous values in certain circumstances.
The really brute-force way to do it would require three nested loops:
for(int a = 1; a <= n; ++a)
{
for(int b = 1; b <= n; ++b)
{
for(int c = 1; c <= n; ++c)
{
// Add this combination to your array, and print it out.
// It may be more convenient to use ArrayList instead of long[].
}
}
}
Note that for this takes O(n^3) time, so n doesn't have to be very large before it will take forever to compute (and also use up all of your memory).
Use three loops. One each for A, B, C. This is a pseudo code and does not adhere to java syntax
for(int A:100){
for(int B:100){
for(int C:100) {
calculate A^5 * B^5 * C^5
}
}
}
I agree with the other answers about nested forloops. For better performance it may be profitable to store the answers in a hash table so that you don't recalculate the same value. For instance, you calculate 15^5 then you store that answer in an array like ans['155'] = 759375. So when you go to calculate 15^5 again you can do an if statement if(ans[num.tostring+'5']) then use that value instead of calculating 15^5 again.
Starting from #Dukeling previous answer:
I use a powers array to compute the powers just n times (not n*n*n)
public static void test(int n){
long[] powers = new long[n+1];
for (int i=0; i<powers.length; i++)
powers[i] = (long) Math.pow(i, 5);
long[][][] solutionSet = new long[n+1][n+1][n+1];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
{
solutionSet[i][j][k] = ((long) powers[i] + (long) powers[i] + (long) powers[i]);
//testing purposes
System.out.println(i +"^5 " + "+" + j+"^5 " + "+" + k+"^5" + "=" + solutionSet[i][j][k]);
}
}
I believe you are looking for a combination and not a permutation. It also seems that you want A, B, and C to be all possible values from 1 to N. In that case, you'll want to make your nested for loop as such to only calculate the combinations:
for (int a = 0; a < n; a++) {
for (int b = 0; b <= a; b++) {
for (int c = 0; c <= b; c++) {
pow5(a) + pow5(b) + pow5(c);
}
}
}
You'll also want to use a lookup table which could be loaded from a file. The more values in your lookup table, the faster your algorithm will perform. In my opinion, the best method will reduce the number of operations required. That means not calculating every value at runtime. Alternatively, you could also optimize for memory usage and just use a simple algorithm. Additionally, you'll want to measure the performance of the algorithm. Here is an example.
// for all number > 0 and <= 25
public static final double[] powersOf5 = {1.0, 32.0, 243.0, 1024.0, 3125.0,
7776.0, 16807.0, 32768.0, 59049.0, 100000.0, 161051.0, 248832.0, 371293.0,
537824.0, 759375.0, 1048576.0, 1419857.0, 1889568.0, 2476099.0, 3200000.0,
4084101.0, 5153632.0, 6436343.0, 7962624.0, 9765625.0};
// calc pow(i, 5) and use a lookup table for small values i
public static double pow5(int i) {
if (i > 0 && i <= 25) {
return powersOf5[i-1];
} else {
return Math.pow(i, 5);
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
System.out.println(pow5(i));
}
long end = System.currentTimeMillis();
System.out.println("Execution time: " + (end - start) + " ms");
}
have a think at first
1. 1^5 + 2^5 + 3^5 = 3^5 + 2^5 +1^5 , So i<j<k
for(i=0;i<N;i++)
for(j=i;j<N;j++)
for(k=j;k<N;k++)
2. A^5+B^5+C^5=D^5+E^5+F^5
If we use array , there may be lots of same value in it.
we can use Set to save memory, if time is not the most important.
3. A^5 cannot be saved by Long type, when A is too big.
So, do we make sure N is little? otherwise, there may be a bug.
4. Multiplication cost lots of time.
Give a example, if N=100, to get all result, how many times does it spend
calc 5^5.
5^5+1^5+1^5
5^5+1^5+2^5
5^5+1^5+3^5
...
How about if there is an array save the answer
define array[i] = i^5
Then it save our time;
Just think more, Algorithm is something that like this
Now let's talk more about Math.pow();
Yes it's a good method that help you, but this is an algorithm which is impl, we just want to know A^5, not A^N, the second parameter is static;
Why not impl a method by yourself.
First, we try to impl a method like this
public Long powOf5(Long A){
return A*A*A*A*A;
}
Then, we find we can optimize it.
public Long powOf5(Long A){
Long A2 = A*A;
return A2*A2*A;
}
This multiply 3 times, that multiply 4 times;
I am sure this method is faster than Math.pow()

Categories

Resources