diff --git a/analysis/pom.xml b/analysis/pom.xml new file mode 100644 index 0000000..95cf638 --- /dev/null +++ b/analysis/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + + net.laprun.sustainability + power-server-parent + 0.0.12-SNAPSHOT + + + power-server-analysis + power-server : analysis + Classes that support analysis of recorded data + + + + net.laprun.sustainability + power-server-measure + ${project.version} + + + org.apache.commons + commons-math3 + 3.6.1 + + + org.hdrhistogram + HdrHistogram + 2.2.2 + + + + + + + + net.revelc.code.formatter + formatter-maven-plugin + + + net.laprun.sustainability + build-tools + 0.0.12-SNAPSHOT + + + + + + + + diff --git a/analysis/src/main/java/net/laprun/sustainability/power/analysis/Compute.java b/analysis/src/main/java/net/laprun/sustainability/power/analysis/Compute.java new file mode 100644 index 0000000..65b8115 --- /dev/null +++ b/analysis/src/main/java/net/laprun/sustainability/power/analysis/Compute.java @@ -0,0 +1,35 @@ +package net.laprun.sustainability.power.analysis; + +import org.apache.commons.math3.util.FastMath; + +import net.laprun.sustainability.power.measure.PowerMeasure; + +public enum Compute { + ; + + public static double standardDeviation(PowerMeasure measure, int componentIndex) { + return measure.getMeasuresFor(componentIndex).map(values -> { + final var samples = values.length; + if (samples <= 1) { + return 0.0; + } + final double mean = average(measure, componentIndex); + double geometricDeviationTotal = 0.0; + for (double value : values) { + double deviation = value - mean; + geometricDeviationTotal += (deviation * deviation); + } + return FastMath.sqrt(geometricDeviationTotal / (samples - 1)); + }).orElse(0.0); + } + + public static double average(PowerMeasure measure, int componentIndex) { + return measure.getMeasuresFor(componentIndex).map(values -> { + double sum = 0.0; + for (double value : values) { + sum += value; + } + return sum / values.length; + }).orElse(0.0); + } +} diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/DescriptiveStatisticsAnalyzer.java b/analysis/src/main/java/net/laprun/sustainability/power/analysis/DescriptiveStatisticsComponentProcessor.java similarity index 64% rename from measure/src/main/java/net/laprun/sustainability/power/measure/DescriptiveStatisticsAnalyzer.java rename to analysis/src/main/java/net/laprun/sustainability/power/analysis/DescriptiveStatisticsComponentProcessor.java index 56fb7ea..bd96a83 100644 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/DescriptiveStatisticsAnalyzer.java +++ b/analysis/src/main/java/net/laprun/sustainability/power/analysis/DescriptiveStatisticsComponentProcessor.java @@ -1,12 +1,12 @@ -package net.laprun.sustainability.power.measure; +package net.laprun.sustainability.power.analysis; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; @SuppressWarnings("unused") -public class DescriptiveStatisticsAnalyzer implements Analyzer { +public class DescriptiveStatisticsComponentProcessor implements ComponentProcessor { private final DescriptiveStatistics statistics; - public DescriptiveStatisticsAnalyzer() { + public DescriptiveStatisticsComponentProcessor() { statistics = new DescriptiveStatistics(); } diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/HdrHistogramAnalyzer.java b/analysis/src/main/java/net/laprun/sustainability/power/analysis/HdrHistogramComponentProcessor.java similarity index 77% rename from measure/src/main/java/net/laprun/sustainability/power/measure/HdrHistogramAnalyzer.java rename to analysis/src/main/java/net/laprun/sustainability/power/analysis/HdrHistogramComponentProcessor.java index 402e2f2..1de6436 100644 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/HdrHistogramAnalyzer.java +++ b/analysis/src/main/java/net/laprun/sustainability/power/analysis/HdrHistogramComponentProcessor.java @@ -1,15 +1,15 @@ -package net.laprun.sustainability.power.measure; +package net.laprun.sustainability.power.analysis; import org.HdrHistogram.IntCountsHistogram; @SuppressWarnings("unused") -public class HdrHistogramAnalyzer implements Analyzer { +public class HdrHistogramComponentProcessor implements ComponentProcessor { private static final int HIGHEST_TRACKABLE_VALUE = 1_000_000; private static final int NUMBER_OF_SIGNIFICANT_VALUE_DIGITS = 4; private static final int CONVERSION_FACTOR = 1000; private final IntCountsHistogram histogram; - public HdrHistogramAnalyzer() { + public HdrHistogramComponentProcessor() { histogram = new IntCountsHistogram(HIGHEST_TRACKABLE_VALUE, NUMBER_OF_SIGNIFICANT_VALUE_DIGITS); } diff --git a/analysis/src/main/java/net/laprun/sustainability/power/analysis/MeanComponentProcessor.java b/analysis/src/main/java/net/laprun/sustainability/power/analysis/MeanComponentProcessor.java new file mode 100644 index 0000000..ecaf70e --- /dev/null +++ b/analysis/src/main/java/net/laprun/sustainability/power/analysis/MeanComponentProcessor.java @@ -0,0 +1,13 @@ +package net.laprun.sustainability.power.analysis; + +public class MeanComponentProcessor implements ComponentProcessor { + private double mean; + private int count; + + @Override + public void recordComponentValue(double value, long timestamp) { + final var previousSize = count; + count++; + mean = mean == 0 ? value : (previousSize * mean + value) / count; + } +} diff --git a/analysis/src/test/java/ComputeTest.java b/analysis/src/test/java/ComputeTest.java new file mode 100644 index 0000000..d751526 --- /dev/null +++ b/analysis/src/test/java/ComputeTest.java @@ -0,0 +1,110 @@ +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Map; +import java.util.Random; +import java.util.random.RandomGenerator; + +import org.junit.jupiter.api.Test; + +import net.laprun.sustainability.power.SensorMetadata; +import net.laprun.sustainability.power.analysis.Compute; +import net.laprun.sustainability.power.measure.OngoingPowerMeasure; + +public class ComputeTest { + private final static SensorMetadata metadata = new SensorMetadata(Map.of(), null, new int[0]) { + + @Override + public int componentCardinality() { + return 3; + } + }; + + @Test + void standardDeviationShouldWork() { + final var random = Random.from(RandomGenerator.getDefault()); + final var m1c1 = random.nextDouble(); + final var m1c2 = random.nextDouble(); + final var m1c3 = 0.0; + final var m2c1 = random.nextDouble(); + final var m2c2 = random.nextDouble(); + final var m2c3 = 0.0; + final var m3c1 = random.nextDouble(); + final var m3c2 = random.nextDouble(); + final var m3c3 = 0.0; + + final var measure = new OngoingPowerMeasure(metadata); + + final var components = new double[metadata.componentCardinality()]; + components[0] = m1c1; + components[1] = m1c2; + components[2] = m1c3; + measure.recordMeasure(components); + + components[0] = m2c1; + components[1] = m2c2; + components[2] = m2c3; + measure.recordMeasure(components); + + components[0] = m3c1; + components[1] = m3c2; + components[2] = m3c3; + measure.recordMeasure(components); + + final var c1Avg = Compute.average(measure, 0); + final var c2Avg = Compute.average(measure, 1); + final var stdVarForC1 = Math + .sqrt((Math.pow(m1c1 - c1Avg, 2) + Math.pow(m2c1 - c1Avg, 2) + Math.pow(m3c1 - c1Avg, 2)) / (3 - 1)); + final var stdVarForC2 = Math + .sqrt((Math.pow(m1c2 - c2Avg, 2) + Math.pow(m2c2 - c2Avg, 2) + Math.pow(m3c2 - c2Avg, 2)) / (3 - 1)); + + assertEquals(stdVarForC1, Compute.standardDeviation(measure, 0), 0.0001, + "Standard Deviation did not match the expected value"); + assertEquals(stdVarForC2, Compute.standardDeviation(measure, 1), 0.0001, + "Standard Deviation did not match the expected value"); + assertEquals(0, Compute.standardDeviation(measure, 2), 0.0001, + "Standard Deviation did not match the expected value"); + } + + @Test + void averageShouldWork() { + final var random = Random.from(RandomGenerator.getDefault()); + final var m1c1 = random.nextDouble(); + final var m1c2 = random.nextDouble(); + final var m1c3 = 0.0; + final var m2c1 = random.nextDouble(); + final var m2c2 = random.nextDouble(); + final var m2c3 = 0.0; + final var m3c1 = random.nextDouble(); + final var m3c2 = random.nextDouble(); + final var m3c3 = 0.0; + + final var measure = new OngoingPowerMeasure(metadata); + + final var components = new double[metadata.componentCardinality()]; + components[0] = m1c1; + components[1] = m1c2; + components[2] = m1c3; + measure.recordMeasure(components); + + components[0] = m2c1; + components[1] = m2c2; + components[2] = m2c3; + measure.recordMeasure(components); + + components[0] = m3c1; + components[1] = m3c2; + components[2] = m3c3; + measure.recordMeasure(components); + + final var c1Avg = Compute.average(measure, 0); + final var c2Avg = Compute.average(measure, 1); + final var c3Avg = Compute.average(measure, 2); + + assertEquals((m1c1 + m2c1 + m3c1) / 3, c1Avg, 0.0001, + "Average did not match the expected value"); + assertEquals((m1c2 + m2c2 + m3c2) / 3, c2Avg, 0.0001, + "Average did not match the expected value"); + assertEquals(0, c3Avg, 0.0001, + "Average did not match the expected value"); + } +} diff --git a/measure/pom.xml b/measure/pom.xml index 133eb9e..72b6248 100644 --- a/measure/pom.xml +++ b/measure/pom.xml @@ -19,14 +19,10 @@ ${project.version} - org.apache.commons - commons-math3 - 3.6.1 - - - org.hdrhistogram - HdrHistogram - 2.2.2 + org.assertj + assertj-core + 3.26.3 + test diff --git a/measure/src/main/java/net/laprun/sustainability/power/analysis/Analyzers.java b/measure/src/main/java/net/laprun/sustainability/power/analysis/Analyzers.java new file mode 100644 index 0000000..b0eed83 --- /dev/null +++ b/measure/src/main/java/net/laprun/sustainability/power/analysis/Analyzers.java @@ -0,0 +1,4 @@ +package net.laprun.sustainability.power.analysis; + +public interface Analyzers { +} diff --git a/measure/src/main/java/net/laprun/sustainability/power/analysis/ComponentProcessor.java b/measure/src/main/java/net/laprun/sustainability/power/analysis/ComponentProcessor.java new file mode 100644 index 0000000..00beaac --- /dev/null +++ b/measure/src/main/java/net/laprun/sustainability/power/analysis/ComponentProcessor.java @@ -0,0 +1,6 @@ +package net.laprun.sustainability.power.analysis; + +public interface ComponentProcessor { + default void recordComponentValue(double value, long timestamp) { + } +} diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/Analyzer.java b/measure/src/main/java/net/laprun/sustainability/power/measure/Analyzer.java deleted file mode 100644 index fb7f63e..0000000 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/Analyzer.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.laprun.sustainability.power.measure; - -public interface Analyzer { - void recordComponentValue(double value, long timestamp); -} diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/Compute.java b/measure/src/main/java/net/laprun/sustainability/power/measure/Compute.java new file mode 100644 index 0000000..c89d11a --- /dev/null +++ b/measure/src/main/java/net/laprun/sustainability/power/measure/Compute.java @@ -0,0 +1,24 @@ +package net.laprun.sustainability.power.measure; + +public enum Compute { + ; + + public static double sumOfComponents(double[] recorded) { + var componentSum = 0.0; + for (double value : recorded) { + componentSum += value; + } + return componentSum; + } + + public static double sumOfSelectedComponents(double[] recorded, int... indices) { + if (indices == null || indices.length == 0) { + return sumOfComponents(recorded); + } + var componentSum = 0.0; + for (int index : indices) { + componentSum += recorded[index]; + } + return componentSum; + } +} diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/OngoingPowerMeasure.java b/measure/src/main/java/net/laprun/sustainability/power/measure/OngoingPowerMeasure.java index d5ba159..a59386e 100644 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/OngoingPowerMeasure.java +++ b/measure/src/main/java/net/laprun/sustainability/power/measure/OngoingPowerMeasure.java @@ -3,16 +3,15 @@ import java.time.Duration; import java.util.BitSet; import java.util.Objects; - -import org.apache.commons.math3.util.FastMath; +import java.util.Optional; import net.laprun.sustainability.power.SensorMetadata; +import net.laprun.sustainability.power.analysis.ComponentProcessor; public class OngoingPowerMeasure implements PowerMeasure { private static final int DEFAULT_SIZE = 32; private final SensorMetadata sensorMetadata; private final long startedAt; - private final double[] averages; private final BitSet nonZeroComponents; private final int[] totalComponents; private final int totalIndex; @@ -22,9 +21,9 @@ public class OngoingPowerMeasure implements PowerMeasure { private int samples; private final double[][] measures; private long[] timestamps; - private final Analyzer[] analyzers; + private final ComponentProcessor[] analyzers; - public OngoingPowerMeasure(SensorMetadata sensorMetadata, Analyzer... analyzers) { + public OngoingPowerMeasure(SensorMetadata sensorMetadata, ComponentProcessor... analyzers) { this.sensorMetadata = sensorMetadata; startedAt = System.currentTimeMillis(); @@ -34,11 +33,10 @@ public OngoingPowerMeasure(SensorMetadata sensorMetadata, Analyzer... analyzers) measures = new double[measuresNb][DEFAULT_SIZE]; timestamps = new long[DEFAULT_SIZE]; totalIndex = numComponents; - averages = new double[measuresNb]; // we don't need to record the total component as a non-zero component since it's almost never zero and we compute the std dev separately nonZeroComponents = new BitSet(numComponents); totalComponents = sensorMetadata.totalComponents(); - this.analyzers = Objects.requireNonNullElseGet(analyzers, () -> new Analyzer[0]); + this.analyzers = Objects.requireNonNullElseGet(analyzers, () -> new ComponentProcessor[0]); } @Override @@ -61,16 +59,12 @@ public void recordMeasure(double[] components) { nonZeroComponents.set(component); } recordComponentValue(component, componentValue); - averages[component] = averages[component] == 0 ? componentValue - : (previousSize * averages[component] + componentValue) / samples; } // record min / max totals - final var recordedTotal = PowerMeasure.sumOfSelectedComponents(components, totalComponents); + final var recordedTotal = Compute.sumOfSelectedComponents(components, totalComponents); recordComponentValue(totalIndex, recordedTotal); accumulatedTotal += recordedTotal; - averages[components.length] = averages[components.length] == 0 ? recordedTotal - : (previousSize * averages[components.length] + recordedTotal) / samples; if (recordedTotal < minTotal) { minTotal = recordedTotal; } @@ -120,44 +114,18 @@ public double maxMeasuredTotal() { } @Override - public double[] averagesPerComponent() { - return averages; - } - - public StdDev standardDeviations() { - final var cardinality = sensorMetadata.componentCardinality(); - final var stdDevs = new double[cardinality]; - nonZeroComponents.stream() - .parallel() - .forEach(component -> stdDevs[component] = standardDeviation(component)); - - final double aggregate = maxTotal == 0 ? 0 : standardDeviation(totalIndex); - return new StdDev(aggregate, stdDevs); - } - - private double standardDeviation(int component) { - final var values = measures[component]; - if (samples <= 1) { - return 0.0; - } - final double mean = averages[component]; - double geometricDeviationTotal = 0.0; - for (int index = 0; index < samples; index++) { - double deviation = values[index] - mean; - geometricDeviationTotal += (deviation * deviation); + public Optional getMeasuresFor(int component) { + if (nonZeroComponents.get(component)) { + final var dest = new double[samples]; + System.arraycopy(measures[component], 0, dest, 0, samples); + return Optional.of(dest); + } else { + return Optional.empty(); } - return FastMath.sqrt(geometricDeviationTotal / (samples - 1)); - } - - @Override - public double[] getMeasuresFor(int component) { - final var dest = new double[samples]; - System.arraycopy(measures[component], 0, dest, 0, samples); - return dest; } @Override - public Analyzer[] analyzers() { + public ComponentProcessor[] analyzers() { return analyzers; } } diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/PowerMeasure.java b/measure/src/main/java/net/laprun/sustainability/power/measure/PowerMeasure.java index eea3d70..5ffe3ee 100644 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/PowerMeasure.java +++ b/measure/src/main/java/net/laprun/sustainability/power/measure/PowerMeasure.java @@ -1,37 +1,20 @@ package net.laprun.sustainability.power.measure; import java.time.Duration; +import java.util.Optional; import net.laprun.sustainability.power.SensorMetadata; +import net.laprun.sustainability.power.analysis.ComponentProcessor; public interface PowerMeasure { - private static double sumOfComponents(double[] recorded) { - var componentSum = 0.0; - for (double value : recorded) { - componentSum += value; - } - return componentSum; - } - - static double sumOfSelectedComponents(double[] recorded, int... indices) { - if (indices == null || indices.length == 0) { - return sumOfComponents(recorded); - } - var componentSum = 0.0; - for (int index : indices) { - componentSum += recorded[index]; - } - return componentSum; - } @SuppressWarnings("unused") static String asString(PowerMeasure measure) { final var durationInSeconds = measure.duration().getSeconds(); final var samples = measure.numberOfSamples(); final var measuredMilliWatts = measure.total(); - final var stdDevs = measure.standardDeviations(); - return String.format("%s / avg: %s / std dev: %.3f [min: %.3f, max: %.3f] (%ds, %s samples)", - readableWithUnit(measuredMilliWatts), readableWithUnit(measure.average()), stdDevs.aggregate, + return String.format("%s [min: %.3f, max: %.3f] (%ds, %s samples)", + readableWithUnit(measuredMilliWatts), measure.minMeasuredTotal(), measure.maxMeasuredTotal(), durationInSeconds, samples); } @@ -45,33 +28,15 @@ static String readableWithUnit(double milliWatts) { Duration duration(); - default double average() { - return total() / numberOfSamples(); - } - double total(); SensorMetadata metadata(); - double[] averagesPerComponent(); - double minMeasuredTotal(); double maxMeasuredTotal(); - StdDev standardDeviations(); - - double[] getMeasuresFor(int component); + Optional getMeasuresFor(int component); - Analyzer[] analyzers(); - - /** - * Records the standard deviations for the aggregated energy comsumption value (as returned by {@link #total()}) and - * per component - * - * @param aggregate - * @param perComponent - */ - record StdDev(double aggregate, double[] perComponent) { - } + ComponentProcessor[] analyzers(); } diff --git a/measure/src/main/java/net/laprun/sustainability/power/measure/StoppedPowerMeasure.java b/measure/src/main/java/net/laprun/sustainability/power/measure/StoppedPowerMeasure.java index 0682840..82a7728 100644 --- a/measure/src/main/java/net/laprun/sustainability/power/measure/StoppedPowerMeasure.java +++ b/measure/src/main/java/net/laprun/sustainability/power/measure/StoppedPowerMeasure.java @@ -1,8 +1,10 @@ package net.laprun.sustainability.power.measure; import java.time.Duration; +import java.util.Optional; import net.laprun.sustainability.power.SensorMetadata; +import net.laprun.sustainability.power.analysis.ComponentProcessor; @SuppressWarnings("unused") public class StoppedPowerMeasure implements PowerMeasure { @@ -12,10 +14,8 @@ public class StoppedPowerMeasure implements PowerMeasure { private final double total; private final double min; private final double max; - private final double[] averages; - private final StdDev standardDeviations; private final double[][] measures; - private final Analyzer[] analyzers; + private final ComponentProcessor[] processors; public StoppedPowerMeasure(PowerMeasure powerMeasure) { this.sensorMetadata = powerMeasure.metadata(); @@ -23,15 +23,13 @@ public StoppedPowerMeasure(PowerMeasure powerMeasure) { this.total = powerMeasure.total(); this.min = powerMeasure.minMeasuredTotal(); this.max = powerMeasure.maxMeasuredTotal(); - this.averages = powerMeasure.averagesPerComponent(); - this.standardDeviations = powerMeasure.standardDeviations(); this.samples = powerMeasure.numberOfSamples(); final var cardinality = metadata().componentCardinality(); measures = new double[cardinality][samples]; for (int i = 0; i < cardinality; i++) { - measures[i] = powerMeasure.getMeasuresFor(i); + measures[i] = powerMeasure.getMeasuresFor(i).orElse(null); } - analyzers = powerMeasure.analyzers(); + processors = powerMeasure.analyzers(); } @Override @@ -54,11 +52,6 @@ public double total() { return total; } - @Override - public double[] averagesPerComponent() { - return averages; - } - @Override public int numberOfSamples() { return samples; @@ -70,17 +63,12 @@ public SensorMetadata metadata() { } @Override - public StdDev standardDeviations() { - return standardDeviations; - } - - @Override - public double[] getMeasuresFor(int component) { - return measures[component]; + public Optional getMeasuresFor(int component) { + return Optional.ofNullable(measures[component]); } @Override - public Analyzer[] analyzers() { - return analyzers; + public ComponentProcessor[] analyzers() { + return processors; } } diff --git a/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java b/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java index 039426f..8369e8f 100644 --- a/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java +++ b/measure/src/test/java/net/laprun/sustainability/power/measure/OngoingPowerMeasureTest.java @@ -1,6 +1,6 @@ package net.laprun.sustainability.power.measure; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Map; @@ -20,7 +20,7 @@ public int componentCardinality() { }; @Test - void testStatistics() { + void testBasics() { final var m1c1 = 10.0; final var m1c2 = 12.0; final var m1c3 = 0.0; @@ -52,31 +52,12 @@ void testStatistics() { components[2] = m3c3; measure.recordMeasure(components); - assertArrayEquals(new double[] { m1c1, m2c1, m3c1 }, measure.getMeasuresFor(0)); - assertArrayEquals(new double[] { m1c2, m2c2, m3c2 }, measure.getMeasuresFor(1)); - assertArrayEquals(new double[] { m1c3, m2c3, m3c3 }, measure.getMeasuresFor(2)); + assertThat(measure.getMeasuresFor(0)).hasValue(new double[] { m1c1, m2c1, m3c1 }); + assertThat(measure.getMeasuresFor(1)).hasValue(new double[] { m1c2, m2c2, m3c2 }); + assertThat(measure.getMeasuresFor(2)).isEmpty(); assertEquals(m1c1 + m1c2 + m1c3 + m2c1 + m2c2 + m2c3 + m3c1 + m3c2 + m3c3, measure.total()); - assertEquals((m1c1 + m1c2 + m1c3 + m2c1 + m2c2 + m2c3 + m3c1 + m3c2 + m3c3) / 3, measure.average()); assertEquals(Stream.of(m1total, m2total, m3total).min(Double::compareTo).orElseThrow(), measure.minMeasuredTotal()); assertEquals(Stream.of(m1total, m2total, m3total).max(Double::compareTo).orElseThrow(), measure.maxMeasuredTotal()); - final var c1Avg = measure.averagesPerComponent()[0]; - final var c2Avg = measure.averagesPerComponent()[1]; - final var c3Avg = measure.averagesPerComponent()[2]; - assertEquals((m1c1 + m2c1 + m3c1) / 3, c1Avg); - assertEquals((m1c2 + m2c2 + m3c2) / 3, c2Avg); - assertEquals(0, c3Avg); - - final var stdVarForC1 = Math - .sqrt((Math.pow(m1c1 - c1Avg, 2) + Math.pow(m2c1 - c1Avg, 2) + Math.pow(m3c1 - c1Avg, 2)) / (3 - 1)); - final var stdVarForC2 = Math - .sqrt((Math.pow(m1c2 - c2Avg, 2) + Math.pow(m2c2 - c2Avg, 2) + Math.pow(m3c2 - c2Avg, 2)) / (3 - 1)); - - assertEquals(stdVarForC1, measure.standardDeviations().perComponent()[0], 0.0001, - "Standard Deviation did not match the expected value"); - assertEquals(stdVarForC2, measure.standardDeviations().perComponent()[1], 0.0001, - "Standard Deviation did not match the expected value"); - assertEquals(0, measure.standardDeviations().perComponent()[2], 0.0001, - "Standard Deviation did not match the expected value"); } } diff --git a/pom.xml b/pom.xml index c07cc70..b58b5d2 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,7 @@ metadata measure server + analysis