diff --git a/pom.xml b/pom.xml
index 70a86c3..c9b6055 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,5 +26,10 @@
1.2.0
test
+
+ org.apache.commons
+ commons-math3
+ 3.6.1
+
\ No newline at end of file
diff --git a/src/main/java/net/berack/upo/valpre/sim/stats/Result.java b/src/main/java/net/berack/upo/valpre/sim/stats/Result.java
index 57d5021..3a61569 100644
--- a/src/main/java/net/berack/upo/valpre/sim/stats/Result.java
+++ b/src/main/java/net/berack/upo/valpre/sim/stats/Result.java
@@ -12,7 +12,7 @@ public class Result {
public final Map nodes;
public final long seed;
public final double simulationTime;
- public final long timeElapsedNano;
+ public final double timeElapsedMS;
/**
* Creates a new result object for the given parameters obtained by the
@@ -20,16 +20,32 @@ public class Result {
*
* @param seed the initial seed used by the simulation
* @param time the final time of the simulation
- * @param elapsed the real time elapsed while running the simulation in ns
+ * @param elapsed the real time elapsed while running the simulation in ms
* @param nodes all the stats collected by the simulation saved per node
*/
- public Result(long seed, double time, long elapsed, Map nodes) {
+ public Result(long seed, double time, double elapsed, Map nodes) {
this.seed = seed;
this.simulationTime = time;
- this.timeElapsedNano = elapsed;
+ this.timeElapsedMS = elapsed;
this.nodes = nodes;
}
+ /**
+ * Get the global information of the simulation. In particular this method build
+ * a string that contains the seed and the time elapsed in the simulation and in
+ * real time
+ */
+ public String getHeader() {
+ var size = (int) Math.ceil(Math.log10(this.simulationTime));
+ var format = "%" + (size + 4) + ".3f";
+ var builder = new StringBuilder();
+ builder.append("===== Net Stats =====\n");
+ builder.append(String.format("Seed: \t%d\n", this.seed));
+ builder.append(String.format("Simulation: \t" + format + "\n", this.simulationTime));
+ builder.append(String.format("Elapsed: \t" + format + "ms\n", this.timeElapsedMS / 1e6));
+ return builder.toString();
+ }
+
/**
* Print a summary of the statistics to the console.
* The summary includes the seed, the simulation time, the elapsed time, and
@@ -56,20 +72,4 @@ public class Result {
}
return table.toString();
}
-
- /**
- * Get the global information of the simulation. In particular this method build
- * a string that contains the seed and the time elapsed in the simulation and in
- * real time
- */
- public String getHeader() {
- var size = (int) Math.ceil(Math.log10(this.simulationTime));
- var format = "%" + (size + 4) + ".3f";
- var builder = new StringBuilder();
- builder.append("===== Net Stats =====\n");
- builder.append(String.format("Seed: \t%d\n", this.seed));
- builder.append(String.format("Simulation: \t" + format + "\n", this.simulationTime));
- builder.append(String.format("Elapsed: \t" + format + "ms\n", this.timeElapsedNano / 1e6));
- return builder.toString();
- }
}
diff --git a/src/main/java/net/berack/upo/valpre/sim/stats/ResultMultiple.java b/src/main/java/net/berack/upo/valpre/sim/stats/ResultMultiple.java
index 45fd9ca..6f5daa6 100644
--- a/src/main/java/net/berack/upo/valpre/sim/stats/ResultMultiple.java
+++ b/src/main/java/net/berack/upo/valpre/sim/stats/ResultMultiple.java
@@ -9,6 +9,8 @@ public class ResultMultiple {
public final Result[] runs;
public final Result average;
public final Result variance;
+ public final Result lowerBound;
+ public final Result upperBound;
/**
* TODO
@@ -19,6 +21,10 @@ public class ResultMultiple {
this.runs = runs;
this.average = ResultMultiple.calcAvg(runs);
this.variance = ResultMultiple.calcVar(this.average, runs);
+
+ var temp = calcInterval(this.average, this.variance, runs.length, 0.95);
+ this.lowerBound = temp[0];
+ this.upperBound = temp[1];
}
/**
@@ -34,7 +40,7 @@ public class ResultMultiple {
for (var run : runs) {
avgTime += run.simulationTime;
- avgElapsed += run.timeElapsedNano;
+ avgElapsed += run.timeElapsedMS;
for (var entry : run.nodes.entrySet()) {
var stats = nodes.computeIfAbsent(entry.getKey(), _ -> new Statistics());
@@ -63,7 +69,7 @@ public class ResultMultiple {
for (var run : runs) {
varTime += Math.pow(run.simulationTime - avg.simulationTime, 2);
- varElapsed += Math.pow(run.timeElapsedNano - avg.simulationTime, 2);
+ varElapsed += Math.pow(run.timeElapsedMS - avg.simulationTime, 2);
for (var entry : run.nodes.entrySet()) {
var stat = nodes.computeIfAbsent(entry.getKey(), _ -> new Statistics());
@@ -82,4 +88,60 @@ public class ResultMultiple {
return new Result(runs[0].seed, varTime, varElapsed, nodes);
}
+
+ /**
+ * TODO
+ *
+ * @param avg
+ * @param stdDev
+ * @param sampleSize
+ * @param alpha
+ * @return
+ */
+ public static Result[] calcInterval(Result avg, Result stdDev, int sampleSize, double alpha) {
+ if (sampleSize <= 1)
+ throw new IllegalArgumentException("Il numero di campioni deve essere maggiore di 1.");
+
+ // Getting the correct values for the percentile
+ var distr = new org.apache.commons.math3.distribution.TDistribution(sampleSize - 1);
+ var percentile = distr.inverseCumulativeProbability(alpha);
+
+ // Calculating the error
+ var sqrtSample = Math.sqrt(sampleSize);
+ var error = new Result(avg.seed,
+ percentile * (stdDev.simulationTime / sqrtSample),
+ percentile * (stdDev.timeElapsedMS / sqrtSample),
+ new HashMap<>());
+ for (var entry : stdDev.nodes.entrySet()) {
+ var stat = new Statistics();
+ stat.merge(entry.getValue(), (_, val) -> percentile * (val / sqrtSample));
+ error.nodes.put(entry.getKey(), stat);
+ }
+
+ // Calculating the lower and the upper bound
+ var lowerBound = new Result(avg.seed,
+ avg.simulationTime - error.simulationTime,
+ avg.timeElapsedMS - error.timeElapsedMS,
+ new HashMap<>());
+ var upperBound = new Result(avg.seed,
+ avg.simulationTime + error.simulationTime,
+ avg.timeElapsedMS + error.timeElapsedMS,
+ new HashMap<>());
+ error.nodes.entrySet().forEach(entry -> {
+ var key = entry.getKey();
+ var errStat = entry.getValue();
+
+ var avgStat = avg.nodes.get(key);
+ var lower = new Statistics();
+ var upper = new Statistics();
+
+ Statistics.apply(lower, avgStat, errStat, (a, e) -> a - e);
+ Statistics.apply(upper, avgStat, errStat, (a, e) -> a + e);
+
+ lowerBound.nodes.put(key, lower);
+ upperBound.nodes.put(key, lower);
+ });
+
+ return new Result[] { lowerBound, upperBound };
+ }
}
\ No newline at end of file