Use internal SNAPSHOT couplings again
[trakem2.git] / TrakEM2_ / src / main / java / mpi / fruitfly / math / General.java
blobc230bfb39022b1032d9fc687f41c73842dc4c843
1 package mpi.fruitfly.math;
3 /**
4 * <p>Title: </p>
6 * <p>Description: </p>
8 * <p>Copyright: Copyright (c) 2007</p>
10 * <p>Company: </p>
12 * <p>License: GPL
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 2
16 * as published by the Free Software Foundation.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * @author Stephan Preibisch
28 * @version 1.0
31 import java.awt.Point;
32 import java.util.Vector;
34 public class General
36 final public static double M_2PI = 2.0 * Math.PI;
38 /**
39 * simple square
40 * @param value
41 * @return value * value
43 public static double sq( double a )
45 return a * a;
48 public static float sq( float a )
50 return a * a;
53 /**
54 * fast floor ld of unsigned v
56 public static int ldu( int v )
58 int c = 0; // c will be lg( v )
61 v >>= 1;
62 c++;
64 while ( v > 1 );
65 return c;
68 /**
69 * return a integer that is flipped in the range [0 ... mod - 1]
71 * @param a the value to be flipped
72 * @param range the size of the range
73 * @return a flipped in range like a ping pong ball
75 public static int flipInRange( int a, int mod )
77 int p = 2 * mod;
78 if ( a < 0 ) a = p + a % p;
79 if ( a >= p ) a = a % p;
80 if ( a >= mod ) a = mod - a % mod - 1;
81 return a;
84 public static int sign (double value)
86 if (value < 0)
87 return -1;
88 else
89 return 1;
92 public static boolean isApproxEqual(double a, double b, double threshold)
94 if (a==b)
95 return true;
97 if (a + threshold > b && a - threshold < b)
98 return true;
99 else
100 return false;
103 public static double computeCorrelationCoefficient(double[] X1, double[] X2)
105 // check for valid input arrays
106 if (X1 == null || X2 == null)
107 return Double.NaN;
109 if (X1.length != X2.length)
110 return Double.NaN;
112 int length = X1.length;
114 if (length == 0)
115 return Double.NaN;
117 // compute averages
118 double avgX1 = 0, avgX2 = 0;
120 for (int pos = 0; pos < length; pos++)
122 avgX1 += X1[pos];
123 avgX2 += X2[pos];
126 avgX1 /= (double)length;
127 avgX2 /= (double)length;
129 // compute covariance and variances of X1 and X2
130 double covar = 0, varX1 = 0, varX2 = 0;
131 double distX1, distX2;
133 for (int pos = 0; pos < length; pos++)
135 distX1 = X1[pos] - avgX1;
136 distX2 = X2[pos] - avgX2;
138 covar += distX1 * distX2;
140 varX1 += distX1 * distX1;
141 varX2 += distX2 * distX2;
144 covar /= (double)length;
145 varX1 /= (double)length;
146 varX2 /= (double)length;
148 varX1 = Math.sqrt(varX1);
149 varX2 = Math.sqrt(varX2);
151 double R = covar / (varX1 * varX2);
153 return R;
156 public static int min(int a, int b)
158 if (a > b)
159 return b;
160 else
161 return a;
165 public static double min(double a, double b)
167 if (a > b)
168 return b;
169 else
170 return a;
173 public static float min(float a, float b)
175 if (a > b)
176 return b;
177 else
178 return a;
181 public static int max(int a, int b)
183 if (a > b)
184 return a;
185 else
186 return b;
189 public static float max(float a, float b)
191 if (a > b)
192 return a;
193 else
194 return b;
196 public static double max(double a, double b)
198 if (a > b)
199 return a;
200 else
201 return b;
205 * Berechnet die Differenz(Offset) der ganzzahligen Eingabe zur naechsten Zweierpotenz.
206 * Bsp: Eingabe 23 -> naechste Potenz 32 -> Ergebnis 9
207 * @param size ganzzahliger Eingabewert
208 * @return int der berechnete Offset
210 public static int offsetToPowerOf2(int size)
212 int offset = 0;
213 int power = 2;
215 while (power < size)
217 power = power * 2;
218 if (power == size)
220 return 0;
222 offset = power - size;
224 return offset;
227 public static double gLog(double z, double c)
229 if (c == 0)
230 return z;
231 else
232 return Log10((z + Math.sqrt(z * z + c * c)) / 2.0);
235 public static double gLogInv(double w, double c)
237 if (c == 0)
238 return w;
239 else
240 return Exp10(w) - (((c * c) * Exp10( -w)) / 4.0);
243 public static double Log10(double x)
245 if (x > 0)
246 return (Math.log(x) / Math.log(10));
247 else
248 return 0;
251 public static double Exp10(double x)
253 return (Math.pow(10, x));
256 public static int pow(int a, int b)
258 if (b == 0)
259 return 1;
261 if (b == 1)
262 return a;
264 int result = a;
266 for (int i = 1; i < b; i++)
267 result *= a;
269 return result;
272 public static double computeTurkeyBiAverage(double[] conc)
274 return computeTurkeyBiAverage(conc, null, 5);
277 public static double computeTurkeyBiAverage(double[] conc, double c)
279 return computeTurkeyBiAverage(conc, null, c);
282 public static double computeTurkeyBiAverage(double[] conc, double[] W, double c)
284 // weighted or non-weighted
285 if (W == null)
287 W = new double[conc.length];
288 for (int i = 0; i < W.length; i++)
289 W[i] = 1;
292 // compute average
293 double avgConc = 0;
294 double sumW = 0;
296 for (int i = 0; i < conc.length; i++)
298 avgConc += W[i] * conc[i];
299 sumW += W[i];
302 avgConc /= sumW;
304 // compute standard deviation
305 double SD = 0;
307 for (int i = 0; i < conc.length; i++)
309 SD += W[i] * Math.pow(conc[i] - avgConc, 2);
312 SD = Math.sqrt(SD / sumW);
314 // compute outlier
315 double u[] = new double[conc.length];
316 double e;
318 for (int i = 0; i < u.length; i++)
320 e = Math.abs(0.01 * conc[i]); // prevent division by zero
321 u[i] = (W[i] * (conc[i] - avgConc)) / ((c * SD) + e);
324 // compute turkey-bi weightening values
326 double tb[] = new double[conc.length];
328 for (int i = 0; i < conc.length; i++)
330 if (Math.abs(u[i]) > 1)
331 tb[i] = 0;
332 else
333 tb[i] = Math.pow(1 - (u[i] * u[i]), 2);
336 // compute result
337 double concTB = 0;
338 double temp = 0;
340 for (int i = 0; i < conc.length; i++)
342 concTB += tb[i] * conc[i];
343 temp += tb[i];
346 return (concTB / temp);
349 public static double computeTurkeyBiMedian(double[] concinput, double c)
351 double[] conc = concinput.clone();
353 // compute median
354 double medianConc = computeMedian(conc);
356 // compute "standard deviation"
357 double SD = 0;
358 double SDValues[] = new double[conc.length];
360 for (int i = 0; i < conc.length; i++)
362 SDValues[i] = Math.abs(conc[i] - medianConc);
365 SD = computeMedian(SDValues);
367 // compute "ausreisser"
368 double u[] = new double[conc.length];
369 double e;
371 for (int i = 0; i < u.length; i++)
373 e = Math.abs(0.01 * conc[i]); // prevent division by zero
374 u[i] = ((conc[i] - medianConc)) / ((c * SD) + e);
377 // compute turkey-bi weightening values
379 double tb[] = new double[conc.length];
381 for (int i = 0; i < conc.length; i++)
383 if (Math.abs(u[i]) > 1)
384 tb[i] = 0;
385 else
386 tb[i] = Math.pow(1 - (u[i] * u[i]), 2);
389 // compute result
390 double concTB = 0;
391 double temp = 0;
393 for (int i = 0; i < conc.length; i++)
395 concTB += tb[i] * conc[i];
396 temp += tb[i];
399 return (concTB / temp);
402 public static float computeTurkeyBiMedian(float[] concinput, float c)
404 float[] conc = concinput.clone();
406 // compute median
407 float medianConc = computeMedian(conc);
409 // compute "standard deviation"
410 float SD = 0;
411 float SDValues[] = new float[conc.length];
413 for (int i = 0; i < conc.length; i++)
415 SDValues[i] = Math.abs(conc[i] - medianConc);
418 SD = computeMedian(SDValues);
420 // compute "ausreisser"
421 float u[] = new float[conc.length];
422 float e;
424 for (int i = 0; i < u.length; i++)
426 e = (float)Math.abs(0.01 * conc[i]); // prevent division by zero
427 u[i] = ((conc[i] - medianConc)) / ((c * SD) + e);
430 // compute turkey-bi weightening values
432 float tb[] = new float[conc.length];
434 for (int i = 0; i < conc.length; i++)
436 if (Math.abs(u[i]) > 1)
437 tb[i] = 0;
438 else
439 tb[i] = (float)Math.pow(1 - (u[i] * u[i]), 2);
442 // compute result
443 float concTB = 0;
444 float temp = 0;
446 for (int i = 0; i < conc.length; i++)
448 concTB += tb[i] * conc[i];
449 temp += tb[i];
452 return (concTB / temp);
455 public static double[] computeTurkeyBiMedianWeights(double[] concinput, double c)
457 double[] conc = concinput.clone();
459 // compute median
460 double medianConc = computeMedian(conc);
462 // compute "standard deviation"
463 double SD = 0;
464 double SDValues[] = new double[conc.length];
466 for (int i = 0; i < conc.length; i++)
468 SDValues[i] = Math.abs(conc[i] - medianConc);
471 SD = computeMedian(SDValues);
473 // compute "ausreisser"
474 double u[] = new double[conc.length];
475 double e;
477 for (int i = 0; i < u.length; i++)
479 e = Math.abs(0.01 * conc[i]); // prevent division by zero
480 u[i] = ((conc[i] - medianConc)) / ((c * SD) + e);
483 // compute turkey-bi weightening values
485 double tb[] = new double[conc.length];
487 for (int i = 0; i < conc.length; i++)
489 if (Math.abs(u[i]) > 1)
490 tb[i] = 0;
491 else
492 tb[i] = Math.pow(1 - (u[i] * u[i]), 2);
495 return tb;
498 public static double computeMedian(double[] values)
500 double temp[] = values.clone();
501 double median;
503 int length = temp.length;
505 quicksort(temp, 0, length - 1);
507 if (length % 2 == 1) //odd length
508 median = temp[length / 2];
509 else //even length
510 median = (temp[length / 2] + temp[(length / 2) - 1]) / 2;
512 temp = null;
513 return median;
516 public static float computeMedian(float[] values)
518 float temp[] = values.clone();
519 float median;
521 int length = temp.length;
523 quicksort(temp, 0, length - 1);
525 if (length % 2 == 1) //odd length
526 median = temp[length / 2];
527 else //even length
528 median = (temp[length / 2] + temp[(length / 2) - 1]) / 2;
530 temp = null;
531 return median;
534 // entropie integral p * log(p)
535 // entropie der joint distr. - entropie 1 - entropie 2
536 // wieviel von der gemeinsamen entropie st
538 // helligkeiten sind ausgang des experimentes
541 public static void quicksort(double[] data, int left, int right)
543 if (data == null || data.length < 2)return;
544 int i = left, j = right;
545 double x = data[(left + right) / 2];
548 while (data[i] < x) i++;
549 while (x < data[j]) j--;
550 if (i <= j)
552 double temp = data[i];
553 data[i] = data[j];
554 data[j] = temp;
555 i++;
556 j--;
559 while (i <= j);
560 if (left < j) quicksort(data, left, j);
561 if (i < right) quicksort(data, i, right);
564 public static void quicksort(float[] data, int left, int right)
566 if (data == null || data.length < 2)return;
567 int i = left, j = right;
568 float x = data[(left + right) / 2];
571 while (data[i] < x) i++;
572 while (x < data[j]) j--;
573 if (i <= j)
575 float temp = data[i];
576 data[i] = data[j];
577 data[j] = temp;
578 i++;
579 j--;
582 while (i <= j);
583 if (left < j) quicksort(data, left, j);
584 if (i < right) quicksort(data, i, right);
587 public static void quicksort(Quicksortable[] data, int left, int right)
589 if (data == null || data.length < 2)return;
590 int i = left, j = right;
592 double x = data[(left + right) / 2].getQuicksortValue();
596 while (data[i].getQuicksortValue() < x) i++;
597 while (x < data[j].getQuicksortValue()) j--;
598 if (i <= j)
600 Quicksortable temp = data[i];
601 data[i] = data[j];
602 data[j] = temp;
603 i++;
604 j--;
607 while (i <= j);
608 if (left < j) quicksort(data, left, j);
609 if (i < right) quicksort(data, i, right);
612 public static void quicksort(Vector data, int left, int right)
614 if (data == null || data.size() < 2)return;
615 int i = left, j = right;
617 double x = ((Quicksortable)data.get((left + right) / 2)).getQuicksortValue();
620 while (((Quicksortable)data.get(i)).getQuicksortValue() < x) i++;
621 while (x < ((Quicksortable)data.get(j)).getQuicksortValue()) j--;
622 if (i <= j)
624 Quicksortable temp = (Quicksortable)data.get(i);
625 data.set( i, data.get( j ) );
626 data.set(j, temp);
627 i++;
628 j--;
631 while (i <= j);
632 if (left < j) quicksort(data, left, j);
633 if (i < right) quicksort(data, i, right);
636 public static void quicksort(float[] data, Point[] sortAlso, int left, int right)
638 if (data == null || data.length < 2)return;
639 int i = left, j = right;
640 float x = data[(left + right) / 2];
643 while (data[i] < x) i++;
644 while (x < data[j]) j--;
645 if (i <= j)
647 float temp = data[i];
648 data[i] = data[j];
649 data[j] = temp;
651 Point temp2 = sortAlso[i];
652 sortAlso[i] = sortAlso[j];
653 sortAlso[j] = temp2;
655 i++;
656 j--;
659 while (i <= j);
660 if (left < j) quicksort(data, sortAlso, left, j);
661 if (i < right) quicksort(data, sortAlso, i, right);
664 public static void quicksort(double[] data, int[] sortAlso, int left, int right)
666 if (data == null || data.length < 2)return;
667 int i = left, j = right;
668 double x = data[(left + right) / 2];
671 while (data[i] < x) i++;
672 while (x < data[j]) j--;
673 if (i <= j)
675 double temp = data[i];
676 data[i] = data[j];
677 data[j] = temp;
679 int temp2 = sortAlso[i];
680 sortAlso[i] = sortAlso[j];
681 sortAlso[j] = temp2;
683 i++;
684 j--;
687 while (i <= j);
688 if (left < j) quicksort(data, sortAlso, left, j);
689 if (i < right) quicksort(data, sortAlso, i, right);