name:
src/main/java/io/protobase/f7/formulas/statistical/STDEV.java
-rw-r--r--
1611
1package io.protobase.f7.formulas.statistical;
2
3import io.protobase.f7.errors.DivException;
4import io.protobase.f7.formulas.AbstractFormula;
5import io.protobase.f7.formulas.FormulaName;
6import io.protobase.f7.models.GridColumnRowKey;
7import io.protobase.f7.utils.Converters;
8import io.protobase.f7.utils.Mappers;
9
10import java.util.Arrays;
11import java.util.List;
12import java.util.function.BiFunction;
13import java.util.function.Function;
14import java.util.stream.Collectors;
15
16public class STDEV extends AbstractFormula {
17 public static FormulaName NAME = FormulaName.STDEV;
18 public static STDEV SELF = new STDEV();
19
20 public STDEV() {
21 super();
22 }
23
24 public STDEV(Function<Object, Object> lookup, BiFunction<GridColumnRowKey, Object, Object> collateralLookup) {
25 super(lookup, collateralLookup);
26 }
27
28 @Override
29 public Object internal(GridColumnRowKey origin, Object... values) {
30 checkAtLeastLength(values.length, 1, NAME);
31 List<Double> numbers = Arrays.stream(values)
32 .map(lookup)
33 .flatMap(Mappers::toFlatStreamGridFilterOnlyNumberLiterals)
34 .map(Converters::toDouble)
35 .collect(Collectors.toList());
36 if (numbers.size() == 1) {
37 return new DivException("Formula STDEV caused an error when attempting to divide by zero.");
38 }
39 double sum = 0.0;
40 double standardDev = 0.0;
41 int length = numbers.size();
42 for (double number : numbers) {
43 sum += number;
44 }
45 double mean = sum / length;
46 for (double number : numbers) {
47 standardDev += Math.pow(number - mean, 2);
48 }
49 return Math.sqrt(standardDev / (length - 1));
50 }
51}