1 package baseCode.math;
2
3 import java.util.Arrays;
4 import java.util.Iterator;
5 import java.util.LinkedHashMap;
6 import java.util.Map;
7
8 import cern.colt.list.DoubleArrayList;
9 import cern.colt.list.IntArrayList;
10 import cern.colt.list.ObjectArrayList;
11
12 /***
13 * Calculate rank statistics for arrays.
14 * <p>
15 * Copyright (c) 2004
16 * </p>
17 * <p>
18 * Institution: Columbia University
19 * </p>
20 *
21 * @author Paul Pavlidis
22 * @version $Id: Rank.java,v 1.12 2004/12/24 23:16:10 pavlidis Exp $
23 */
24 public class Rank {
25
26 /***
27 * Return a permutation which puts the array in sorted order. In other words, the values returned indicate the
28 * positions of the sorted values in the current array (the lowest value has the lowest rank, but it could be located
29 * anywhere in the array).
30 *
31 * @param array
32 * @return
33 */
34 public static IntArrayList order( DoubleArrayList array ) {
35
36
37
38 IntArrayList ranks = rankTransform( array );
39
40 IntArrayList order = new IntArrayList( ranks.size() );
41
42 for ( int i = 0; i < ranks.size(); i++ ) {
43
44
45 for ( int j = 0; j < ranks.size(); j++ ) {
46 if ( i == ranks.getQuick( j ) ) {
47 order.add( j );
48 break;
49 }
50 }
51
52 }
53 return order;
54 }
55
56 /***
57 * Rank transform an array. Ties are not handled specially. The ranks are constructed based on the sort order of the
58 * elements. That is, low values get low numbered ranks.
59 *
60 * @param array DoubleArrayList
61 * @return cern.colt.list.DoubleArrayList
62 */
63 public static IntArrayList rankTransform( DoubleArrayList array ) {
64 if ( array == null ) {
65 throw new IllegalArgumentException( "Null array" );
66 }
67
68 int size = array.size();
69 if ( size == 0 ) {
70 return null;
71 }
72
73 ObjectArrayList ranks = new ObjectArrayList( size );
74 IntArrayList result = new IntArrayList( new int[size] );
75
76
77 for ( int i = 0; i < size; i++ ) {
78 rankData rd = new rankData( i, array.get( i ) );
79 ranks.add( rd );
80 }
81
82 ranks.sort();
83
84
85 for ( int i = 0; i < size; i++ ) {
86 result.set( ( ( rankData ) ranks.get( i ) ).getIndex(), i );
87 }
88
89 return result;
90 }
91
92 /***
93 * Rank transform a map, where the values are numerical (java.lang.Double) values we wish to rank. Ties are not
94 * handled specially.
95 *
96 * @param m java.util.Map with keys Objects, values Doubles.
97 * @return A java.util.Map keys=old keys, values=java.lang.Integer rank of the key.
98 * @throws IllegalArgumentException if the input Map does not have Double values.
99 */
100 public static Map rankTransform( Map m ) throws IllegalArgumentException {
101 int counter = 0;
102
103 keyAndValueData[] values = new keyAndValueData[m.size()];
104
105
106
107
108 for ( Iterator itr = m.keySet().iterator(); itr.hasNext(); ) {
109
110 Object key = itr.next();
111
112 if ( !( m.get( key ) instanceof Double ) ) {
113 throw new IllegalArgumentException(
114 "Attempt to rank a map with non-Double values" );
115 }
116
117 double val = ( ( Double ) m.get( key ) ).doubleValue();
118 values[counter] = new keyAndValueData( key, val );
119 counter++;
120 }
121
122
123 Arrays.sort( values );
124 Map result = new LinkedHashMap();
125
126 for ( int i = 0; i < m.size(); i++ ) {
127 result.put( values[i].getKey(), new Integer( i ) );
128 }
129 return result;
130 }
131 }
132
133
134
135
136
137 class rankData implements Comparable {
138
139 private int index;
140 private double value;
141
142 public rankData( int tindex, double tvalue ) {
143 index = tindex;
144 value = tvalue;
145 }
146
147 public int compareTo( Object a ) {
148 rankData other = ( rankData ) ( a );
149 if ( this.value < other.getValue() ) {
150 return -1;
151 } else if ( this.value > other.getValue() ) {
152 return 1;
153 } else {
154 return 0;
155 }
156 }
157
158 public int getIndex() {
159 return index;
160 }
161
162 public double getValue() {
163 return value;
164 }
165 }
166
167
168
169
170
171 class keyAndValueData implements Comparable {
172 private Object key;
173
174 private double value;
175
176 public keyAndValueData( Object id, double v ) {
177 this.key = id;
178 this.value = v;
179 }
180
181 public int compareTo( Object ob ) {
182 keyAndValueData other = ( keyAndValueData ) ob;
183
184 if ( this.value < other.value ) {
185 return -1;
186 } else if ( this.value > other.value ) {
187 return 1;
188 } else {
189 return 0;
190 }
191 }
192
193 public Object getKey() {
194 return key;
195 }
196
197 public double getValue() {
198 return value;
199 }
200 }