/Users/lyon/j4p/src/math/Mat1.java
|
1 package math;
2
3 import utils.Timer;
4
5 /**
6 * Mat1 is a class that uses 1-D arrays and contains static methods.
7 * @author Douglas Lyon
8 */
9 public abstract class Mat1 {
10
11 public static void main(final String[] args) {
12 //testAdd1();
13
14 //testAdd2();
15 for (int i=0; i < 10; i++)
16 testSum();
17 }
18
19
20 /**
21 * Add a vector times a scalar to a vector.
22 * The first vector contains the sum.
23 *
24 * @param a the first vector
25 * @param b the second vector
26 * @param c the scalar multiplier
27 */
28 public static void add(final double[] a,
29 final double[] b,
30 final double c) {
31 final int aLength = a.length;
32 if (aLength != b.length) {
33 System.out.println(
34 "ERROR: Vectors must be of equal length to add.");
35 return;
36 }
37 for (int i = 0; i < aLength; i++) {
38 a[i] += c * b[i];
39 }
40 }
41
42 /**
43 * Add two vectors. The first vector contains
44 * the sum.
45 * <b>This is not optimized for <i>altivec</i>
46 * </b>
47 *
48 * @param a the first vector <code>a = a + b; </code>
49 * @param b the second vector
50 */
51 public static void add(final double[] a,
52 final double[] b) {
53 final int aLength = a.length;
54 if (aLength != b.length) {
55 System.out.println(
56 "ERROR: Vectors must be of equal length to add.");
57 return;
58 }
59 for (int i = 0; i < aLength; i++) {
60 a[i] += b[i];
61 }
62 }
63
64 /**
65 * Add two vectors. The first vector contains
66 * the sum.
67 *
68 * @param a the first vector a = a + b;
69 * @param b the second vector
70 */
71 public static void add(final float[] a,
72 final float[] b) {
73 final int aLength = a.length;
74 if (aLength != b.length) {
75 System.out.println(
76 "ERROR: Vectors must be of equal length to add.");
77 return;
78 }
79 for (int i = 0; i < aLength; i++) {
80 a[i] += b[i];
81 }
82 }
83
84 public static void testSum() {
85 final int n = 1 << 19;
86 System.out.println("n=" + n);
87 final float[] a = ramp(0, 100, n);
88 final Timer t = new Timer();
89 double ans;
90 ans = sum(a);
91 ans = sum(a);
92 ans = sum(a);
93 t.start();
94 ans = sum(a);
95 t.stop();
96
97 t.print(1, "ans=" + ans);
98 ans = sum4(a);
99 ans = sum4(a);
100 ans = sum4(a);
101 t.start();
102 ans = sum4(a);
103 t.stop();
104 t.print(1, "ans4=" + ans);
105 ans = sum8(a);
106 ans = sum8(a);
107 ans = sum8(a);
108 t.start();
109 ans = sum8(a);
110 t.stop();
111 t.print(1, "ans8=" + ans);
112 ans = sumV(a);
113 ans = sumV(a);
114 ans = sumV(a);
115 t.start();
116 ans = sumV(a);
117 t.stop();
118 t.print(1, "sumV=" + ans);
119 }
120
121 public static void testAdd2() {
122 final int n = 1 << 12;
123 System.out.println("n=" + n);
124 final float[] a = ramp(0, 100, n);
125 final float[] b = ramp(0, 100, n);
126 final Timer t = new Timer();
127 double ans;
128 t.start();
129 add(a, b);
130 ans = add(a);
131 t.stop();
132
133 t.print(1, "ans=" + ans);
134
135 ans = sum8(a);
136 t.stop();
137 t.print(1, "ans=" + ans);
138 }
139
140 /**
141 * Calculate the dot product of two vectors.
142 *
143 * @param a the first vector
144 * @param b the second vector
145 * @return the dot product
146 */
147 static public double dot(final double[] a,
148 final double[] b) {
149 final int aLength = a.length;
150 if (aLength != b.length) {
151 System.out.println(
152 "ERROR: Vectors must be of equal length in dot product.");
153 return 0;
154 }
155 double sum = 0;
156 for (int i = 0; i < aLength; i++) {
157 sum += a[i] * b[i];
158 }
159 return sum;
160 }
161
162
163 /**
164 * Calculate the dot product of a vector with
165 * itself.
166 *
167 * @param a the vector
168 * @return the dot product
169 */
170 static public double dot(final double[] a) {
171 final int aLength = a.length;
172 double sum = 0;
173 for (int i = 0; i < aLength; i++) {
174 sum += a[i] * a[i];
175 }
176 return sum;
177 }
178
179 /**
180 * Calculate the magnitude a vector.
181 *
182 * @param a the vector
183 * @return the magnitude
184 */
185 static public double magnitude(
186 final double[] a) {
187 final int aLength = a.length;
188 double sum = 0;
189 for (int i = 0; i < aLength; i++) {
190 sum += a[i] * a[i];
191 }
192 return Math.sqrt(sum);
193 }
194
195 public static void print(final double[] a) {
196 for (int i = 0; i < a.length; i++) {
197
198 System.out.print(a[i] + " ");
199 System.out.println();
200 }
201 }
202
203 public static void printStats(
204 final String title,
205 final float[] a) {
206 System.out.println(title);
207 printStats(a);
208 }
209
210 public static void printStats(
211 final float[] a) {
212 float min = Float.MAX_VALUE;
213 float max = Float.MIN_VALUE;
214 float aBar = 0;
215
216
217 final double N = a.length;
218 for (int x = 0; x < a.length; x++) {
219
220 aBar += a[x];
221
222 min = Math.min(a[x], min);
223 max = Math.max(a[x], max);
224 }
225
226
227 aBar /= N;
228
229 System.out.println(" aBar=" + aBar +
230 " a min=" +
231 min +
232 " a max=" +
233 max +
234 " a.length=" +
235 a.length +
236 " a[0].length=" +
237 a.length);
238
239 }
240
241 public static void print(final float[] a) {
242 for (int i = 0; i < a.length; i++) {
243 System.out.print(a[i] + " ");
244 System.out.println();
245 }
246 }
247
248 public static final float sum(
249 final float[] a) {
250 float s = 0;
251 for (int i = 0; i < a.length; i++)
252 s += a[i];
253 return s;
254 }
255
256 public static final double sum(
257 final double[] a) {
258 double s = 0.0;
259 for (int i = 0; i < a.length; i++)
260 s += a[i];
261 return s;
262 }
263
264 public static float[] ramp(final float start,
265 final float end,
266 final int n) {
267 final float[] f = new float[n];
268 float t = 0f;
269 for (int i = 0; i < f.length; i++) {
270
271 f[i] = t * end + (1 - t) * start;
272 // t*p1 + (1-t)*p0
273 t = (1f * i) / n;
274 }
275 return f;
276
277 }
278
279 public static void testAdd1() {
280 final int n = 1 << 18;
281 System.out.println("n=" + n);
282 final float[] a = ramp(0, 100, n);
283 //final float[] b = ramp(0, 200, n);
284 //final float[] c = new float[a.length];
285 //final Timer t = new Timer();
286
287
288 testAdd1(a);
289
290
291 }
292
293 /**
294 * Show how loop unwinding can improve speed
295 * for a vector sum, but only to a point.
296 */
297 public static void testAdd1(final float a[]) {
298
299 int numberOfRuns = 100;
300 System.out.println(
301 "each run is executed " +
302 numberOfRuns +
303 " times, averages are reported in ms");
304 Runnable r = new Runnable() {
305 public void run() {
306 add(a);
307 }
308 };
309 System.out.println(" add: " +
310 Timer.benchMark(r,
311 numberOfRuns));
312
313 r = new Runnable() {
314 public void run() {
315 sumV(a);
316 }
317 };
318 System.out.println(" SumV: " +
319 Timer.benchMark(r,
320 numberOfRuns));
321
322
323 r = new Runnable() {
324 public void run() {
325 add16(a);
326 }
327 };
328 System.out.println(" add16:" +
329 Timer.benchMark(r,
330 numberOfRuns));
331
332 r = new Runnable() {
333 public void run() {
334 add8Depend(a);
335 }
336 };
337 System.out.println(" add8Depend:" +
338 Timer.benchMark(r,
339 numberOfRuns));
340
341 r = new Runnable() {
342 public void run() {
343 add8NoDepend(a);
344 }
345 };
346 System.out.println(" add8NoDepend:" +
347 Timer.benchMark(r,
348 numberOfRuns));
349
350
351 //add(a, b, c);
352 // ans = add8(c);
353 // t.print(1, "add c = a + b, ans=" + ans);
354
355
356 // add8(a, b, c);
357 // ans = add8(c);
358 // t.print(1,
359 // "add c = a + b, p; ans=" + ans);
360 }
361
362 public static void add(final float[] a,
363 final float[] b,
364 final float[] c) {
365 for (int i = 0; i < a.length; i++)
366 c[i] = a[i] + b[i];
367 }
368
369 public static void add8(final float[] a,
370 final float[] b,
371 final float[] c) {
372 int i1, i2, i3, i4, i5, i6, i7;
373 for (int i = 0; i < a.length; i += 8) {
374 i1 = i + 1;
375 i2 = i + 2;
376 i3 = i + 3;
377 i4 = i + 4;
378 i5 = i + 5;
379 i6 = i + 6;
380 i7 = i + 7;
381 c[i] = a[i] + b[i];
382 c[i1] = a[i1] + b[i1];
383 c[i2] = a[i2] + b[i2];
384 c[i3] = a[i3] + b[i3];
385 c[i4] = a[i4] + b[i4];
386 c[i5] = a[i5] + b[i5];
387 c[i6] = a[i6] + b[i6];
388 c[i7] = a[i7] + b[i7];
389 }
390 }
391
392 public static final float sum4(final float[] a) {
393 float s = 0;
394 for (int i = 0; i < a.length; i = i + 4) {
395 s = a[i] +
396 a[i + 1] +
397 a[i + 2] +
398 a[i + 3] +
399 s;
400 }
401 return s;
402 }
403
404 public static final float sum8(final float[] a) {
405 float s = 0;
406 for (int i = 0; i < a.length; i = i + 8) {
407 s = a[i] +
408 a[i + 1] +
409 a[i + 2] +
410 a[i + 3] +
411 a[i + 4] +
412 a[i + 5] +
413 a[i + 6] +
414 a[i + 7] +
415 s;
416 }
417 return s;
418 }
419
420 public static double add8Depend(
421 final float[] a) {
422 double s = 0;
423 for (int i = 0; i < a.length; i = i + 8) {
424 s = s + a[i];
425 s = s + a[i + 1];
426 s = s + a[i + 2];
427 s = s + a[i + 3];
428 s = s + a[i + 4];
429 s = s + a[i + 5];
430 s = s + a[i + 6];
431 s = s + a[i + 7];
432 }
433 return s;
434 }
435
436 public static double add8NoDepend(
437 final float[] a) {
438 final float[] s = new float[8];
439 for (int i = 0; i < a.length; i = i + 8) {
440 s[0] = s[0] + a[i];
441 s[1] = s[1] + a[i + 1];
442 s[2] = s[2] + a[i + 2];
443 s[3] = s[3] + a[i + 3];
444 s[4] = s[4] + a[i + 4];
445 s[5] = s[5] + a[i + 5];
446 s[6] = s[6] + a[i + 6];
447 s[7] = s[7] + a[i + 7];
448
449 }
450 // compacting phase.
451 return
452 s[0] +
453 s[1] +
454 s[2] +
455 s[3] +
456 s[4] +
457 s[5] +
458 s[6] +
459 s[7];
460 }
461
462 public static double add16(final float[] a) {
463 double s = 0;
464 for (int i = 0; i < a.length; i = i + 16) {
465 s = a[i] +
466 a[i + 1] +
467 a[i + 2] +
468 a[i + 3] +
469 a[i + 4] +
470 a[i + 5] +
471 a[i + 6] +
472 a[i + 7] +
473 a[i + 8] +
474 a[i + 9] +
475 a[i + 10] +
476 a[i + 11] +
477 a[i + 12] +
478 a[i + 13] +
479 a[i + 14] +
480 a[i + 15] +
481 s;
482 }
483 return s;
484 }
485
486
487 public static double add(final float[] a) {
488 double s = 0.0;
489 for (int i = 0; i < a.length; i++)
490 s = s + a[i];
491 return s;
492 }
493
494 public static double add(final short[] a) {
495 double s = 0.0;
496 if (a == null) return 0;
497 for (int i = 0; i < a.length; i++)
498 s += a[i];
499 return s;
500 }
501
502 public static short clip(final short i) {
503 if (i < 0)
504 return 0;
505
506 if (i > 255)
507 return 255;
508
509 return i;
510 }
511
512 public static final float sumV(
513 final float a[]) {
514 int i = 0;
515 int n = a.length;
516 float s[] = {0, 0, 0, 0};
517 for (i = 0; i < n; i = i + 4) {
518 s[0] = s[0] + a[i];
519 s[1] = s[1] + a[i + 1];
520 s[2] = s[2] + a[i + 2];
521 s[3] = s[3] + a[i + 3];
522 }// compaction phase...
523 return s[0] + s[1] + s[2] + s[3];
524 }
525
526 public static short[][] clip(
527 final short[][] i) {
528 final short[][] i2 = new short[i.length][i[0].length];
529 for (int x = 0; x < i2.length; x++)
530 for (int y = 0; y < i2[0].length; y++)
531 i2[x][y] = clip(i[x][y]);
532 return i2;
533 }
534
535 public static void normalize(
536 final double[] a) {
537 scale(a, 1.0 / sum(a));
538 }
539
540 public static float[] normalize(
541 final short[] a) {
542 return scale(a, (float) (1.0f / add(a)));
543 }
544
545 public static void normalize(final float[] a) {
546 scale(a, 1.0 / add(a));
547 }
548
549 public static double average(
550 final double[] a) {
551 final int n = a.length * a.length;
552 return sum(a) / n;
553 }
554
555 public static double average(final float[] a) {
556 final int n = a.length * a.length;
557 return add(a) / n;
558 }
559
560 public static double average(final short[] a) {
561 final int n = a.length * a.length;
562 return add(a) / n;
563 }
564
565 public static void threshold(final short[] a,
566 final short thresh) {
567 for (int i = 0; i < a.length; i++)
568 if (a[i] < thresh)
569 a[i] = 0;
570 else
571 a[i] = 255;
572 }
573
574 public static void threshold(final short[] a) {
575 threshold(a, (short) average(a));
576 }
577
578
579 public static float[] scale(final short[] a,
580 final float k) {
581 if (a == null) return null;
582 final float[] f = new float[a.length];
583 for (int i = 0; i < a.length; i++) {
584 f[i] = k * a[i];
585 }
586 return f;
587
588 }
589
590 public static void scale(final double[] a,
591 final double k) {
592 System.out.println(
593 "scale(double a[], double k)");
594 for (int i = 0; i < a.length; i++) {
595
596 a[i] *= k;
597 }
598
599 }
600
601 public static void scale(final float[] a,
602 final float k) {
603 if (a == null) return;
604 for (int i = 0; i < a.length; i++) {
605 a[i] = a[i] * k;
606 }
607 }
608
609 public static void scale(final float[] a,
610 final double k) {
611 //System.out.println("scale(float a[][], double k)");
612 // System.out.println("k="+k);
613 scale(a, (float) k);
614 }
615
616 public static float[] shortToFloat(
617 final short[] a) {
618 final int w = a.length;
619
620 final float[] c = new float[w];
621 for (int i = 0; i < w; i++)
622 c[i] = a[i];
623 return c;
624 }
625
626 public static short[] copyArray(
627 final short[] a) {
628 final int w = a.length;
629
630 final short[] c = new short[w];
631 for (int i = 0; i < w; i++)
632 c[i] = a[i];
633 return c;
634 }
635
636 public static double variance(final int[] a) {
637 final double xBar = mean(a);
638 double sum = 0;
639 double dx;
640 for (int i = 0; i < a.length; i++) {
641 dx = a[i] - xBar;
642 sum += dx * dx;
643 }
644 return sum / a.length;
645 }
646
647 public static double mean(final int[] a) {
648 double sum = 0;
649 for (int i = 0; i < a.length; i++)
650 sum += a[i];
651 return sum / a.length;
652 }
653
654 public static double coefficientOfVariation(
655 final int[] a) {
656 final double aBar = mean(a);
657 final double aBar2 = aBar * aBar;
658 return Math.sqrt(variance(a) / aBar2);
659 }
660
661 public static void testVariance() {
662 final int[] a = {1, 2, 3, 5, 4, 3, 2, 5,
663 6, 7};
664 System.out.println(
665 "The variance =" + variance(a));
666 }
667
668 public static void testCoefficientOfVariation() {
669 final int[] a = {0, 85, 87, 90, 100};
670 System.out.println("coefficientOfVariation({0,85,87,90,100}) ="
671 +
672 coefficientOfVariation(
673 a));
674 final int[] b = {95, 85, 87, 90, 100};
675 System.out.println("The coefficientOfVariation({95,85,87,90,100}) ="
676 +
677 coefficientOfVariation(
678 b));
679 }
680
681 public static boolean outlierHere(
682 final int[] a) {
683 return (coefficientOfVariation(a) > .1);
684 }
685
686 public static void testOutlier() {
687 final int[] a = {0, 85, 87, 90, 100};
688 final int[] b = {95, 85, 87, 90, 100};
689 System.out.println("dog ate my homework ={0,85,87,90,100}"
690 + outlierHere(a));
691 System.out.println("dog ate my homework ={95,85,87,90,100}"
692 + outlierHere(b));
693 }
694
695 public static void quickSort(final int[] a,
696 final int lo0,
697 final int hi0) {
698 // Based on the QuickSort method by
699 // James Gosling from Sun's SortDemo applet
700
701 int lo = lo0;
702 int hi = hi0;
703 final int mid;
704 int t;
705
706 if (hi0 > lo0) {
707 mid = a[(lo0 + hi0) / 2];
708 while (lo <= hi) {
709 while ((lo < hi0) &&
710 (a[lo] < mid))
711 ++lo;
712 while ((hi > lo0) &&
713 (a[hi] > mid))
714 --hi;
715 if (lo <= hi) {
716 t = a[lo];
717 a[lo] = a[hi];
718 a[hi] = t;
719 ++lo;
720 --hi;
721 }
722 }
723 if (lo0 < hi)
724 quickSort(a, lo0, hi);
725 if (lo < hi0)
726 quickSort(a, lo, hi0);
727
728 }
729 }
730
731 public static void swap(final int[] x,
732 final int a,
733 final int b) {
734 final int t = x[a];
735 x[a] = x[b];
736 x[b] = t;
737 }
738
739 public static void quickSort(final int[] a) {
740 quickSort(a, 0, a.length - 1);
741 }
742
743 public static double mean(final short[][] a) {
744 double sum = 0;
745 for (int x = 0; x < a.length; x++)
746 for (int y = 0; y < a[0].length; y++) {
747 sum += a[x][y];
748 }
749 return sum / (a.length * a[0].length);
750 }
751
752 public static double variance(
753 final short[][] a) {
754 final double xBar = mean(a);
755 double sum = 0;
756 double dx;
757 for (int x = 0; x < a.length; x++)
758 for (int y = 0; y < a[0].length; y++) {
759 dx = a[x][y] - xBar;
760 sum += dx * dx;
761 }
762 return sum / (a.length * a[0].length);
763 }
764
765 public static double[] getAverage(
766 final double[] a,
767 final double[] b,
768 final double[] c) {
769 final double[] avg = new double[a.length];
770
771 for (int i = 0; i < a.length; i++) {
772 avg[i] = (a[i] + b[i] + c[i]) / 3.0;
773 }
774 return avg;
775 }
776
777 public static short[][] copy(
778 final short[][] r) {
779 final short[][] c = new short[r.length][r[0].length];
780 final int w = r.length;
781 final int h = r[0].length;
782 for (int x = 0; x < w; x++)
783 for (int y = 0; y < h; y++)
784 c[x][y] = r[x][y];
785 return c;
786 }
787
788 public static short getMin(final short[] a) {
789 short min = 255;
790 for (int i = 0; i < a.length; i++)
791 if (a[i] < min)
792 min = a[i];
793 return min;
794 }
795
796 public static short getMax(final short[] a) {
797 short max = -255;
798 for (int i = 0; i < a.length; i++)
799 if (a[i] > max)
800 max = a[i];
801 return max;
802 }
803
804
805 public static void testQuickSort() {
806 final int[] a = {1, 2, 3, 5, 4, 3, 2, 5,
807 6, 7};
808 quickSort(a);
809 for (int i = 0; i < a.length; i++)
810 System.out.println(a[i]);
811 }
812
813 public static int numberOfNonZeros(
814 final short[][] k) {
815 final int umax = k.length;
816 final int vmax = k[0].length;
817 int sum = 0;
818
819 for (int x = 0; x < umax; x++)
820 for (int y = 0; y < vmax; y++)
821 if (k[x][y] != 0) sum++;
822 return sum;
823 }
824
825 public static void printMedian(
826 final short[][] k,
827 final String name) {
828 //printMaple(k);
829 System.out.println("\npublic void " +
830 name +
831 "(){\n"
832 + "\tfloat k[][] = {");
833 final int w = k.length;
834 final int h = k[0].length;
835
836 for (int y = 0; y < h; y++) {
837 System.out.print("\t{");
838 for (int x = 0; x < w - 1; x++)
839 System.out.print(k[x][y] + ", ");
840 String s = k[w - 1][y] + "}";
841 if (y < h - 1)
842 s = s + ",";
843 else
844 s = s + "};";
845 System.out.println(s);
846 }
847
848 final String s = "\n\tmedian(k);\n}";
849 System.out.println(s);
850
851 }
852
853
854 }
855