Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / statistics / DefaultHistogramBand.java @ 8800

History | View | Annotate | Download (7.92 KB)

1 5456 dmartinezizquierdo
package org.gvsig.raster.lib.buffer.impl.statistics;
2
3
import java.util.ArrayList;
4 5482 fdiaz
import java.util.Collections;
5 5533 fdiaz
import java.util.Iterator;
6 5456 dmartinezizquierdo
import java.util.List;
7
8
import org.gvsig.raster.lib.buffer.api.Band;
9 5493 fdiaz
import org.gvsig.raster.lib.buffer.api.BufferManager;
10 5456 dmartinezizquierdo
import org.gvsig.raster.lib.buffer.api.statistics.HistogramBand;
11
import org.gvsig.raster.lib.buffer.api.statistics.HistogramClass;
12
13
14 5482 fdiaz
/**
15
 * @author fdiaz
16
 *
17
 */
18 5456 dmartinezizquierdo
public class DefaultHistogramBand implements HistogramBand {
19
20
    Band band;
21
    List<HistogramClass> histogramClasses;
22
23 5482 fdiaz
24 5456 dmartinezizquierdo
    public DefaultHistogramBand(Band band){
25
        this.band=band;
26
        this.histogramClasses=new ArrayList<HistogramClass>();
27
    }
28
29 5482 fdiaz
    public DefaultHistogramBand(Band band, List<HistogramClass> histogramClasses){
30
        this.band=band;
31
        this.histogramClasses=histogramClasses;
32
        Collections.sort(this.histogramClasses);
33
    }
34
35 5456 dmartinezizquierdo
    @Override
36 5533 fdiaz
    public long getNumValues() {
37
        long count = 0;
38
        for (Iterator iterator = histogramClasses.iterator(); iterator.hasNext();) {
39
            HistogramClass histogramClass = (HistogramClass) iterator.next();
40
            count += histogramClass.getValue();
41
        }
42
43
        return count;
44 5456 dmartinezizquierdo
    }
45
46
    @Override
47
    public int getDataType() {
48
        return this.band.getDataType();
49
    }
50
51
    @Override
52 5473 dmartinezizquierdo
    public long getHistogramValue(double value) {
53
        HistogramClass histogramClass=getHistogramClass(value);
54
        if (histogramClass==null){
55
            return 0;
56
        }else{
57
            return histogramClass.getValue();
58
        }
59 5456 dmartinezizquierdo
    }
60
61 5473 dmartinezizquierdo
    private HistogramClass getHistogramClass(double value){
62
        for (HistogramClass histogramClass: histogramClasses){
63
            if (histogramClass.isIn(value)){
64
                return histogramClass;
65
            }
66
        }
67 5533 fdiaz
68 5528 llmarques
        if(histogramClasses.size() == 0){
69
            return null;
70
        }
71 5533 fdiaz
72 5528 llmarques
        HistogramClass lastHistogramClass = histogramClasses.get(histogramClasses.size()-1);
73
        if(lastHistogramClass.getMax() == value){
74
            return lastHistogramClass;
75
        }
76 5533 fdiaz
77 5473 dmartinezizquierdo
        return null;
78 5456 dmartinezizquierdo
    }
79
80
    @Override
81
    public boolean union(HistogramBand hist) {
82 5473 dmartinezizquierdo
        //First we must check that histograms are compatible
83 5533 fdiaz
        if (this.getNumClasses()==hist.getNumClasses()){
84 5473 dmartinezizquierdo
            for (int i=0; i<histogramClasses.size(); i++){
85
                if ( this.getIntervalMin(i)!=hist.getIntervalMin(i) ||
86
                    this.getIntervalMax(i)!=hist.getIntervalMax(i)){
87
                    return false;
88
                }
89
            }
90
        }else{
91
            return false;
92
        }
93
        //Once checked compatibility, values are added
94
        for (int i=0; i<histogramClasses.size(); i++){
95
            histogramClasses.get(i).increment(hist.getValueCount(i));
96
        }
97
        return true;
98 5456 dmartinezizquierdo
    }
99
100
    @Override
101 5473 dmartinezizquierdo
    public long[] getFrequencies() {
102 8582 fdiaz
103
        Integer dataType = getDataType();
104
105
        int size;
106
        int rangeMin;
107
        int rangeMax;
108
        switch (dataType) {
109
        case BufferManager.TYPE_BYTE:
110
            rangeMin = 0;
111
            rangeMax = 255;
112
            size = 256;
113
            break;
114
        case BufferManager.TYPE_SHORT:
115
            rangeMin = Short.MIN_VALUE;
116
            rangeMax = Short.MAX_VALUE;
117
            size = rangeMax-rangeMin+1;
118
            break;
119
        case BufferManager.TYPE_USHORT:
120
            rangeMin = 0;
121
            rangeMax = Math.abs(Short.MIN_VALUE) + Short.MAX_VALUE;
122
            size = rangeMax-rangeMin+1;
123
            break;
124
        case BufferManager.TYPE_INT:
125
            rangeMin = Integer.MIN_VALUE;
126
            rangeMax = Integer.MAX_VALUE;
127
            size = rangeMax-rangeMin+1;
128
            break;
129
        default:
130
            throw new IllegalArgumentException("Can't process type '" + dataType + "'");
131 5473 dmartinezizquierdo
        }
132 8582 fdiaz
        long[] table = new long[size];
133
            for (int j = 0; j < table.length; j++) {
134
                table[j] = getHistogramValue(j);
135
            }
136
        return table;
137
138 5456 dmartinezizquierdo
    }
139
140
    @Override
141 5533 fdiaz
    public int getNumClasses() {
142 5473 dmartinezizquierdo
        return histogramClasses.size();
143 5456 dmartinezizquierdo
    }
144
145
    @Override
146 5473 dmartinezizquierdo
    public long getValueCount(int interval) {
147
        return histogramClasses.get(interval).getValue();
148 5456 dmartinezizquierdo
    }
149
150
    @Override
151 5473 dmartinezizquierdo
    public double getIntervalMin(int interval) {
152
        return histogramClasses.get(interval).getMin();
153 5456 dmartinezizquierdo
    }
154
155
    @Override
156 5473 dmartinezizquierdo
    public double getIntervalMax(int interval) {
157
        return histogramClasses.get(interval).getMax();
158 5456 dmartinezizquierdo
    }
159
160
    @Override
161 5473 dmartinezizquierdo
    public double getMedian() {
162 5533 fdiaz
        double halfn=(getNumValues())/2d;
163 5493 fdiaz
        return getUmpteenth(halfn);
164
    }
165
166
    /**
167 5528 llmarques
     * Obtiene el en?simo valor
168 5493 fdiaz
     * @param n
169
     * @return
170
     */
171 5528 llmarques
    private double getUmpteenth(double n) {
172
        long contValues = 0;
173
174
        if (this.getDataType() == BufferManager.TYPE_FLOAT
175
            || this.getDataType() == BufferManager.TYPE_DOUBLE) { // Valores no
176
                                                                  // discretos
177
178
            for (int i = 0; i < histogramClasses.size(); i++) {
179
                HistogramClass histogramClass = histogramClasses.get(i);
180
                long anteriorCont = contValues;
181
                if (n == contValues) {
182
                    return histogramClass.getMin();
183
                }
184
                contValues += histogramClass.getValue();
185
                if (n == contValues) {
186
                    return histogramClass.getMax();
187
                }
188
                if (n < contValues) {
189
                    double median;
190
191
                    double nM = n; // getBandLenght() / 2;
192
                    double nA = anteriorCont;
193
                    double fI = histogramClass.getValue();
194
                    double interval = histogramClass.getMax() - histogramClass.getMin();
195
                    double min = histogramClass.getMin();
196
197
                    median = min + ((nM - nA) / fI) * interval;
198
                    return median;
199
                }
200 5473 dmartinezizquierdo
            }
201 5528 llmarques
202
        } else { // Valores discretos
203
            double antMax = Double.NEGATIVE_INFINITY;
204
205
            for (int i = 0; i < histogramClasses.size(); i++) {
206
                HistogramClass histogramClass = histogramClasses.get(i);
207
208
                if (n == contValues) {
209
                    return (histogramClass.getMin() + antMax) / 2;
210 5486 fdiaz
                }
211 5528 llmarques
212
                contValues += histogramClass.getValue();
213
214
                if (n < contValues) {
215
216
                    return histogramClass.getMin();
217
                }
218
                antMax = histogramClass.getMax();
219 5473 dmartinezizquierdo
            }
220 5528 llmarques
221 5473 dmartinezizquierdo
        }
222 5456 dmartinezizquierdo
        return 0;
223
    }
224
225 5493 fdiaz
    /**
226
     * Adds value to histogram
227
     *
228
     * @param value
229
     */
230 5482 fdiaz
    public void addValue(double value){
231
        HistogramClass histogramClass = getHistogramClass(value);
232
        if(histogramClass == null){
233
            histogramClass = new DefaultHistogramClass(value, value);
234
            histogramClass.setValue(1);
235
            histogramClasses.add(histogramClass);
236 8577 fdiaz
            // So that the list is always sorted
237 5482 fdiaz
            Collections.sort(histogramClasses);
238
        } else {
239
            histogramClass.increment(1);
240
        }
241
    }
242 5456 dmartinezizquierdo
243 5493 fdiaz
    @Override
244 5534 fdiaz
    public double[] getTailTrimValue(double percent) {
245 5493 fdiaz
        if(percent>100 || percent <0){
246
            StringBuilder builder = new StringBuilder();
247
            builder.append("Percent ");
248
            builder.append(percent);
249
            builder.append(" is out of range [0,100]");
250
            throw new IllegalArgumentException(builder.toString());
251
        }
252 5533 fdiaz
        long lowPosition = Math.round(getNumValues()*percent/100);
253
        long upperPosition = Math.round(getNumValues()*(100-percent)/100);
254 5493 fdiaz
255
        double[] result = new double[2];
256
257
        result[0] = getUmpteenth(lowPosition);
258
        result[1] = getUmpteenth(upperPosition);
259
        return result;
260
    }
261
262
    @Override
263 5534 fdiaz
    public double[] getTailTrimValue(int pos) {
264 5493 fdiaz
        long lowPosition = pos;
265 5533 fdiaz
        long upperPosition = getNumValues()-pos;
266 5493 fdiaz
267
        double[] result = new double[2];
268
269
        result[0] = getUmpteenth(lowPosition);
270
        result[1] = getUmpteenth(upperPosition);
271
        return result;
272
    }
273
274 8577 fdiaz
275
276 5456 dmartinezizquierdo
}