Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / statistics / DefaultHistogramBand.java @ 44831

History | View | Annotate | Download (7.92 KB)

1
package org.gvsig.raster.lib.buffer.impl.statistics;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7

    
8
import org.gvsig.raster.lib.buffer.api.Band;
9
import org.gvsig.raster.lib.buffer.api.BufferManager;
10
import org.gvsig.raster.lib.buffer.api.statistics.HistogramBand;
11
import org.gvsig.raster.lib.buffer.api.statistics.HistogramClass;
12

    
13

    
14
/**
15
 * @author fdiaz
16
 *
17
 */
18
public class DefaultHistogramBand implements HistogramBand {
19

    
20
    Band band;
21
    List<HistogramClass> histogramClasses;
22

    
23

    
24
    public DefaultHistogramBand(Band band){
25
        this.band=band;
26
        this.histogramClasses=new ArrayList<HistogramClass>();
27
    }
28

    
29
    public DefaultHistogramBand(Band band, List<HistogramClass> histogramClasses){
30
        this.band=band;
31
        this.histogramClasses=histogramClasses;
32
        Collections.sort(this.histogramClasses);
33
    }
34

    
35
    @Override
36
    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
    }
45

    
46
    @Override
47
    public int getDataType() {
48
        return this.band.getDataType();
49
    }
50

    
51
    @Override
52
    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
    }
60

    
61
    private HistogramClass getHistogramClass(double value){
62
        for (HistogramClass histogramClass: histogramClasses){
63
            if (histogramClass.isIn(value)){
64
                return histogramClass;
65
            }
66
        }
67

    
68
        if(histogramClasses.size() == 0){
69
            return null;
70
        }
71

    
72
        HistogramClass lastHistogramClass = histogramClasses.get(histogramClasses.size()-1);
73
        if(lastHistogramClass.getMax() == value){
74
            return lastHistogramClass;
75
        }
76

    
77
        return null;
78
    }
79

    
80
    @Override
81
    public boolean union(HistogramBand hist) {
82
        //First we must check that histograms are compatible
83
        if (this.getNumClasses()==hist.getNumClasses()){
84
            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
    }
99

    
100
    @Override
101
    public long[] getFrequencies() {
102

    
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
        }
132
        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
    }
139

    
140
    @Override
141
    public int getNumClasses() {
142
        return histogramClasses.size();
143
    }
144

    
145
    @Override
146
    public long getValueCount(int interval) {
147
        return histogramClasses.get(interval).getValue();
148
    }
149

    
150
    @Override
151
    public double getIntervalMin(int interval) {
152
        return histogramClasses.get(interval).getMin();
153
    }
154

    
155
    @Override
156
    public double getIntervalMax(int interval) {
157
        return histogramClasses.get(interval).getMax();
158
    }
159

    
160
    @Override
161
    public double getMedian() {
162
        double halfn=(getNumValues())/2d;
163
        return getUmpteenth(halfn);
164
    }
165

    
166
    /**
167
     * Obtiene el en?simo valor
168
     * @param n
169
     * @return
170
     */
171
    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
            }
201

    
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
                }
211

    
212
                contValues += histogramClass.getValue();
213

    
214
                if (n < contValues) {
215

    
216
                    return histogramClass.getMin();
217
                }
218
                antMax = histogramClass.getMax();
219
            }
220

    
221
        }
222
        return 0;
223
    }
224

    
225
    /**
226
     * Adds value to histogram
227
     *
228
     * @param value
229
     */
230
    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
            // So that the list is always sorted
237
            Collections.sort(histogramClasses);
238
        } else {
239
            histogramClass.increment(1);
240
        }
241
    }
242

    
243
    @Override
244
    public double[] getTailTrimValue(double percent) {
245
        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
        long lowPosition = Math.round(getNumValues()*percent/100);
253
        long upperPosition = Math.round(getNumValues()*(100-percent)/100);
254

    
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
    public double[] getTailTrimValue(int pos) {
264
        long lowPosition = pos;
265
        long upperPosition = getNumValues()-pos;
266

    
267
        double[] result = new double[2];
268

    
269
        result[0] = getUmpteenth(lowPosition);
270
        result[1] = getUmpteenth(upperPosition);
271
        return result;
272
    }
273

    
274

    
275

    
276
}