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