name:
src/main/java/io/protobase/f7/formulas/statistical/AVEDEV.java
-rw-r--r--
1656
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 AVEDEV extends AbstractFormula {
17 public static FormulaName NAME = FormulaName.AVEDEV;
18 public static AVEDEV SELF = new AVEDEV();
19
20 public AVEDEV() {
21 super();
22 }
23
24 public AVEDEV(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() == 0) {
37 return new DivException("Formula AVEDEV caused an error when attempting to divide by zero.");
38 }
39 double sum = 0;
40 for (Double number : numbers) {
41 sum += number;
42 }
43 double mean = sum / numbers.size();
44 for (int i = 0; i < numbers.size(); i++) {
45 numbers.set(i, Math.abs(numbers.get(i) - mean));
46 }
47 double meanSum = 0;
48 for (Double number : numbers) {
49 meanSum += number;
50 }
51 return meanSum / numbers.size();
52 }
53}