1 package structures; 2 3 import java.util.ArrayList; 4 import java.util.LinkedList; 5 6 import shared.KillSwitch; 7 import shared.Shared; 8 import shared.Timer; 9 import shared.Tools; 10 11 12 13 public final class FloatList{ 14 main(String[] args)15 public static void main(String[] args){ 16 Timer t=new Timer(); 17 int length=args.length>0 ? Integer.parseInt(args[0]) : 100000000; 18 19 System.gc(); 20 21 { 22 System.err.println("\nFloatList:"); 23 Shared.printMemory(); 24 t.start(); 25 FloatList list=new FloatList(); 26 for(int i=0; i<length; i++){ 27 list.add(i); 28 } 29 t.stop("Time: \t"); 30 System.gc(); 31 Shared.printMemory(); 32 list=null; 33 System.gc(); 34 } 35 36 { 37 System.err.println("\nArrayList:"); 38 Shared.printMemory(); 39 t.start(); 40 ArrayList<Float> list=new ArrayList<Float>(); 41 for(int i=0; i<length; i++){ 42 list.add((float)i); 43 } 44 t.stop("Time: \t"); 45 System.gc(); 46 Shared.printMemory(); 47 list=null; 48 System.gc(); 49 } 50 51 { 52 System.err.println("\nLinkedList:"); 53 Shared.printMemory(); 54 t.start(); 55 LinkedList<Float> list=new LinkedList<Float>(); 56 for(int i=0; i<length; i++){ 57 list.add((float)i); 58 } 59 t.stop("Time: \t"); 60 System.gc(); 61 Shared.printMemory(); 62 list=null; 63 System.gc(); 64 } 65 } 66 FloatList()67 public FloatList(){this(256);} 68 FloatList(int initial)69 public FloatList(int initial){ 70 // assert(initial>0) : initial+"\n"+this; 71 initial=Tools.max(initial, 1); 72 array=KillSwitch.allocFloat1D(initial); 73 } 74 copy()75 public FloatList copy() { 76 FloatList copy=new FloatList(size); 77 copy.addAll(this); 78 return copy; 79 } 80 clear()81 public void clear(){size=0;} 82 set(int loc, float value)83 public final void set(int loc, float value){ 84 if(loc>=array.length){ 85 resize(loc*2L+1); 86 } 87 array[loc]=value; 88 size=max(size, loc+1); 89 } 90 setLast(float value)91 public final void setLast(float value){ 92 assert(size>0); 93 array[size-1]=value; 94 } 95 increment(int loc, float value)96 public final void increment(int loc, float value){ 97 if(loc>=array.length){ 98 resize(loc*2L+1); 99 } 100 array[loc]+=value; 101 size=max(size, loc+1); 102 } 103 increment(int loc)104 public final void increment(int loc){ 105 increment(loc, 1); 106 } 107 incrementBy(FloatList b)108 public final void incrementBy(FloatList b){ 109 for(int i=b.size-1; i>=0; i--){ 110 increment(i, b.get(i)); 111 } 112 } 113 incrementBy(float[] b)114 public final void incrementBy(float[] b){ 115 for(int i=b.length-1; i>=0; i--){ 116 increment(i, b[i]); 117 } 118 } 119 append(FloatList b)120 public final void append(FloatList b){ 121 for(int i=0; i<b.size; i++){ 122 add(b.get(i)); 123 } 124 } 125 append(float[] b)126 public final void append(float[] b){ 127 for(int i=0; i<b.length; i++){ 128 add(b[i]); 129 } 130 } 131 subtractFrom(float value)132 public void subtractFrom(float value){ 133 for(int i=0; i<size; i++){ 134 array[i]=value-array[i]; 135 } 136 } 137 get(int loc)138 public final float get(int loc){ 139 return(loc>=size ? 0 : array[loc]);//TODO: Shouldn't this crash instead of returning 0? 140 } 141 lastElement()142 public float lastElement() { 143 assert(size>0); 144 return array[size-1]; 145 } 146 add(float x)147 public final void add(float x){ 148 if(size>=array.length){ 149 resize(size*2L+1); 150 } 151 array[size]=x; 152 size++; 153 } 154 155 //Slow; for validation containsDuplicates()156 public boolean containsDuplicates(){ 157 for(int i=0; i<size; i++){ 158 for(int j=i+1; j<size; j++){ 159 if(array[i]==array[j]){return true;} 160 } 161 } 162 return false; 163 } 164 addAll(FloatList counts)165 public void addAll(FloatList counts) { 166 final float[] array2=counts.array; 167 final int size2=counts.size; 168 for(int i=0; i<size2; i++){add(array2[i]);} 169 } 170 contains(float x)171 public boolean contains(float x) { 172 for(int i=0; i<size; i++){ 173 if(array[i]==x){return true;} 174 } 175 return false; 176 } 177 setSize(final int size2)178 public final void setSize(final int size2) { 179 if(size2<array.length){resize(size2);} 180 size=size2; 181 } 182 resize(final long size2)183 private final void resize(final long size2){ 184 assert(size2>size) : size+", "+size2; 185 final int size3=(int)Tools.min(Shared.MAX_ARRAY_LEN, size2); 186 assert(size3>size) : "Overflow: "+size+", "+size2+" -> "+size3; 187 array=KillSwitch.copyOf(array, size3); 188 } 189 stdev()190 public final float stdev(){ 191 if(size<2){return 0;} 192 double sum=sum(); 193 double avg=sum/size; 194 double sumdev2=0; 195 for(int i=0; i<size; i++){ 196 double x=array[i]; 197 double dev=avg-x; 198 sumdev2+=(dev*dev); 199 } 200 return (float)Math.sqrt(sumdev2/size); 201 } 202 sumLong()203 public final double sumLong(){ 204 double sum=0; 205 for(int i=0; i<size; i++){ 206 sum+=array[i]; 207 } 208 return sum; 209 } 210 sum()211 public final double sum(){ 212 double sum=0; 213 for(int i=0; i<size; i++){ 214 sum+=array[i]; 215 } 216 return sum; 217 } 218 mean()219 public final double mean(){ 220 return size<1 ? 0 : sum()/size; 221 } 222 223 /** Assumes list is sorted */ median()224 public final double median(){ 225 if(size<1){return 0;} 226 int idx=percentileIndex(0.5f); 227 return array[idx]; 228 } 229 230 /** Assumes list is sorted */ mode()231 public final float mode(){ 232 if(size<1){return 0;} 233 assert(sorted()); 234 int streak=1, bestStreak=0; 235 float prev=array[0]; 236 float best=prev; 237 for(int i=0; i<size; i++){ 238 float x=array[i]; 239 if(x==prev){streak++;} 240 else{ 241 if(streak>bestStreak){ 242 bestStreak=streak; 243 best=prev; 244 } 245 streak=1; 246 prev=x; 247 } 248 } 249 if(streak>bestStreak){ 250 bestStreak=streak; 251 best=prev; 252 } 253 return best; 254 } 255 percentile(double fraction)256 public float percentile(double fraction){ 257 if(size<1){return 0;} 258 int idx=percentileIndex(fraction); 259 return array[idx]; 260 } 261 percentileIndex(double fraction)262 public int percentileIndex(double fraction){ 263 if(size<2){return size-1;} 264 assert(sorted()); 265 double target=(sum()*fraction); 266 double sum=0; 267 for(int i=0; i<size; i++){ 268 sum+=array[i]; 269 if(sum>=target){ 270 return i; 271 } 272 } 273 return size-1; 274 } 275 shrink()276 public final void shrink(){ 277 if(size==array.length){return;} 278 array=KillSwitch.copyOf(array, size); 279 } 280 281 282 shrinkToUnique()283 public final void shrinkToUnique(){ 284 condense(); 285 shrink(); 286 } 287 288 //In-place. 289 //Assumes sorted. condense()290 public final void condense(){ 291 if(size<=1){return;} 292 293 int i=0, j=1; 294 for(; j<size && array[i]<array[j]; i++, j++){}//skip while strictly ascending 295 296 int dupes=0; 297 for(; j<size; j++){//This only enters at the first nonascending pair 298 float a=array[i], b=array[j]; 299 assert(a<=b) : "Unsorted: "+i+", "+j+", "+a+", "+b; 300 if(b>a){ 301 i++; 302 array[i]=b; 303 }else{ 304 //do nothing 305 dupes++; 306 assert(a==b); 307 } 308 } 309 assert(dupes==(size-(i+1))); 310 assert(size>=(i+1)); 311 size=i+1; 312 } 313 toArray()314 public float[] toArray(){ 315 return KillSwitch.copyOf(array, size); 316 } 317 318 @Override toString()319 public String toString(){ 320 return toStringListView(); 321 } 322 toStringSetView()323 public String toStringSetView(){ 324 StringBuilder sb=new StringBuilder(); 325 sb.append('['); 326 String comma=""; 327 for(int i=0; i<size; i++){ 328 if(array[i]!=0){ 329 sb.append(comma+"("+i+", "+array[i]+")"); 330 comma=", "; 331 } 332 } 333 sb.append(']'); 334 return sb.toString(); 335 } 336 toStringListView()337 public String toStringListView(){ 338 StringBuilder sb=new StringBuilder(); 339 sb.append('['); 340 String comma=""; 341 for(int i=0; i<size; i++){ 342 sb.append(comma+array[i]); 343 comma=", "; 344 } 345 sb.append(']'); 346 return sb.toString(); 347 } 348 349 /** Assumes this is sorted. 350 * Reduces the list to a set of unique values; 351 * stores their counts in a second list. */ getUniqueCounts(FloatList counts)352 public void getUniqueCounts(FloatList counts) { 353 counts.size=0; 354 if(size<=0){return;} 355 356 int unique=1; 357 int count=1; 358 359 for(int i=1; i<size; i++){ 360 assert(array[i]>=array[i-1]); 361 if(array[i]==array[i-1]){ 362 count++; 363 }else{ 364 array[unique]=array[i]; 365 unique++; 366 counts.add(count); 367 count=1; 368 } 369 } 370 if(count>0){ 371 counts.add(count); 372 } 373 size=unique; 374 assert(counts.size==size); 375 } 376 sort()377 public void sort() { 378 if(size>1){Shared.sort(array, 0, size);} 379 } 380 reverse()381 public void reverse() { 382 if(size>1){Tools.reverseInPlace(array, 0, size);} 383 } 384 sorted()385 public boolean sorted(){ 386 for(int i=1; i<size; i++){ 387 if(array[i]<array[i-1]){return false;} 388 } 389 return true; 390 } 391 size()392 public int size() { 393 return size; 394 } 395 isEmpty()396 public boolean isEmpty() { 397 return size<1; 398 } 399 capacity()400 public int capacity() { 401 return array.length; 402 } 403 freeSpace()404 public int freeSpace() { 405 return array.length-size; 406 } 407 min(int x, int y)408 private static final int min(int x, int y){return x<y ? x : y;} max(int x, int y)409 private static final int max(int x, int y){return x>y ? x : y;} 410 411 public float[] array; 412 public int size=0; 413 414 } 415