1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 package org.galagosearch.core.eval.stat;
37
38 import java.util.*;
39
40 public class Stat{
41
42
43
44 public static final double FPMIN = 1e-300;
45
46
47
48
49
50 private static int lgfN = 6;
51
52 private static double[] lgfCoeff = {1.000000000190015, 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179E-2, -0.5395239384953E-5};
53
54 private static double lgfGamma = 5.0;
55
56 private static int igfiter = 1000;
57
58 private static double igfeps = 1e-8;
59
60
61
62 private static double histTol = 1.0001D;
63
64
65
66
67 public static double mean(double[] aa){
68 int n = aa.length;
69 double sum=0.0D;
70 for(int i=0; i<n; i++){
71 sum+=aa[i];
72 }
73 return sum/((double)n);
74 }
75
76
77 public static double mean(double[] aa, double[] ww){
78 int n = aa.length;
79 if(n!=ww.length)throw new IllegalArgumentException("length of variable array, " + n + " and length of weight array, " + ww.length + " are different");
80 double sumx=0.0D;
81 double sumw=0.0D;
82 double weight = 0.0D;
83 for(int i=0; i<n; i++){
84 weight = 1.0D/(ww[i]*ww[i]);
85 sumx+=aa[i]*weight;
86 sumw+=weight;
87 }
88 return sumx/sumw;
89 }
90
91
92 public static double mean(float[] aa, float[] ww){
93 int n = aa.length;
94 if(n!=ww.length)throw new IllegalArgumentException("length of variable array, " + n + " and length of weight array, " + ww.length + " are different");
95 float sumx=0.0F;
96 float sumw=0.0F;
97 float weight = 0.0F;
98 for(int i=0; i<n; i++){
99 weight = 1.0F/(ww[i]*ww[i]);
100 sumx+=aa[i]*weight;
101 sumw+=weight;
102 }
103 return sumx/sumw;
104 }
105
106
107 public static double geometricMean(double[] aa){
108 int n = aa.length;
109 double product=1.0D;
110 for(int i=0; i<n; i++)product *= Math.pow(aa[i], 1.0D/((double)n));
111 return product;
112 }
113
114
115 public static float geometricMean(float[] aa){
116 int n = aa.length;
117 float product=1.0F;
118 for(int i=0; i<n; i++)product *= (float)Math.pow(aa[i], 1.0F/((float)n));
119 return product;
120 }
121
122
123 public static double geometricMean(double[] aa, double[] ww){
124 int n = aa.length;
125 double sumW = 0.0D;
126 double[] weight = new double[n];
127 for(int i=0; i<n; i++){
128 weight[i]=1.0D/(ww[i]*ww[i]);
129 sumW += ww[i];
130 }
131 double product=1.0D;
132 for(int i=0; i<n; i++){
133 product *= Math.pow(aa[i], weight[i]/sumW);
134 }
135 return product;
136 }
137
138
139 public static float geometricMean(float[] aa, float[] ww){
140 int n = aa.length;
141 float sumW = 0.0F;
142 float[] weight = new float[n];
143 for(int i=0; i<n; i++){
144 weight[i]=1.0F/(ww[i]*ww[i]);
145 sumW += ww[i];
146 }
147 float product=1.0F;
148 for(int i=0; i<n; i++){
149 product *= (float)Math.pow(aa[i], weight[i]/sumW);
150 }
151 return product;
152 }
153
154
155 public static double harmonicMean(double[] aa){
156 int n = aa.length;
157 double sum = 0.0D;
158 for(int i=0; i<n; i++)sum += 1.0D/aa[i];
159 return (double)n/sum;
160 }
161
162
163 public static float harmonicMean(float[] aa){
164 int n = aa.length;
165 float sum = 0.0F;
166 for(int i=0; i<n; i++)sum += 1.0F/aa[i];
167 return (float)n/sum;
168 }
169
170
171 public static double harmonicMean(double[] aa, double[] ww){
172 int n = aa.length;
173 double sum = 0.0D;
174 double sumW = 0.0D;
175 double[] weight = new double[n];
176 for(int i=0; i<n; i++){
177 sumW += ww[i];
178 weight[i]=1.0D/(ww[i]*ww[i]);
179 }
180 for(int i=0; i<n; i++)sum += ww[i]/aa[i];
181 return sumW/sum;
182 }
183
184
185 public static float harmonicMean(float[] aa, float[] ww){
186 int n = aa.length;
187 float sum = 0.0F;
188 float sumW = 0.0F;
189 float[] weight = new float[n];
190 for(int i=0; i<n; i++){
191 sumW += ww[i];
192 weight[i]=1.0F/(ww[i]*ww[i]);
193 }
194 for(int i=0; i<n; i++)sum += ww[i]/aa[i];
195 return sumW/sum;
196 }
197
198
199 public static double generalisedMean(double[] aa, double m){
200 int n = aa.length;
201 double sum=0.0D;
202 for(int i=0; i<n; i++){
203 sum += Math.pow(aa[i],m);
204 }
205 return Math.pow(sum/((double)n), 1.0D/m);
206 }
207
208
209 public static float generalisedMean(float[] aa, float m){
210 int n = aa.length;
211 float sum=0.0F;
212 for(int i=0; i<n; i++){
213 sum += Math.pow(aa[i],m);
214 }
215 return (float)Math.pow(sum/((float)n), 1.0F/m);
216 }
217
218
219 public static double interQuartileMean(double[] aa){
220 int n = aa.length;
221 if(n<4)throw new IllegalArgumentException("At least 4 array elements needed");
222 double[] bb = Fmath.selectionSort(aa);
223 double sum = 0.0D;
224 for(int i=n/4; i<3*n/4; i++)sum += bb[i];
225 return 2.0*sum/(double)(n);
226 }
227
228
229 public static float interQuartileMean(float[] aa){
230 int n = aa.length;
231 if(n<4)throw new IllegalArgumentException("At least 4 array elements needed");
232 float[] bb = Fmath.selectionSort(aa);
233 float sum = 0.0F;
234 for(int i=n/4; i<3*n/4; i++)sum += bb[i];
235 return 2.0F*sum/(float)(n);
236 }
237
238
239 public static double rms(double[] aa){
240 int n = aa.length;
241 double sum=0.0D;
242 for(int i=0; i<n; i++){
243 sum+=aa[i]*aa[i];
244 }
245 return Math.sqrt(sum/((double)n));
246 }
247
248
249 public static float rms(float[] aa){
250 int n = aa.length;
251 float sum = 0.0F;
252 for(int i=0; i<n; i++){
253 sum+=aa[i]*aa[i];
254 }
255 sum /= (float)n;
256
257 return (float)Math.sqrt(sum);
258 }
259
260
261 public static float mean(float[] aa){
262 int n = aa.length;
263 float sum=0.0F;
264 for(int i=0; i<n; i++){
265 sum+=aa[i];
266 }
267 return sum/((float)n);
268 }
269
270
271 public static double mean(int[] aa){
272 int n = aa.length;
273 double sum=0.0D;
274 for(int i=0; i<n; i++){
275 sum+=(double)aa[i];
276 }
277 return sum/((double)n);
278 }
279
280
281 public static double mean(long[] aa){
282 int n = aa.length;
283 double sum=0.0D;
284 for(int i=0; i<n; i++){
285 sum+=(double)aa[i];
286 }
287 return sum/((double)n);
288 }
289
290
291 public static double median(double[] aa){
292 int n = aa.length;
293 int nOverTwo = n/2;
294 double med = 0.0D;
295 double[] bb = Fmath.selectionSort(aa);
296 if(Fmath.isOdd(n)){
297 med = bb[nOverTwo];
298 }
299 else{
300 med = (bb[nOverTwo-1]+bb[nOverTwo])/2.0D;
301 }
302
303 return med;
304 }
305
306
307 public static float median(float[] aa){
308 int n = aa.length;
309 int nOverTwo = n/2;
310 float med = 0.0F;
311 float[] bb = Fmath.selectionSort(aa);
312 if(Fmath.isOdd(n)){
313 med = bb[nOverTwo];
314 }
315 else{
316 med = (bb[nOverTwo-1]+bb[nOverTwo])/2.0F;
317 }
318
319 return med;
320 }
321
322
323 public static double median(int[] aa){
324 int n = aa.length;
325 int nOverTwo = n/2;
326 double med = 0.0D;
327 int[] bb = Fmath.selectionSort(aa);
328 if(Fmath.isOdd(n)){
329 med = (double)bb[nOverTwo];
330 }
331 else{
332 med = (double)(bb[nOverTwo-1]+bb[nOverTwo])/2.0D;
333 }
334
335 return med;
336 }
337
338
339 public static double median(long[] aa){
340 int n = aa.length;
341 int nOverTwo = n/2;
342 double med = 0.0D;
343 long[] bb = Fmath.selectionSort(aa);
344 if(Fmath.isOdd(n)){
345 med = (double)bb[nOverTwo];
346 }
347 else{
348 med = (double)(bb[nOverTwo-1]+bb[nOverTwo])/2.0D;
349 }
350
351 return med;
352 }
353
354
355 public static double standardDeviation(double[] aa){
356 return Math.sqrt(variance(aa));
357 }
358
359
360 public static float standardDeviation(float[] aa){
361 return (float)Math.sqrt(variance(aa));
362 }
363
364
365 public static double standardDeviation(int[] aa){
366 return Math.sqrt(variance(aa));
367 }
368
369
370 public static double standardDeviation(long[] aa){
371 return Math.sqrt(variance(aa));
372 }
373
374
375 public static double standardDeviation(double[] aa, double[] ww){
376 if(aa.length!=ww.length)throw new IllegalArgumentException("length of variable array, " + aa.length + " and length of weight array, " + ww.length + " are different");
377 return Math.sqrt(variance(aa, ww));
378 }
379
380
381 public static float standardDeviation(float[] aa, float[] ww){
382 if(aa.length!=ww.length)throw new IllegalArgumentException("length of variable array, " + aa.length + " and length of weight array, " + ww.length + " are different");
383 return (float)Math.sqrt(variance(aa, ww));
384 }
385
386
387
388
389 public static double volatilityLogChange(double[] array){
390 int n = array.length-1;
391 double[] change = new double[n];
392 for(int i=0; i<n; i++)change[i] = Math.log(array[i+1]/array[i]);
393 return Stat.standardDeviation(change);
394 }
395
396
397 public static float volatilityLogChange(float[] array){
398 int n = array.length-1;
399 float[] change = new float[n];
400 for(int i=0; i<n; i++)change[i] = (float)Math.log(array[i+1]/array[i]);
401 return Stat.standardDeviation(change);
402 }
403
404
405 public static double volatilityPerCentChange(double[] array){
406 int n = array.length-1;
407 double[] change = new double[n];
408 for(int i=0; i<n; i++)change[i] = (array[i+1] - array[i])*100.0D/array[i];
409 return Stat.standardDeviation(change);
410 }
411
412
413 public static double volatilityPerCentChange(float[] array){
414 int n = array.length-1;
415 float[] change = new float[n];
416 for(int i=0; i<n; i++)change[i] = (array[i+1] - array[i])*100.0F/array[i];
417 return Stat.standardDeviation(change);
418 }
419
420
421 public static double coefficientOfVariation(double[] array){
422 return 100.0D*Stat.standardDeviation(array)/Math.abs(Stat.mean(array));
423 }
424
425
426 public static float coefficientOfVariation(float[] array){
427 return 100.0F*Stat.standardDeviation(array)/Math.abs(Stat.mean(array));
428 }
429
430
431 public static double[] subtractMean(double[] array){
432 int n = array.length;
433 double mean = Stat.mean(array);
434 double[] arrayMinusMean = new double[n];
435 for(int i=0; i<n; i++)arrayMinusMean[i] = array[i] - mean;
436
437 return arrayMinusMean;
438 }
439
440
441 public static float[] subtractMean(float[] array){
442 int n = array.length;
443 float mean = Stat.mean(array);
444 float[] arrayMinusMean = new float[n];
445 for(int i=0; i<n; i++)arrayMinusMean[i] = array[i] - mean;
446
447 return arrayMinusMean;
448 }
449
450
451 public static double variance(double[] aa){
452 int n = aa.length;
453 double sum=0.0D, mean=0.0D;
454 for(int i=0; i<n; i++){
455 sum+=aa[i];
456 }
457 mean=sum/((double)n);
458 sum=0.0D;
459 for(int i=0; i<n; i++){
460 sum+=Fmath.square(aa[i]-mean);
461 }
462 return sum/((double)(n-1));
463 }
464
465
466 public static float variance(float[] aa){
467 int n = aa.length;
468 float sum=0.0F, mean=0.0F;
469 for(int i=0; i<n; i++){
470 sum+=aa[i];
471 }
472 mean=sum/((float)n);
473 sum=0.0F;
474 for(int i=0; i<n; i++){
475 sum+=Fmath.square(aa[i]-mean);
476 }
477 return sum/((float)(n-1));
478 }
479
480
481 public static double variance(int[] aa){
482 int n = aa.length;
483 double sum=0.0D, mean=0.0D;
484 for(int i=0; i<n; i++){
485 sum+=(double)aa[i];
486 }
487 mean=sum/((double)n);
488 sum=0.0D;
489 for(int i=0; i<n; i++){
490 sum+=Fmath.square((double)aa[i]-mean);
491 }
492 return sum/((double)(n-1));
493 }
494
495
496 public static double variance(long[] aa){
497 int n = aa.length;
498 double sum=0.0D, mean=0.0D;
499 for(int i=0; i<n; i++){
500 sum+=(double)aa[i];
501 }
502 mean=sum/((double)n);
503 sum=0.0D;
504 for(int i=0; i<n; i++){
505 sum+=Fmath.square((double)aa[i]-mean);
506 }
507 return sum/((double)(n-1));
508 }
509
510
511 public static double variance(double[] aa, double[] ww){
512 int n = aa.length;
513 if(n!=ww.length)throw new IllegalArgumentException("length of variable array, " + n + " and length of weight array, " + ww.length + " are different");
514 double sumx=0.0D, sumw=0.0D, mean=0.0D;
515 double[] weight = new double[n];
516 for(int i=0; i<n; i++){
517 sumx+=aa[i];
518 weight[i]=1.0D/(ww[i]*ww[i]);
519 sumw+=weight[i];
520 }
521 mean=sumx/sumw;
522 sumx=0.0D;
523 for(int i=0; i<n; i++){
524 sumx+=weight[i]*Fmath.square(aa[i]-mean);
525 }
526 return sumx*(double)(n)/((double)(n-1)*sumw);
527 }
528
529
530 public static float variance(float[] aa, float[] ww){
531 int n = aa.length;
532 if(n!=ww.length)throw new IllegalArgumentException("length of variable array, " + n + " and length of weight array, " + ww.length + " are different");
533 float sumx=0.0F, sumw=0.0F, mean=0.0F;
534 float[] weight = new float[n];
535 for(int i=0; i<n; i++){
536 sumx+=aa[i];
537 weight[i]=1.0F/(ww[i]*ww[i]);
538 sumw+=weight[i];
539 }
540 mean=sumx/sumw;
541 sumx=0.0F;
542 for(int i=0; i<n; i++){
543 sumx+=weight[i]*Fmath.square(aa[i]-mean);
544 }
545 return sumx*(float)(n)/((float)(n-1)*sumw);
546 }
547
548
549 public static double covariance(double[] xx, double[] yy){
550 int n = xx.length;
551 if(n!=yy.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of y array, " + yy.length + " are different");
552
553 double sumx=0.0D, meanx=0.0D;
554 double sumy=0.0D, meany=0.0D;
555 for(int i=0; i<n; i++){
556 sumx+=xx[i];
557 sumy+=yy[i];
558 }
559 meanx=sumx/((double)n);
560 meany=sumy/((double)n);
561 double sum=0.0D;
562 for(int i=0; i<n; i++){
563 sum+=(xx[i]-meanx)*(yy[i]-meany);
564 }
565 return sum/((double)(n-1));
566 }
567
568
569 public static float covariance(float[] xx, float[] yy){
570 int n = xx.length;
571 if(n!=yy.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of y array, " + yy.length + " are different");
572
573 float sumx=0.0F, meanx=0.0F;
574 float sumy=0.0F, meany=0.0F;
575 for(int i=0; i<n; i++){
576 sumx+=xx[i];
577 sumy+=yy[i];
578 }
579 meanx=sumx/((float)n);
580 meany=sumy/((float)n);
581 float sum=0.0F;
582 for(int i=0; i<n; i++){
583 sum+=(xx[i]-meanx)*(yy[i]-meany);
584 }
585 return sum/((float)(n-1));
586 }
587
588
589 public static double covariance(int[] xx, int[] yy){
590 int n = xx.length;
591 if(n!=yy.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of y array, " + yy.length + " are different");
592
593 double sumx=0.0D, meanx=0.0D;
594 double sumy=0.0D, meany=0.0D;
595 for(int i=0; i<n; i++){
596 sumx+=(double)xx[i];
597 sumy+=(double)yy[i];
598 }
599 meanx=sumx/((double)n);
600 meany=sumy/((double)n);
601 double sum=0.0D;
602 for(int i=0; i<n; i++){
603 sum+=((double)xx[i]-meanx)*((double)yy[i]-meany);
604 }
605 return sum/((double)(n-1));
606 }
607
608
609 public static double covariance(long[] xx, long[] yy){
610 int n = xx.length;
611 if(n!=yy.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of y array, " + yy.length + " are different");
612
613 double sumx=0.0D, meanx=0.0D;
614 double sumy=0.0D, meany=0.0D;
615 for(int i=0; i<n; i++){
616 sumx+=(double)xx[i];
617 sumy+=(double)yy[i];
618 }
619 meanx=sumx/((double)n);
620 meany=sumy/((double)n);
621 double sum=0.0D;
622 for(int i=0; i<n; i++){
623 sum+=((double)xx[i]-meanx)*((double)yy[i]-meany);
624 }
625 return sum/((double)(n-1));
626 }
627
628
629 public static double covariance(double[] xx, double[] yy, double[] ww){
630 int n = xx.length;
631 if(n!=yy.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of y array, " + yy.length + " are different");
632 if(n!=ww.length)throw new IllegalArgumentException("length of x variable array, " + n + " and length of weight array, " + yy.length + " are different");
633 double sumx=0.0D, sumy=0.0D, sumw=0.0D, meanx=0.0D, meany=0.0D;
634 double[] weight = new double[n];
635 for(int i=0; i<n; i++){
636 sumx+=xx[i];
637 sumy+=yy[i];
638 weight[i]=1.0D/(ww[i]*ww[i]);
639 sumw+=weight[i];
640 }
641 meanx=sumx/sumw;
642 meany=sumy/sumw;
643
644 double sum=0.0D;
645 for(int i=0; i<n; i++){
646 sum+=weight[i]*(xx[i]-meanx)*(yy[i]-meany);
647 }
648 return sum*(double)(n)/((double)(n-1)*sumw);
649 }
650
651
652
653
654
655 public static double gamma(double x){
656
657 double xcopy = x;
658 double first = x + lgfGamma + 0.5;
659 double second = lgfCoeff[0];
660 double fg = 0.0D;
661
662 if(x>=0.0){
663 if(x>=1.0D && x-(int)x==0.0D){
664 fg = Stat.factorial(x)/x;
665 }
666 else{
667 first = Math.pow(first, x + 0.5)*Math.exp(-first);
668 for(int i=1; i<=lgfN; i++)second += lgfCoeff[i]/++xcopy;
669 fg = first*Math.sqrt(2.0*Math.PI)*second/x;
670 }
671 }
672 else{
673 fg = -Math.PI/(x*Stat.gamma(-x)*Math.sin(Math.PI*x));
674 }
675 return fg;
676 }
677
678
679 public static double getLanczosGamma(){
680 return Stat.lgfGamma;
681 }
682
683
684 public static int getLanczosN(){
685 return Stat.lgfN;
686 }
687
688
689 public static double[] getLanczosCoeff(){
690 int n = Stat.getLanczosN()+1;
691 double[] coef = new double[n];
692 for(int i=0; i<n; i++){
693 coef[i] = Stat.lgfCoeff[i];
694 }
695 return coef;
696 }
697
698
699 public static double getFpmin(){
700 return Stat.FPMIN;
701 }
702
703
704
705 public static double logGamma(double x){
706 double xcopy = x;
707 double fg = 0.0D;
708 double first = x + lgfGamma + 0.5;
709 double second = lgfCoeff[0];
710
711 if(x>=0.0){
712 if(x>=1.0 && x-(int)x==0.0){
713 fg = Stat.logFactorial(x)-Math.log(x);
714 }
715 else{
716 first -= (x + 0.5)*Math.log(first);
717 for(int i=1; i<=lgfN; i++)second += lgfCoeff[i]/++xcopy;
718 fg = Math.log(Math.sqrt(2.0*Math.PI)*second/x) - first;
719 }
720 }
721 else{
722 fg = Math.PI/(Stat.gamma(1.0D-x)*Math.sin(Math.PI*x));
723
724 if(fg!=1.0/0.0 && fg!=-1.0/0.0){
725 if(fg<0){
726 throw new IllegalArgumentException("\nThe gamma function is negative");
727 }
728 else{
729 fg = Math.log(fg);
730 }
731 }
732 }
733 return fg;
734 }
735
736
737 public static double incompleteGamma(double a, double x){
738 if(a<0.0D || x<0.0D)throw new IllegalArgumentException("\nFunction defined only for a >= 0 and x>=0");
739 double igf = 0.0D;
740
741 if(x < a+1.0D){
742
743 igf = incompleteGammaSer(a, x);
744 }
745 else{
746
747 igf = incompleteGammaFract(a, x);
748 }
749 return igf;
750 }
751
752
753
754 public static double incompleteGammaComplementary(double a, double x){
755 if(a<0.0D || x<0.0D)throw new IllegalArgumentException("\nFunction defined only for a >= 0 and x>=0");
756 double igf = 0.0D;
757
758 if(x!=0.0D){
759 if(x==1.0D/0.0D)
760 {
761 igf=1.0D;
762 }
763 else{
764 if(x < a+1.0D){
765
766 igf = 1.0D - incompleteGammaSer(a, x);
767 }
768 else{
769
770 igf = 1.0D - incompleteGammaFract(a, x);
771 }
772 }
773 }
774 return igf;
775 }
776
777
778
779 public static double incompleteGammaSer(double a, double x){
780 if(a<0.0D || x<0.0D)throw new IllegalArgumentException("\nFunction defined only for a >= 0 and x>=0");
781 if(x>=a+1) throw new IllegalArgumentException("\nx >= a+1 use Continued Fraction Representation");
782
783 int i = 0;
784 double igf = 0.0D;
785 boolean check = true;
786
787 double acopy = a;
788 double sum = 1.0/a;
789 double incr = sum;
790 double loggamma = Stat.logGamma(a);
791
792 while(check){
793 ++i;
794 ++a;
795 incr *= x/a;
796 sum += incr;
797 if(Math.abs(incr) < Math.abs(sum)*Stat.igfeps){
798 igf = sum*Math.exp(-x+acopy*Math.log(x)- loggamma);
799 check = false;
800 }
801 if(i>=Stat.igfiter){
802 check=false;
803 igf = sum*Math.exp(-x+acopy*Math.log(x)- loggamma);
804 System.out.println("\nMaximum number of iterations were exceeded in Stat.incompleteGammaSer().\nCurrent value returned.\nIncrement = "+String.valueOf(incr)+".\nSum = "+String.valueOf(sum)+".\nTolerance = "+String.valueOf(igfeps));
805 }
806 }
807 return igf;
808 }
809
810
811
812
813
814
815
816 public static double incompleteGammaFract(double a, double x){
817 if(a<0.0D || x<0.0D)throw new IllegalArgumentException("\nFunction defined only for a >= 0 and x>=0");
818 if(x<a+1) throw new IllegalArgumentException("\nx < a+1 Use Series Representation");
819
820 int i = 0;
821 double ii = 0;
822 double igf = 0.0D;
823 boolean check = true;
824
825 double loggamma = Stat.logGamma(a);
826 double numer = 0.0D;
827 double incr = 0.0D;
828 double denom = x - a + 1.0D;
829 double first = 1.0D/denom;
830 double term = 1.0D/FPMIN;
831 double prod = first;
832
833 while(check){
834 ++i;
835 ii = (double)i;
836 numer = -ii*(ii - a);
837 denom += 2.0D;
838 first = numer*first + denom;
839 if(Math.abs(first) < Stat.FPMIN){
840 first = Stat.FPMIN;
841 }
842 term = denom + numer/term;
843 if(Math.abs(term) < Stat.FPMIN){
844 term = Stat.FPMIN;
845 }
846 first = 1.0D/first;
847 incr = first*term;
848 prod *= incr;
849 if(Math.abs(incr - 1.0D) < igfeps)check = false;
850 if(i>=Stat.igfiter){
851 check=false;
852 System.out.println("\nMaximum number of iterations were exceeded in Stat.incompleteGammaFract().\nCurrent value returned.\nIncrement - 1 = "+String.valueOf(incr-1)+".\nTolerance = "+String.valueOf(igfeps));
853 }
854 }
855 igf = 1.0D - Math.exp(-x+a*Math.log(x)-loggamma)*prod;
856 return igf;
857 }
858
859
860 public static void setIncGammaMaxIter(int igfiter){
861 Stat.igfiter=igfiter;
862 }
863
864
865 public static int getIncGammaMaxIter(){
866 return Stat.igfiter;
867 }
868
869
870 public static void setIncGammaTol(double igfeps){
871 Stat.igfeps=igfeps;
872 }
873
874
875 public static double getIncGammaTol(){
876 return Stat.igfeps;
877 }
878
879
880 public static double beta(double z, double w){
881 return Math.exp(logGamma(z) + logGamma(w) - logGamma(z + w));
882 }
883
884
885
886 public static double incompleteBeta(double z, double w, double x){
887 if(x<0.0D || x>1.0D)throw new IllegalArgumentException("Argument x, "+x+", must be lie between 0 and 1 (inclusive)");
888 double ibeta = 0.0D;
889 if(x==0.0D){
890 ibeta=0.0D;
891 }
892 else{
893 if(x==1.0D){
894 ibeta=1.0D;
895 }
896 else{
897
898 ibeta = Math.exp(Stat.logGamma(z+w) - Stat.logGamma(z) - logGamma(w) + z*Math.log(x) + w*Math.log(1.0D-x));
899
900 if(x < (z+1.0D)/(z+w+2.0D)){
901 ibeta = ibeta*Stat.contFract(z, w, x)/z;
902 }
903 else{
904
905 ibeta = 1.0D - ibeta*Stat.contFract(w, z, 1.0D-x)/w;
906 }
907 }
908 }
909 return ibeta;
910 }
911
912
913
914 public static double contFract(double a, double b, double x){
915 int maxit = 500;
916 double eps = 3.0e-7;
917 double aplusb = a + b;
918 double aplus1 = a + 1.0D;
919 double aminus1 = a - 1.0D;
920 double c = 1.0D;
921 double d = 1.0D - aplusb*x/aplus1;
922 if(Math.abs(d)<Stat.FPMIN)d = FPMIN;
923 d = 1.0D/d;
924 double h = d;
925 double aa = 0.0D;
926 double del = 0.0D;
927 int i=1, i2=0;
928 boolean test=true;
929 while(test){
930 i2=2*i;
931 aa = i*(b-i)*x/((aminus1+i2)*(a+i2));
932 d = 1.0D + aa*d;
933 if(Math.abs(d)<Stat.FPMIN)d = FPMIN;
934 c = 1.0D + aa/c;
935 if(Math.abs(c)<Stat.FPMIN)c = FPMIN;
936 d = 1.0D/d;
937 h *= d*c;
938 aa = -(a+i)*(aplusb+i)*x/((a+i2)*(aplus1+i2));
939 d = 1.0D + aa*d;
940 if(Math.abs(d)<Stat.FPMIN)d = FPMIN;
941 c = 1.0D + aa/c;
942 if(Math.abs(c)<Stat.FPMIN)c = FPMIN;
943 d = 1.0D/d;
944 del = d*c;
945 h *= del;
946 i++;
947 if(Math.abs(del-1.0D) < eps)test=false;
948 if(i>maxit){
949 test=false;
950 System.out.println("Maximum number of iterations ("+maxit+") exceeded in Stat.contFract in Stat.incomplete Beta");
951 }
952 }
953 return h;
954
955 }
956
957
958 public static double erf(double x){
959 double erf = 0.0D;
960 if(x!=0.0){
961 if(x==1.0D/0.0D){
962 erf = 1.0D;
963 }
964 else{
965 if(x>=0){
966 erf = Stat.incompleteGamma(0.5, x*x);
967 }
968 else{
969 erf = -Stat.incompleteGamma(0.5, x*x);
970 }
971 }
972 }
973 return erf;
974 }
975
976
977 public static double erfc(double x){
978 double erfc = 1.0D;
979 if(x!=0.0){
980 if(x==1.0D/0.0D){
981 erfc = 0.0D;
982 }
983 else{
984 if(x>=0){
985 erfc = 1.0D - Stat.incompleteGamma(0.5, x*x);
986 }
987 else{
988 erfc = 1.0D + Stat.incompleteGamma(0.5, x*x);
989 }
990 }
991 }
992 return erfc;
993 }
994
995
996
997
998 public static double normalProb(double mean, double sd, double upperlimit){
999 double arg = (upperlimit - mean)/(sd*Math.sqrt(2.0));
1000 return (1.0D + Stat.erf(arg))/2.0D;
1001 }
1002
1003
1004
1005
1006 public static double gaussianProb(double mean, double sd, double upperlimit){
1007 double arg = (upperlimit - mean)/(sd*Math.sqrt(2.0));
1008 return (1.0D + Stat.erf(arg))/2.0D;
1009 }
1010
1011
1012
1013
1014 public static double normalProb(double mean, double sd, double lowerlimit, double upperlimit){
1015 double arg1 = (lowerlimit - mean)/(sd*Math.sqrt(2.0));
1016 double arg2 = (upperlimit - mean)/(sd*Math.sqrt(2.0));
1017
1018 return (Stat.erf(arg2)-Stat.erf(arg1))/2.0D;
1019 }
1020
1021
1022
1023
1024 public static double gaussianProb(double mean, double sd, double lowerlimit, double upperlimit){
1025 double arg1 = (lowerlimit - mean)/(sd*Math.sqrt(2.0));
1026 double arg2 = (upperlimit - mean)/(sd*Math.sqrt(2.0));
1027
1028 return (Stat.erf(arg2)-Stat.erf(arg1))/2.0D;
1029 }
1030
1031
1032
1033 public static double normal(double mean, double sd, double x){
1034 return Math.exp(-Fmath.square((x - mean)/sd)/2.0)/(sd*Math.sqrt(2.0D*Math.PI));
1035 }
1036
1037
1038
1039 public static double gaussian(double mean, double sd, double x){
1040 return Math.exp(-Fmath.square((x - mean)/sd)/2.0)/(sd*Math.sqrt(2.0D*Math.PI));
1041 }
1042
1043
1044
1045 public static double[] normalRand(double mean, double sd, int n){
1046 double[] ran = new double[n];
1047 Random rr = new Random();
1048 for(int i=0; i<n; i++){
1049 ran[i]=rr.nextGaussian();
1050 ran[i] = ran[i]*sd+mean;
1051 }
1052 return ran;
1053 }
1054
1055
1056
1057 public static double[] gaussianRand(double mean, double sd, int n){
1058 double[] ran = new double[n];
1059 Random rr = new Random();
1060 for(int i=0; i<n; i++){
1061 ran[i]=rr.nextGaussian();
1062 ran[i] = ran[i]*sd+mean;
1063 }
1064 return ran;
1065 }
1066
1067
1068
1069 public static double[] normalRand(double mean, double sd, int n, long seed){
1070 double[] ran = new double[n];
1071 Random rr = new Random(seed);
1072 for(int i=0; i<n; i++){
1073 ran[i]=rr.nextGaussian();
1074 ran[i] = ran[i]*sd+mean;
1075 }
1076 return ran;
1077 }
1078
1079
1080
1081 public static double[] gaussianRand(double mean, double sd, int n, long seed){
1082 double[] ran = new double[n];
1083 Random rr = new Random(seed);
1084 for(int i=0; i<n; i++){
1085 ran[i]=rr.nextGaussian();
1086 ran[i] = ran[i]*sd+mean;
1087 }
1088 return ran;
1089 }
1090
1091
1092
1093
1094
1095
1096 public static double logisticProb(double mu, double beta, double upperlimit){
1097 return 0.5D*(1.0D + Math.tanh((upperlimit - mu)/(2.0D*beta)));
1098 }
1099
1100
1101
1102
1103
1104 public static double logisticProb(double mu, double beta, double lowerlimit, double upperlimit){
1105 double arg1 = 0.5D*(1.0D + Math.tanh((lowerlimit - mu)/(2.0D*beta)));
1106 double arg2 = 0.5D*(1.0D + Math.tanh((upperlimit - mu)/(2.0D*beta)));
1107 return arg2 - arg1;
1108 }
1109
1110
1111
1112 public static double logistic(double mu, double beta, double x){
1113 return Fmath.square(Fmath.sech((x - mu)/(2.0D*beta)))/(4.0D*beta);
1114 }
1115
1116
1117
1118 public static double[] logisticRand(double mu, double beta, int n){
1119 double[] ran = new double[n];
1120 Random rr = new Random();
1121 for(int i=0; i<n; i++){
1122 ran[i] = 2.0D*beta*Fmath.atanh(2.0D*rr.nextDouble() - 1.0D) + mu;
1123 }
1124 return ran;
1125 }
1126
1127
1128
1129 public static double[] logisticRand(double mu, double beta, int n, long seed){
1130 double[] ran = new double[n];
1131 Random rr = new Random(seed);
1132 for(int i=0; i<n; i++){
1133 ran[i] = 2.0D*beta*Fmath.atanh(2.0D*rr.nextDouble() - 1.0D) + mu;
1134 }
1135 return ran;
1136 }
1137
1138
1139 public static double logisticMean(double mu){
1140 return mu;
1141 }
1142
1143
1144
1145 public static double logisticStandDev(double beta){
1146 return Math.sqrt(Fmath.square(Math.PI*beta)/3.0D);
1147 }
1148
1149
1150 public static double logisticMode(double mu){
1151 return mu;
1152 }
1153
1154
1155 public static double logisticMedian(double mu){
1156 return mu;
1157 }
1158
1159
1160
1161 public static double lorentzianProb(double mu, double gamma, double upperlimit){
1162 double arg = (upperlimit - mu)/(gamma/2.0D);
1163 return (1.0D/Math.PI)*(Math.atan(arg)+Math.PI/2.0);
1164 }
1165
1166
1167
1168 public static double lorentzianProb(double mu, double gamma, double lowerlimit, double upperlimit){
1169 double arg1 = (upperlimit - mu)/(gamma/2.0D);
1170 double arg2 = (lowerlimit - mu)/(gamma/2.0D);
1171 return (1.0D/Math.PI)*(Math.atan(arg1)-Math.atan(arg2));
1172 }
1173
1174
1175
1176
1177
1178 public static double poissonProb(int k, double mean){
1179 if(k<1)throw new IllegalArgumentException("k must be an integer greater than or equal to 1");
1180 return Stat.incompleteGammaComplementary((double) k, mean);
1181 }
1182
1183
1184
1185
1186 public static double poisson(int k, double mean){
1187 if(k<0)throw new IllegalArgumentException("k must be an integer greater than or equal to 0");
1188 return Math.pow(mean, k)*Math.exp(-mean)/Stat.factorial((double)k);
1189 }
1190
1191
1192
1193
1194 public static double[] poissonRand(double mean, int n){
1195
1196 Random rr = new Random();
1197 double[] ran = poissonRandCalc(rr, mean, n);
1198 return ran;
1199 }
1200
1201
1202
1203
1204 public static double[] poissonRand(double mean, int n, long seed){
1205
1206 Random rr = new Random(seed);
1207 double[] ran = poissonRandCalc(rr, mean, n);
1208 return ran;
1209 }
1210
1211
1212 private static double[] poissonRandCalc(Random rr, double mean, int n){
1213 double[] ran = new double[n];
1214 double oldm = -1.0D;
1215 double expt = 0.0D;
1216 double em = 0.0D;
1217 double term = 0.0D;
1218 double sq = 0.0D;
1219 double lnMean = 0.0D;
1220 double yDev = 0.0D;
1221
1222 if(mean < 12.0D){
1223 for(int i=0; i<n; i++){
1224 if(mean != oldm){
1225 oldm = mean;
1226 expt = Math.exp(-mean);
1227 }
1228 em = -1.0D;
1229 term = 1.0D;
1230 do{
1231 ++em;
1232 term *= rr.nextDouble();
1233 }while(term>expt);
1234 ran[i] = em;
1235 }
1236 }
1237 else{
1238 for(int i=0; i<n; i++){
1239 if(mean != oldm){
1240 oldm = mean;
1241 sq = Math.sqrt(2.0D*mean);
1242 lnMean = Math.log(mean);
1243 expt = lnMean - Stat.logGamma(mean+1.0D);
1244 }
1245 do{
1246 do{
1247 yDev = Math.tan(Math.PI*rr.nextDouble());
1248 em = sq*yDev+mean;
1249 }while(em<0.0D);
1250 em = Math.floor(em);
1251 term = 0.9D*(1.0D+yDev*yDev)*Math.exp(em*lnMean - Stat.logGamma(em+1.0D)-expt);
1252 }while(rr.nextDouble()>term);
1253 ran[i] = em;
1254 }
1255 }
1256 return ran;
1257 }
1258
1259
1260
1261
1262
1263 public static double chiSquareProb(double chiSquare, int nu){
1264 return Stat.incompleteGamma((double)nu/2.0D, chiSquare/2.0D);
1265 }
1266
1267
1268 public static double chiSquare(double[] observed, double[] expected, double[] variance){
1269 int nObs = observed.length;
1270 int nExp = expected.length;
1271 int nVar = variance.length;
1272 if(nObs!=nExp)throw new IllegalArgumentException("observed array length does not equal the expected array length");
1273 if(nObs!=nVar)throw new IllegalArgumentException("observed array length does not equal the variance array length");
1274 double chi = 0.0D;
1275 for(int i=0; i<nObs; i++){
1276 chi += Fmath.square(observed[i]-expected[i])/variance[i];
1277 }
1278 return chi;
1279 }
1280
1281
1282
1283
1284 public static double chiSquareFreq(double[] observedFreq, double[] expectedFreq){
1285 int nObs = observedFreq.length;
1286 int nExp = expectedFreq.length;
1287 if(nObs!=nExp)throw new IllegalArgumentException("observed array length does not equal the expected array length");
1288 double chi = 0.0D;
1289 for(int i=0; i<nObs; i++){
1290 chi += Fmath.square(observedFreq[i]-expectedFreq[i])/expectedFreq[i];
1291 }
1292 return chi;
1293 }
1294
1295
1296
1297
1298 public static double chiSquareFreq(int[] observedFreq, int[] expectedFreq){
1299 int nObs = observedFreq.length;
1300 int nExp = expectedFreq.length;
1301 if(nObs!=nExp)throw new IllegalArgumentException("observed array length does not equal the expected array length");
1302 double[] observ = new double[nObs];
1303 double[] expect = new double[nObs];
1304 for(int i=0; i<nObs; i++){
1305 observ[i] = (int)observedFreq[i];
1306 expect[i] = (int)expectedFreq[i];
1307 }
1308
1309 return chiSquareFreq(observ, expect);
1310 }
1311
1312
1313 public static double binomialProb(double p, int n, int k){
1314 if(p<0.0D || p>1.0D)throw new IllegalArgumentException("\np must lie between 0 and 1");
1315 if(k<0 || n<0)throw new IllegalArgumentException("\nn and k must be greater than or equal to zero");
1316 if(k>n)throw new IllegalArgumentException("\nk is greater than n");
1317 return Stat.incompleteBeta(k, n-k+1, p);
1318 }
1319
1320
1321 public static double binomial(double p, int n, int k){
1322 if(k<0 || n<0)throw new IllegalArgumentException("\nn and k must be greater than or equal to zero");
1323 if(k>n)throw new IllegalArgumentException("\nk is greater than n");
1324 return Math.floor(0.5D + Math.exp(Stat.logFactorial(n) - Stat.logFactorial(k) - Stat.logFactorial(n-k)))*Math.pow(p, k)*Math.pow(1.0D - p, n - k);
1325 }
1326
1327
1328 public static double binomialCoeff(int n, int k){
1329 if(k<0 || n<0)throw new IllegalArgumentException("\nn and k must be greater than or equal to zero");
1330 if(k>n)throw new IllegalArgumentException("\nk is greater than n");
1331 return Math.floor(0.5D + Math.exp(Stat.logFactorial(n) - Stat.logFactorial(k) - Stat.logFactorial(n-k)));
1332 }
1333
1334
1335
1336
1337
1338 public double[] binomialRand(double prob, int nTrials, int n){
1339
1340 if(nTrials<n)throw new IllegalArgumentException("Number of deviates requested, " + n + ", must be less than the number of trials, " + nTrials);
1341 if(prob<0.0D || prob>1.0D)throw new IllegalArgumentException("The probablity provided, " + prob + ", must lie between 0 and 1)");
1342
1343 double[] ran = new double[n];
1344 Random rr = new Random();
1345
1346 double binomialDeviate = 0.0D;
1347 double deviateMean = 0.0D;
1348 double testDeviate = 0.0D;
1349 double workingProb = 0.0;
1350 double logProb = 0.0;
1351 double probOld = -1.0D;
1352 double probC = -1.0D;
1353 double logProbC = -1.0D;
1354 int nOld= -1;
1355 double enTrials = 0.0D;
1356 double oldGamma = 0.0D;
1357 double tanW = 0.0D;
1358 double hold0 = 0.0D;
1359 int jj;
1360
1361 double probOriginalValue = prob;
1362 for(int i=0; i<n; i++){
1363 prob = probOriginalValue;
1364 workingProb=(prob <= 0.5D ? prob : 1.0-prob);
1365 deviateMean = nTrials*workingProb;
1366
1367 if(nTrials < 25) {
1368
1369 binomialDeviate=0.0D;
1370 for(jj=1;jj<=nTrials;jj++)if (rr.nextDouble() < workingProb) ++binomialDeviate;
1371 }
1372 else if(deviateMean < 1.0D) {
1373
1374 double expOfMean=Math.exp(-deviateMean);
1375 testDeviate=1.0D;
1376 for (jj=0;jj<=nTrials;jj++) {
1377 testDeviate *= rr.nextDouble();
1378 if (testDeviate < expOfMean) break;
1379 }
1380 binomialDeviate=(jj <= nTrials ? jj : nTrials);
1381
1382 }
1383 else{
1384
1385 if(nTrials != nOld) {
1386
1387 enTrials = (double)nTrials;
1388 oldGamma = Stat.logGamma(enTrials + 1.0D);
1389 nOld = nTrials;
1390 }
1391 if(workingProb != probOld) {
1392
1393 probC = 1.0 - workingProb;
1394 logProb = Math.log(workingProb);
1395 logProbC = Math.log(probC);
1396 probOld = workingProb;
1397 }
1398
1399 double sq = Math.sqrt(2.0*deviateMean*probC);
1400 do{
1401 do{
1402 double angle = Math.PI*rr.nextDouble();
1403 tanW = Math.tan(angle);
1404 hold0 = sq*tanW + deviateMean;
1405 }while(hold0 < 0.0D || hold0 >= (enTrials + 1.0D));
1406 hold0 = Math.floor(hold0);
1407 testDeviate = 1.2D*sq*(1.0D + tanW*tanW)*Math.exp(oldGamma - Stat.logGamma(hold0 + 1.0D) - Stat.logGamma(enTrials - hold0 + 1.0D) + hold0*logProb + (enTrials - hold0)*logProbC);
1408 }while(rr.nextDouble() > testDeviate);
1409 binomialDeviate=hold0;
1410 }
1411
1412 if(workingProb != prob) binomialDeviate = nTrials - binomialDeviate;
1413
1414 ran[i] = binomialDeviate;
1415 }
1416
1417 return ran;
1418 }
1419
1420
1421
1422 public static double fTestProb(double fValue, int df1, int df2){
1423 double ddf1 = (double)df1;
1424 double ddf2 = (double)df2;
1425 double x = ddf2/(ddf2+ddf1*fValue);
1426 return Stat.incompleteBeta(df2/2.0D, df1/2.0D, x);
1427 }
1428
1429
1430
1431 public static double fTestProb(double var1, int df1, double var2, int df2){
1432 double fValue = var1/var2;
1433 double ddf1 = (double)df1;
1434 double ddf2 = (double)df2;
1435 double x = ddf2/(ddf2+ddf1*fValue);
1436 return Stat.incompleteBeta(df2/2.0D, df1/2.0D, x);
1437 }
1438
1439
1440
1441 public static double fTestValueGivenFprob(double fProb, int df1, int df2){
1442
1443
1444 int fTestsNum = 100;
1445 double[] fTestValues = new double[fTestsNum];
1446 fTestValues[0]=0.0001D;
1447 fTestValues[fTestsNum-1]=10000.0D;
1448
1449 double diff = (Fmath.log10(fTestValues[fTestsNum-1])-Fmath.log10(fTestValues[0]))/(fTestsNum-1);
1450
1451 for(int i=1; i<fTestsNum-1; i++){
1452 fTestValues[i] = Math.pow(10.0D,(Fmath.log10(fTestValues[i-1])+diff));
1453 }
1454
1455
1456 double[] fTestProb = new double[fTestsNum];
1457 for(int i=0; i<fTestsNum; i++){
1458 fTestProb[i] = Stat.fTestProb(fTestValues[i], df1, df2);
1459 }
1460
1461
1462
1463 double fTest0 = 0.0D;
1464 double fTest1 = 0.0D;
1465 double fTest2 = 0.0D;
1466
1467
1468 boolean test0 = true;
1469 boolean test1 = true;
1470 int i=0;
1471 int endTest=0;
1472 while(test0){
1473 if(fProb==fTestProb[i]){
1474 fTest0=fTestValues[i];
1475 test0=false;
1476 test1=false;
1477 }
1478 else{
1479 if(fProb>fTestProb[i]){
1480 test0=false;
1481 if(i>0){
1482 fTest1=fTestValues[i-1];
1483 fTest2=fTestValues[i];
1484 endTest=-1;
1485 }
1486 else{
1487 fTest1=fTestValues[i]/10.0D;
1488 fTest2=fTestValues[i];
1489 }
1490 }
1491 else{
1492 i++;
1493 if(i>fTestsNum-1){
1494 test0=false;
1495 fTest1=fTestValues[i-1];
1496 fTest2=10.0D*fTestValues[i-1];
1497 endTest=1;
1498 }
1499 }
1500 }
1501 }
1502
1503
1504 if(test1)fTest0=fTestBisect(fProb, fTest1, fTest2, df1, df2, endTest);
1505
1506 return fTest0;
1507 }
1508
1509
1510
1511 private static double fTestBisect(double fProb, double fTestLow, double fTestHigh, int df1, int df2, int endTest){
1512
1513 double funcLow = fProb - Stat.fTestProb(fTestLow, df1, df2);
1514 double funcHigh = fProb - Stat.fTestProb(fTestHigh, df1, df2);
1515 double fTestMid = 0.0D;
1516 double funcMid = 0.0;
1517 int nExtensions = 0;
1518 int nIter = 1000;
1519 double check = fProb*1e-6;
1520 boolean test0 = true;
1521 boolean test1 = true;
1522 while(test0){
1523 if(funcLow*funcHigh>0.0D){
1524 if(endTest<0){
1525 nExtensions++;
1526 if(nExtensions>100){
1527 System.out.println("Class: Stats\nMethod: fTestBisect\nProbability higher than range covered\nF-test value is less than "+fTestLow);
1528 System.out.println("This value was returned");
1529 fTestMid=fTestLow;
1530 test0=false;
1531 test1=false;
1532 }
1533 fTestLow /= 10.0D;
1534 funcLow = fProb - Stat.fTestProb(fTestLow, df1, df2);
1535 }
1536 else{
1537 nExtensions++;
1538 if(nExtensions>100){
1539 System.out.println("Class: Stats\nMethod: fTestBisect\nProbability lower than range covered\nF-test value is greater than "+fTestHigh);
1540 System.out.println("This value was returned");
1541 fTestMid=fTestHigh;
1542 test0=false;
1543 test1=false;
1544 }
1545 fTestHigh *= 10.0D;
1546 funcHigh = fProb - Stat.fTestProb(fTestHigh, df1, df2);
1547 }
1548 }
1549 else{
1550 test0=false;
1551 }
1552
1553 int i=0;
1554 while(test1){
1555 fTestMid = (fTestLow+fTestHigh)/2.0D;
1556 funcMid = fProb - Stat.fTestProb(fTestMid, df1, df2);
1557 if(Math.abs(funcMid)<check){
1558 test1=false;
1559 }
1560 else{
1561 i++;
1562 if(i>nIter){
1563 System.out.println("Class: Stats\nMethod: fTestBisect\nmaximum number of iterations exceeded\ncurrent value of F-test value returned");
1564 test1=false;
1565 }
1566 if(funcMid*funcHigh>0){
1567 funcHigh=funcMid;
1568 fTestHigh=fTestMid;
1569 }
1570 else{
1571 funcLow=funcMid;
1572 fTestLow=fTestMid;
1573 }
1574 }
1575 }
1576 }
1577 return fTestMid;
1578 }
1579
1580
1581 public static double studentT(double tValue, int df){
1582 double ddf = (double)df;
1583 double dfterm = (ddf + 1.0D)/2.0D;
1584 return ((Stat.gamma(dfterm)/Stat.gamma(ddf/2))/Math.sqrt(ddf*Math.PI))*Math.pow(1.0D + tValue*tValue/ddf, -dfterm);
1585 }
1586
1587
1588 public static double studentTProb(double tValue, int df){
1589 double ddf = (double)df;
1590 double x = ddf/(ddf+tValue*tValue);
1591 return 0.5D*(1.0D + (Stat.incompleteBeta(ddf/2.0D, 0.5D, 1) - Stat.incompleteBeta(ddf/2.0D, 0.5D, x))*Fmath.sign(tValue));
1592 }
1593
1594
1595 public static double probAtn(double tValue, int df){
1596 double ddf = (double)df;
1597 double x = ddf/(ddf+tValue*tValue);
1598 return 1.0D - Stat.incompleteBeta(ddf/2.0D, 0.5D, x);
1599 }
1600
1601
1602
1603 public static double[][] histogramBins(double[] data, double binWidth, double binZero, double binUpper){
1604 int n = 0;
1605 int m = data.length;
1606 for(int i=0; i<m; i++)if(data[i]<=binUpper)n++;
1607 if(n!=m){
1608 double[] newData = new double[n];
1609 int j = 0;
1610 for(int i=0; i<m; i++){
1611 if(data[i]<=binUpper){
1612 newData[j] = data[i];
1613 j++;
1614 }
1615 }
1616 System.out.println((m-n)+" data points, above histogram upper limit, excluded in Stat.histogramBins");
1617 return histogramBins(newData, binWidth, binZero);
1618 }
1619 else{
1620 return histogramBins(data, binWidth, binZero);
1621
1622 }
1623 }
1624
1625
1626
1627 public static double[][] histogramBins(double[] data, double binWidth, double binZero){
1628 double dmax = Fmath.maximum(data);
1629 int nBins = (int) Math.ceil((dmax - binZero)/binWidth);
1630 if(binZero+nBins*binWidth>dmax)nBins++;
1631 int nPoints = data.length;
1632 int[] dataCheck = new int[nPoints];
1633 for(int i=0; i<nPoints; i++)dataCheck[i]=0;
1634 double[]binWall = new double[nBins+1];
1635 binWall[0]=binZero;
1636 for(int i=1; i<=nBins; i++){
1637 binWall[i] = binWall[i-1] + binWidth;
1638 }
1639 double[][] binFreq = new double[2][nBins];
1640 for(int i=0; i<nBins; i++){
1641 binFreq[0][i]= (binWall[i]+binWall[i+1])/2.0D;
1642 binFreq[1][i]= 0.0D;
1643 }
1644 boolean test = true;
1645
1646 for(int i=0; i<nPoints; i++){
1647 test=true;
1648 int j=0;
1649 while(test){
1650 if(j==nBins-1){
1651 if(data[i]>=binWall[j] && data[i]<=binWall[j+1]*(1.0D + Stat.histTol)){
1652 binFreq[1][j]+= 1.0D;
1653 dataCheck[i]=1;
1654 test=false;
1655 }
1656 }
1657 else{
1658 if(data[i]>=binWall[j] && data[i]<binWall[j+1]){
1659 binFreq[1][j]+= 1.0D;
1660 dataCheck[i]=1;
1661 test=false;
1662 }
1663 }
1664 if(test){
1665 if(j==nBins-1){
1666 test=false;
1667 }
1668 else{
1669 j++;
1670 }
1671 }
1672 }
1673 }
1674 int nMissed=0;
1675 for(int i=0; i<nPoints; i++)if(dataCheck[i]==0){
1676 nMissed++;
1677 System.out.println("p " + i + " " + data[i] + " " + binWall[0] + " " + binWall[nBins]);
1678 }
1679 if(nMissed>0)System.out.println(nMissed+" data points, outside histogram limits, excluded in Stat.histogramBins");
1680 return binFreq;
1681 }
1682
1683
1684
1685 public static double[][] histogramBins(double[] data, double binWidth){
1686
1687 double dmin = Fmath.minimum(data);
1688 double dmax = Fmath.maximum(data);
1689 double span = dmax - dmin;
1690 double binZero = dmin;
1691 int nBins = (int) Math.ceil(span/binWidth);
1692 double histoSpan = ((double)nBins)*binWidth;
1693 double rem = histoSpan - span;
1694 if(rem>=0){
1695 binZero -= rem/2.0D;
1696 }
1697 else{
1698 if(Math.abs(rem)/span>histTol){
1699
1700 boolean testBw = true;
1701 double incr = histTol/nBins;
1702 int iTest = 0;
1703 while(testBw){
1704 binWidth += incr;
1705 histoSpan = ((double)nBins)*binWidth;
1706 rem = histoSpan - span;
1707 if(rem<0){
1708 iTest++;
1709 if(iTest>1000){
1710 testBw = false;
1711 System.out.println("histogram method could not encompass all data within histogram\nContact Michael thomas Flanagan");
1712 }
1713 }
1714 else{
1715 testBw = false;
1716 }
1717 }
1718 }
1719 }
1720
1721 return Stat.histogramBins(data, binWidth, binZero);
1722 }
1723
1724
1725
1726
1727 public static int factorial(int n){
1728 if(n<0)throw new IllegalArgumentException("n must be a positive integer");
1729 if(n>12)throw new IllegalArgumentException("n must less than 13 to avoid integer overflow\nTry long or double argument");
1730 int f = 1;
1731 for(int i=1; i<=n; i++)f*=i;
1732 return f;
1733 }
1734
1735
1736
1737
1738 public static long factorial(long n){
1739 if(n<0)throw new IllegalArgumentException("n must be a positive integer");
1740 if(n>20)throw new IllegalArgumentException("n must less than 21 to avoid long integer overflow\nTry double argument");
1741 long f = 1;
1742 for(int i=1; i<=n; i++)f*=i;
1743 return f;
1744 }
1745
1746
1747
1748
1749
1750 public static double factorial(double n){
1751 if(n<0 || (n-(int)n)!=0)throw new IllegalArgumentException("\nn must be a positive integer\nIs a Gamma funtion [Fmath.gamma(x)] more appropriate?");
1752 double f = 1.0D;
1753 int nn = (int)n;
1754 for(int i=1; i<=nn; i++)f*=i;
1755 return f;
1756 }
1757
1758
1759
1760
1761 public static double logFactorial(int n){
1762 if(n<0 || (n-(int)n)!=0)throw new IllegalArgumentException("\nn must be a positive integer\nIs a Gamma funtion [Fmath.gamma(x)] more appropriate?");
1763 double f = 0.0D;
1764 for(int i=2; i<=n; i++)f+=Math.log(i);
1765 return f;
1766 }
1767
1768
1769
1770
1771
1772 public static double logFactorial(double n){
1773 if(n<0 || (n-(int)n)!=0)throw new IllegalArgumentException("\nn must be a positive integer\nIs a Gamma funtion [Fmath.gamma(x)] more appropriate?");
1774 double f = 0.0D;
1775 int nn = (int)n;
1776 for(int i=2; i<=nn; i++)f+=Math.log(i);
1777 return f;
1778 }
1779
1780
1781
1782 public static double corrCoeff(double[] xx, double[]yy){
1783
1784 double temp0 = 0.0D, temp1 = 0.0D;
1785 int nData = xx.length;
1786 if(yy.length!=nData)throw new IllegalArgumentException("array lengths must be equal");
1787 int df = nData-1;
1788
1789 double mx = 0.0D;
1790 double my = 0.0D;
1791 for(int i=0; i<nData; i++){
1792 mx += xx[i];
1793 my += yy[i];
1794 }
1795 mx /= nData;
1796 my /= nData;
1797
1798
1799 double s2xx = 0.0D;
1800 double s2yy = 0.0D;
1801 double s2xy = 0.0D;
1802 for(int i=0; i<nData; i++){
1803 s2xx += Fmath.square(xx[i]-mx);
1804 s2yy += Fmath.square(yy[i]-my);
1805 s2xy += (xx[i]-mx)*(yy[i]-my);
1806 }
1807 s2xx /= df;
1808 s2yy /= df;
1809 s2xy /= df;
1810
1811
1812 double sampleR = s2xy/Math.sqrt(s2xx*s2yy);
1813
1814 return sampleR;
1815 }
1816
1817
1818
1819 public static float corrCoeff(float[] x, float[] y){
1820 int nData = x.length;
1821 if(y.length!=nData)throw new IllegalArgumentException("array lengths must be equal");
1822 int n = x.length;
1823 double[] xx = new double[n];
1824 double[] yy = new double[n];
1825 for(int i=0; i<n; i++){
1826 xx[i] = (double)x[i];
1827 yy[i] = (double)y[i];
1828 }
1829 return (float)Stat.corrCoeff(xx, yy);
1830 }
1831
1832
1833
1834 public static double corrCoeff(int[] x, int[]y){
1835 int n = x.length;
1836 if(y.length!=n)throw new IllegalArgumentException("array lengths must be equal");
1837
1838 double[] xx = new double[n];
1839 double[] yy = new double[n];
1840 for(int i=0; i<n; i++){
1841 xx[i] = (double)x[i];
1842 yy[i] = (double)y[i];
1843 }
1844 return Stat.corrCoeff(xx, yy);
1845 }
1846
1847
1848
1849 public static double corrCoeff(double[] x, double[]y, double[] w){
1850 int n = x.length;
1851 if(y.length!=n)throw new IllegalArgumentException("x and y array lengths must be equal");
1852 if(w.length!=n)throw new IllegalArgumentException("x and weight array lengths must be equal");
1853
1854 double sxy = Stat.covariance(x, y, w);
1855 double sx = Stat.variance(x, w);
1856 double sy = Stat.variance(y, w);
1857 return sxy/Math.sqrt(sx*sy);
1858 }
1859
1860
1861
1862
1863
1864
1865
1866
1867 public static double corrCoeff(int element00, int element01, int element10, int element11){
1868 return ((double)(element00*element11 - element01*element10))/Math.sqrt((double)((element00+element01)*(element10+element11)*(element00+element10)*(element01+element11)));
1869 }
1870
1871
1872
1873
1874
1875
1876
1877
1878 public static double corrCoeff(int[][] freqMatrix){
1879 double element00 = (double)freqMatrix[0][0];
1880 double element01 = (double)freqMatrix[0][1];
1881 double element10 = (double)freqMatrix[1][0];
1882 double element11 = (double)freqMatrix[1][1];
1883 return ((element00*element11 - element01*element10))/Math.sqrt(((element00+element01)*(element10+element11)*(element00+element10)*(element01+element11)));
1884 }
1885
1886
1887
1888 public static double linearCorrCoeff(double rCoeff, int nu){
1889 return Stat.corrCoeffPdf(rCoeff, nu);
1890 }
1891
1892
1893 public static double corrCoeffPdf(double rCoeff, int nu){
1894 if(Math.abs(rCoeff)>1.0D)throw new IllegalArgumentException("|Correlation coefficient| > 1 : " + rCoeff);
1895
1896 double a = ((double)nu - 2.0D)/2.0D;
1897 double y = Math.pow((1.0D - Fmath.square(rCoeff)),a);
1898
1899 double preterm = Math.exp(Stat.logGamma((nu+1.0D)/2.0)-Stat.logGamma(nu/2.0D))/Math.sqrt(Math.PI);
1900
1901 return preterm*y;
1902 }
1903
1904
1905
1906 public static double weibullProb(double mu, double sigma, double gamma, double upperlimit){
1907 double arg = (upperlimit - mu)/sigma;
1908 double y = 0.0D;
1909 if(arg>0.0D)y = 1.0D - Math.exp(-Math.pow(arg, gamma));
1910 return y;
1911 }
1912
1913
1914
1915 public static double weibullProb(double mu, double sigma, double gamma, double lowerlimit, double upperlimit){
1916 double arg1 = (lowerlimit - mu)/sigma;
1917 double arg2 = (upperlimit - mu)/sigma;
1918 double term1 = 0.0D, term2 = 0.0D;
1919 if(arg1>=0.0D)term1 = -Math.exp(-Math.pow(arg1, gamma));
1920 if(arg2>=0.0D)term2 = -Math.exp(-Math.pow(arg2, gamma));
1921 return term2-term1;
1922 }
1923
1924
1925 public static double weibull(double mu,double sigma, double gamma, double x){
1926 double arg =(x-mu)/sigma;
1927 double y = 0.0D;
1928 if(arg>=0.0D){
1929 y = (gamma/sigma)*Math.pow(arg, gamma-1.0D)*Math.exp(-Math.pow(arg, gamma));
1930 }
1931 return y;
1932 }
1933
1934
1935 public static double weibullMean(double mu,double sigma, double gamma){
1936 return mu + sigma*Stat.gamma(1.0D/gamma+1.0D);
1937 }
1938
1939
1940 public static double weibullStandDev(double sigma, double gamma){
1941 double y = Stat.gamma(2.0D/gamma+1.0D)-Fmath.square(Stat.gamma(1.0D/gamma+1.0D));
1942 return sigma*Math.sqrt(y);
1943 }
1944
1945
1946 public static double weibullMode(double mu,double sigma, double gamma){
1947 double y=mu;
1948 if(gamma>1.0D){
1949 y = mu + sigma*Math.pow((gamma-1.0D)/gamma, 1.0D/gamma);
1950 }
1951 return y;
1952 }
1953
1954
1955 public static double weibullMedian(double mu,double sigma, double gamma){
1956 return mu + sigma*Math.pow(Math.log(2.0D),1.0D/gamma);
1957 }
1958
1959
1960
1961 public static double[] weibullRand(double mu, double sigma, double gamma, int n){
1962 double[] ran = new double[n];
1963 Random rr = new Random();
1964 for(int i=0; i<n; i++){
1965 ran[i] = Math.pow(-Math.log(1.0D-rr.nextDouble()),1.0D/gamma)*sigma + mu;
1966 }
1967 return ran;
1968 }
1969
1970
1971
1972 public static double[] weibullRand(double mu, double sigma, double gamma, int n, long seed){
1973 double[] ran = new double[n];
1974 Random rr = new Random(seed);
1975 for(int i=0; i<n; i++){
1976 ran[i] = Math.pow(-Math.log(1.0D-rr.nextDouble()),1.0D/gamma)*sigma + mu;
1977 }
1978 return ran;
1979 }
1980
1981
1982
1983 public static double frechetProb(double mu, double sigma, double gamma, double upperlimit){
1984 double arg = (upperlimit - mu)/sigma;
1985 double y = 0.0D;
1986 if(arg>0.0D)y = Math.exp(-Math.pow(arg, -gamma));
1987 return y;
1988 }
1989
1990
1991
1992
1993 public static double frechetProb(double mu, double sigma, double gamma, double lowerlimit, double upperlimit){
1994 double arg1 = (lowerlimit - mu)/sigma;
1995 double arg2 = (upperlimit - mu)/sigma;
1996 double term1 = 0.0D, term2 = 0.0D;
1997 if(arg1>=0.0D)term1 = Math.exp(-Math.pow(arg1, -gamma));
1998 if(arg2>=0.0D)term2 = Math.exp(-Math.pow(arg2, -gamma));
1999 return term2-term1;
2000 }
2001
2002
2003
2004 public static double exponentialProb(double mu, double sigma, double upperlimit){
2005 double arg = (upperlimit - mu)/sigma;
2006 double y = 0.0D;
2007 if(arg>0.0D)y = 1.0D - Math.exp(-arg);
2008 return y;
2009 }
2010
2011
2012
2013 public static double exponentialProb(double mu, double sigma, double lowerlimit, double upperlimit){
2014 double arg1 = (lowerlimit - mu)/sigma;
2015 double arg2 = (upperlimit - mu)/sigma;
2016 double term1 = 0.0D, term2 = 0.0D;
2017 if(arg1>=0.0D)term1 = -Math.exp(-arg1);
2018 if(arg2>=0.0D)term2 = -Math.exp(-arg2);
2019 return term2-term1;
2020 }
2021
2022
2023 public static double exponential(double mu,double sigma, double x){
2024 double arg =(x-mu)/sigma;
2025 double y = 0.0D;
2026 if(arg>=0.0D){
2027 y = Math.exp(-arg)/sigma;
2028 }
2029 return y;
2030 }
2031
2032
2033 public static double exponentialMean(double mu, double sigma){
2034 return mu + sigma;
2035 }
2036
2037
2038 public static double exponentialStandDev(double sigma){
2039 return sigma;
2040 }
2041
2042
2043 public static double exponentialMode(double mu){
2044 return mu;
2045 }
2046
2047
2048 public static double exponentialMedian(double mu,double sigma){
2049 return mu + sigma*Math.log(2.0D);
2050 }
2051
2052
2053
2054 public static double[] exponentialRand(double mu, double sigma, int n){
2055 double[] ran = new double[n];
2056 Random rr = new Random();
2057 for(int i=0; i<n; i++){
2058 ran[i] = mu - Math.log(1.0D-rr.nextDouble())*sigma;
2059 }
2060 return ran;
2061 }
2062
2063
2064
2065 public static double[] exponentialRand(double mu, double sigma, int n, long seed){
2066 double[] ran = new double[n];
2067 Random rr = new Random(seed);
2068 for(int i=0; i<n; i++){
2069 ran[i] = mu - Math.log(1.0D-rr.nextDouble())*sigma;
2070 }
2071 return ran;
2072 }
2073 }