0

how can I make sqrt(-x) example: sqrt(-1.5) work, so I don't receive a NaN? Tried to find the answer and now I understand how it works but still don't know how to do it properly. Thanks!

Context: exercise 67 (Variance) to calculate the sample variance. I base my code on example: (The average of the numbers is 3.5, so the sample variance is ((3 - 3.5)² + (2 - 3.5)² + (7 - 3.5)² + (2 - 3.5)²)/(4 - 1) ? 5,666667.)

import java.util.ArrayList;

import static java.lang.StrictMath.sqrt;

public static int sum(ArrayList<Integer> list) {
    int sum = 0;

    for (int item : list) {
        sum+= item;
    }
    return sum;
}

//average from exercise 64
public static double average(ArrayList<Integer> list) {
    return (double) sum(list) / list.size();
}

public static double variance(ArrayList<Integer> list) {

    // write code here
    double variance = 0;
    int i = 0;
    while (i < list.size()) {
        variance = (sqrt(list.get(i) - average(list)));
        i++;

    }
    return variance / 4-1;


    // ... / n-1 for Bessel's correction
}

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(3);
    list.add(2);
    list.add(7);
    list.add(2);

    System.out.println("The variance is: " + variance(list));

}
  • 4
    sqrt - square root, what you want is power (`Math.pow`) of 2 – Iłya Bursov Feb 02 '19 at 16:08
  • 2
    You can't. You need a square root function that returns a complex number. The standard function only deals with real values. How does a sum of squares ever generate a negative number? Squares are, by definition, positive definite. – duffymo Feb 02 '19 at 16:11

1 Answers1

1

This line is incorrect:

variance = (sqrt(list.get(i) - average(list)));

Your variance method has some serious problems beyond this mistake.

The variance is the square root of the sum of squares. You should sum inside the loop and take the square root of the sum outside of it.

Here's how I'd do it:

/**
 * Created by Michael
 * Creation date 2/2/2019.
 * @link https://stackoverflow.com/questions/54494823/how-can-i-handle-nan-with-sqrt-x/54494917#54494917
 */
public class Exercise64 {

    public static void main(String[] args) {
        int [] data = { 3, 2, 7, 2 };
        System.out.println(String.format("average  : %10.4f", average(data)));
        System.out.println(String.format("variance : %10.4f", variance(data)));
        System.out.println(String.format("sqrt(var): %10.4f", Math.sqrt(variance(data)/(data.length-1))));
    }

    public static double average(int [] data) {
        double average = 0.0;
        if ((data != null) && (data.length > 0)) {
            for (int x : data) {
                average += x;
            }
            average /= data.length;
        }
        return average;
    }

    public static double variance(int [] data) {
        double variance = 0.0;
        if ((data != null) && (data.length > 1)) {
            double average = average(data);
            for (int x : data) {
                double diff = x-average;
                variance += diff*diff;
            }
        }
        return variance;
    }
}

Here's my output:

average  :     3.5000
variance :    17.0000
sqrt(var):     2.3805

Process finished with exit code 0
duffymo
  • 305,152
  • 44
  • 369
  • 561