comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/DischargeValuesFinder.java @ 8931:b10f8415798c

Trying to avoid symptoms of == double comparison
author gernotbelger
date Tue, 06 Mar 2018 17:04:17 +0100
parents d9dbf0b74bc2
children 5d5d482da3e9
comparison
equal deleted inserted replaced
8930:f972e1da4a63 8931:b10f8415798c
15 import org.dive4elements.river.artifacts.model.QKms; 15 import org.dive4elements.river.artifacts.model.QKms;
16 import org.dive4elements.river.artifacts.model.WKms; 16 import org.dive4elements.river.artifacts.model.WKms;
17 import org.dive4elements.river.artifacts.model.WQKms; 17 import org.dive4elements.river.artifacts.model.WQKms;
18 import org.dive4elements.river.utils.DoubleUtil; 18 import org.dive4elements.river.utils.DoubleUtil;
19 19
20 import gnu.trove.TDoubleDoubleHashMap;
21
20 /** 22 /**
21 * @author Gernot Belger 23 * @author Gernot Belger
22 */ 24 */
23 public final class DischargeValuesFinder { 25 public final class DischargeValuesFinder {
24 26
25 private final UnivariateRealFunction qInterpolator; 27 private final UnivariateRealFunction qInterpolator;
28
29 private final TDoubleDoubleHashMap exactValues;
30
26 private final QKms qKms; 31 private final QKms qKms;
27 32
28 /** 33 /**
29 * Create an instance from a {@link WKms} object. If the given {@link WKms} is not a {@link WQKms}, a finder that always 34 * Create an instance from a {@link WKms} object. If the given {@link WKms} is not a {@link WQKms}, a finder that always
30 * returns {@link Double#NaN} is returned. 35 * returns {@link Double#NaN} is returned.
40 } 45 }
41 46
42 public DischargeValuesFinder(final QKms qKms) { 47 public DischargeValuesFinder(final QKms qKms) {
43 this.qKms = qKms; 48 this.qKms = qKms;
44 this.qInterpolator = qKms == null ? null : DoubleUtil.getLinearInterpolator(qKms.allKms(), qKms.allQs()); 49 this.qInterpolator = qKms == null ? null : DoubleUtil.getLinearInterpolator(qKms.allKms(), qKms.allQs());
50
51 this.exactValues = new TDoubleDoubleHashMap(qKms.size());
52
53 for (int i = 0; i < qKms.size(); i++) {
54 final double station = qKms.getKm(i);
55 final double discharge = qKms.getQ(i);
56 this.exactValues.put(station, discharge);
57 }
45 } 58 }
46 59
47 /** 60 /**
48 * If this provider may return valid data at all. 61 * If this provider may return valid data at all.
49 */ 62 */
54 public DoubleRange getRange() { 67 public DoubleRange getRange() {
55 return new DoubleRange(this.qKms.allQs().min(), this.qKms.allQs().max()); 68 return new DoubleRange(this.qKms.allQs().min(), this.qKms.allQs().max());
56 } 69 }
57 70
58 public double getDischarge(final double station) throws FunctionEvaluationException { 71 public double getDischarge(final double station) throws FunctionEvaluationException {
72
73 // IMPORTANT: we first try to retreive the exact value if it is present, to avoid rounding changes due to interpolation.
74 // This is important because in the WaterlevelExporter code, these values are double-compared (with '==' ...) in order
75 // to find the corresponding main-value.
76 if (this.exactValues.contains(station))
77 return this.exactValues.get(station);
78
59 return this.qInterpolator.value(station); 79 return this.qInterpolator.value(station);
60 } 80 }
61 } 81 }

http://dive4elements.wald.intevation.org