Switch to higher precision in the computation. BigDecimal
diff --git a/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java b/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
index b704fd7..3b6a3ee 100644
--- a/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
+++ b/org.eclipse.stem/analysis/org.eclipse.stem.analysis/src/org/eclipse/stem/analysis/impl/CompoundErrorFunctionImpl.java
@@ -2,6 +2,8 @@
*/
package org.eclipse.stem.analysis.impl;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -589,9 +591,7 @@
double[] Xdata = new double[time.length];
double finalerror = 0.0;
double verror = 0.0;
-
for(int i=0;i<time.length;++i) list.add(0.0);
-
// Get the average population for each location
for(String loc:commonPopulationLocationsA.keySet()) {
List<Double>ld = commonPopulationLocationsA.get(loc);
@@ -599,7 +599,6 @@
sum /= (double)ld.size();
commonAvgPopulationLocationsA.put(loc, sum);
}
-
// Get the average population for each location
for(String loc:commonPopulationLocationsB.keySet()) {
List<Double>ld = commonPopulationLocationsB.get(loc);
@@ -607,7 +606,6 @@
sum /= (double)ld.size();
commonAvgPopulationLocationsB.put(loc, sum);
}
-
// Get the maximum value for the A series (reference)
for(String loc:commonPopulationLocationsA.keySet()) {
List<Double>ld = commonDailyIncidenceLocationsMapA.get(loc);
@@ -615,7 +613,6 @@
for(double d:ld)if(d >max)max=d;
commonMaxLocationsA.put(loc, max);
}
-
// Calculate the normalized root mean square error for each location, then
// divide by the number of locatins
double weighted_denom = 0.0;
@@ -646,12 +643,14 @@
++timesteps;
}
double error = Double.MAX_VALUE;
+ BigDecimal maxRefBD = new BigDecimal(maxRef);
+ BigDecimal minRefBD = new BigDecimal(minRef);
if(timesteps > 0) {
error = Math.sqrt(nominator/timesteps);
- if(maxRef-minRef > 0.0) {
+ if(maxRefBD.subtract(minRefBD).doubleValue() > 0.0) {
error = error / (maxRef-minRef);
}
- else if(maxRef-minRef==0) {
+ else if(maxRefBD.subtract(minRefBD).doubleValue()==0) {
error=Double.MIN_VALUE;// if all values in the reference data is 0
}
if(WEIGHTED_AVERAGE) finalerror += commonAvgPopulationLocationsA.get(loc) * error;
@@ -662,7 +661,6 @@
}
// Divide the error by the number of locations
finalerror /= weighted_denom;
-
} else { // Aggregate signal, then calculate NRMSE
for(int icount =0; icount < time.length; icount ++) {
for(String loc:commonDailyIncidenceLocationsMapA.keySet()) {
@@ -674,12 +672,10 @@
Xdata[icount]+=iB;
}
}
-
double maxRef = Double.MIN_VALUE;
double minRef = Double.MAX_VALUE;
double maxValidationRef = Double.MIN_VALUE;
double minValidationRef = Double.MAX_VALUE;
-
for(int icount =0; icount < time.length; icount ++) {
if(icount >= validationYear*365.25 && icount <= (validationYear+1)*365.25) {
if(Xref[icount]>maxValidationRef)maxValidationRef = Xref[icount];
@@ -709,24 +705,28 @@
list.set(icount, Math.abs(Xref[icount]-Xdata[icount]));
++timesteps;
}
+ BigDecimal maxRefBD = new BigDecimal(maxRef).setScale(5,RoundingMode.DOWN);
+ BigDecimal minRefBD = new BigDecimal(minRef).setScale(5,RoundingMode.DOWN);
+ BigDecimal maxValidationRefBD = new BigDecimal(maxValidationRef).setScale(5,RoundingMode.DOWN);
+ BigDecimal minValidationRefBD = new BigDecimal(minValidationRef).setScale(5,RoundingMode.DOWN);
double error = Double.MAX_VALUE;
if(timesteps > 0) {
- if(maxRef-minRef > 0.0) {
+ if(maxRefBD.subtract(minRefBD).doubleValue() > 0.0) {
error = Math.sqrt(nominator/timesteps);
finalerror = error / (maxRef-minRef);
}
- else if(maxRef-minRef==0) {
- error=Double.MIN_VALUE;// if all values in the reference data is 0
+ else if(maxRefBD.subtract(minRefBD).doubleValue() ==0) {
+ error=Math.sqrt(nominator/timesteps);// if all values in the reference data is 0
finalerror=Double.MIN_VALUE;// if all values in the reference data is 0
}
}
// Validation
error = Double.MAX_VALUE;
if(vtimesteps > 0) {
- if(maxValidationRef-minValidationRef > 0.0) {
+ if(maxValidationRefBD.subtract(minValidationRefBD).doubleValue() > 0.0) {
error = Math.sqrt(vnominator/vtimesteps);
verror = error / (maxValidationRef-minValidationRef);
- }else if(maxValidationRef-minValidationRef==0) {
+ }else if(maxValidationRefBD.subtract(minValidationRefBD).doubleValue()==0) {
error=Double.MIN_VALUE;// if all values in the reference data is 0
verror=Double.MIN_VALUE;// if all values in the reference data is 0
}