comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java @ 3566:8d0f06b76e09

S/Q relation: Fixed flys/issue748 flys-artifacts/trunk@5164 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 01 Aug 2012 10:19:45 +0000
parents 1df6984628c3
children b8b1280606c2
comparison
equal deleted inserted replaced
3565:b136113dad53 3566:8d0f06b76e09
12 12
13 public class Outlier 13 public class Outlier
14 { 14 {
15 private static Logger log = Logger.getLogger(Outlier.class); 15 private static Logger log = Logger.getLogger(Outlier.class);
16 16
17 public static final int MAX_ITERATIONS = 1000;
18
19 public interface Callback { 17 public interface Callback {
20 18
21 void initialize(Iterator<SQ> good) throws MathException; 19 void initialize(List<SQ> sqs) throws MathException;
22 20
23 double eval(SQ sq); 21 double eval(SQ sq);
24 22
25 void outlier(SQ sq); 23 void iterationFinished(
26 24 double stdDev,
27 void remaining(SQ sq); 25 SQ outlier,
28 26 List<SQ> remaining);
29 void standardDeviation(double stdDev);
30
31 void iterationFinished();
32 27
33 } // interface Callback 28 } // interface Callback
34
35 private static final class EvalSQ {
36 protected SQ sq;
37 protected double value;
38
39 public EvalSQ(SQ sq) {
40 this.sq = sq;
41 }
42 } // class EvalSQ
43 29
44 public static void detectOutliers( 30 public static void detectOutliers(
45 Callback callback, 31 Callback callback,
46 List<SQ> sqs, 32 List<SQ> sqs,
47 double stdDevFactor 33 double stdDevFactor
52 38
53 if (debug) { 39 if (debug) {
54 log.debug("stdDevFactor: " + stdDevFactor); 40 log.debug("stdDevFactor: " + stdDevFactor);
55 } 41 }
56 42
57 List<EvalSQ> data = new ArrayList<EvalSQ>(sqs.size()); 43 List<SQ> data = new ArrayList<SQ>(sqs);
58 44
59 for (SQ sq: sqs) { 45 while (data.size() > 2) {
60 data.add(new EvalSQ(sq));
61 }
62 46
63 List<EvalSQ> good = new ArrayList<EvalSQ>(sqs.size()); 47 callback.initialize(data);
64
65 for (int i = 0; i < MAX_ITERATIONS && data.size() > 2; ++i) {
66
67 callback.initialize(asSQIterator(data));
68 48
69 StandardDeviation stdDev = new StandardDeviation(); 49 StandardDeviation stdDev = new StandardDeviation();
70 50
71 for (EvalSQ esq: data) { 51 double maxValue = -Double.MAX_VALUE;
72 stdDev.increment(esq.value = callback.eval(esq.sq)); 52 int maxIndex = -1;
53
54 for (int i = data.size()-1; i >= 0; --i) {
55 double value = Math.abs(callback.eval(data.get(i)));
56 stdDev.increment(value);
57 if (value > maxValue) {
58 maxValue = value;
59 maxIndex = i;
60 }
73 } 61 }
74 62
75 double sd = stdDev.getResult(); 63 double sd = stdDev.getResult();
76 64
77 callback.standardDeviation(sd);
78
79 double accepted = stdDevFactor * sd; 65 double accepted = stdDevFactor * sd;
80 66
81 if (debug) { 67 if (debug) {
68 log.debug("std dev: " + stdDev);
82 log.debug("accepted: " + accepted); 69 log.debug("accepted: " + accepted);
70 log.debug("max value: " + maxValue);
83 } 71 }
84 72
85 for (EvalSQ esq: data) { 73 SQ outlier = maxValue > accepted
86 if (debug) { 74 ? data.remove(maxIndex)
87 log.debug(" value: " + Math.abs(esq.value)); 75 : null;
88 }
89 76
90 if (Math.abs(esq.value) > accepted) { 77 callback.iterationFinished(sd, outlier, data);
91 callback.outlier(esq.sq);
92 }
93 else {
94 callback.remaining(esq.sq);
95 good.add(esq);
96 }
97 }
98 78
99 callback.iterationFinished(); 79 if (outlier == null) {
100
101 if (good.size() == data.size()) {
102 break; 80 break;
103 } 81 }
104
105 List<EvalSQ> tmp = good;
106 good = data;
107 data = tmp;
108 good.clear();
109 } 82 }
110 }
111
112 protected static Iterator<SQ> asSQIterator(List<EvalSQ> esqs) {
113 final Iterator<EvalSQ> parent = esqs.iterator();
114 return new Iterator<SQ>() {
115 @Override
116 public boolean hasNext() {
117 return parent.hasNext();
118 }
119
120 @Override
121 public SQ next() {
122 return parent.next().sq;
123 }
124
125 @Override
126 public void remove() {
127 throw new UnsupportedOperationException();
128 }
129 };
130 } 83 }
131 } 84 }
132 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 85 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org