The R Project SVN R

Rev

Rev 59087 | Rev 65919 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 59087 Rev 60118
Line 41... Line 41...
41
 *
41
 *
42
 *  NOTES
42
 *  NOTES
43
 *
43
 *
44
 *	Complete redesign by Morten Welinder, originally for Gnumeric.
44
 *	Complete redesign by Morten Welinder, originally for Gnumeric.
45
 *	Improvements (e.g. "while NEEDED_SCALE") by Martin Maechler
45
 *	Improvements (e.g. "while NEEDED_SCALE") by Martin Maechler
46
 *	The old version can be activated by compiling with -DR_USE_OLD_PGAMMA
-
 
47
 *
46
 *
48
 *  REFERENCES
47
 *  REFERENCES
49
 *
48
 *
50
 */
49
 */
51
 
50
 
Line 242... Line 241...
242
{
241
{
243
    return logx + R_Log1_Exp(logy - logx);
242
    return logx + R_Log1_Exp(logy - logx);
244
}
243
}
245
 
244
 
246
 
245
 
247
#ifndef R_USE_OLD_PGAMMA
-
 
248
 
-
 
249
/* dpois_wrap (x_P_1,  lambda, g_log) ==
246
/* dpois_wrap (x_P_1,  lambda, g_log) ==
250
 *   dpois (x_P_1 - 1, lambda, g_log) :=  exp(-L)  L^k / gamma(k+1) ,  k := x_P_1 - 1
247
 *   dpois (x_P_1 - 1, lambda, g_log) :=  exp(-L)  L^k / gamma(k+1) ,  k := x_P_1 - 1
251
*/
248
*/
252
static double
249
static double
253
dpois_wrap (double x_plus_1, double lambda, int give_log)
250
dpois_wrap (double x_plus_1, double lambda, int give_log)
Line 720... Line 717...
720
 * available to other parts of R.
717
 * available to other parts of R.
721
 
718
 
722
 * MM: I've not (yet?) taken  logcf(), but the other four
719
 * MM: I've not (yet?) taken  logcf(), but the other four
723
 */
720
 */
724
 
721
 
725

-
 
726
#else
-
 
727
/* R_USE_OLD_PGAMMA */
-
 
728
/*
-
 
729
 *  Copyright (C) 1998		Ross Ihaka
-
 
730
 *  Copyright (C) 1999-2000	The R Core Team
-
 
731
 *  Copyright (C) 2003-2004	The R Foundation
-
 
732
 *  based on AS 239 (C) 1988 Royal Statistical Society
-
 
733
 *
-
 
734
 *  ................
-
 
735
 *
-
 
736
 *  NOTES
-
 
737
 *
-
 
738
 *	This function is an adaptation of Algorithm 239 from the
-
 
739
 *	Applied Statistics Series.  The algorithm is faster than
-
 
740
 *	those by W. Fullerton in the FNLIB library and also the
-
 
741
 *	TOMS 542 alorithm of W. Gautschi.  It provides comparable
-
 
742
 *	accuracy to those algorithms and is considerably simpler.
-
 
743
 *
-
 
744
 *  REFERENCES
-
 
745
 *
-
 
746
 *	Algorithm AS 239, Incomplete Gamma Function
-
 
747
 *	Applied Statistics 37, 1988.
-
 
748
 */
-
 
749
 
-
 
750
/* now would need this here: */
-
 
751
double attribute_hidden pgamma_raw(x, alph, lower_tail, log_p) {
-
 
752
    return pgamma(x, alph, 1, lower_tail, log_p);
-
 
753
}
-
 
754
 
-
 
755
double pgamma(double x, double alph, double scale, int lower_tail, int log_p)
-
 
756
{
-
 
757
    const static double
-
 
758
	xbig = 1.0e+8,
-
 
759
	xlarge = 1.0e+37,
-
 
760
 
-
 
761
	/* normal approx. for alph > alphlimit */
-
 
762
	alphlimit = 1e5;/* was 1000. till R.1.8.x */
-
 
763
 
-
 
764
    double pn1, pn2, pn3, pn4, pn5, pn6, arg, a, b, c, an, osum, sum;
-
 
765
    long n;
-
 
766
    int pearson;
-
 
767
 
-
 
768
    /* check that we have valid values for x and alph */
-
 
769
 
-
 
770
#ifdef IEEE_754
-
 
771
    if (ISNAN(x) || ISNAN(alph) || ISNAN(scale))
-
 
772
	return x + alph + scale;
-
 
773
#endif
-
 
774
#ifdef DEBUG_p
-
 
775
    REprintf("pgamma(x=%4g, alph=%4g, scale=%4g): ",x,alph,scale);
-
 
776
#endif
-
 
777
    if(alph <= 0. || scale <= 0.)
-
 
778
	ML_ERR_return_NAN;
-
 
779
 
-
 
780
    x /= scale;
-
 
781
#ifdef DEBUG_p
-
 
782
    REprintf("-> x=%4g; ",x);
-
 
783
#endif
-
 
784
#ifdef IEEE_754
-
 
785
    if (ISNAN(x)) /* eg. original x = scale = Inf */
-
 
786
	return x;
-
 
787
#endif
-
 
788
    if (x <= 0.)
-
 
789
	return R_DT_0;
-
 
790
 
-
 
791
#define USE_PNORM \
-
 
792
    pn1 = sqrt(alph) * 3. * (pow(x/alph, 1./3.) + 1. / (9. * alph) - 1.); \
-
 
793
    return pnorm(pn1, 0., 1., lower_tail, log_p);
-
 
794
 
-
 
795
    if (alph > alphlimit) { /* use a normal approximation */
-
 
796
	USE_PNORM;
-
 
797
    }
-
 
798
 
-
 
799
    if (x > xbig * alph) {
-
 
800
	if (x > DBL_MAX * alph)
-
 
801
	    /* if x is extremely large __compared to alph__ then return 1 */
-
 
802
	    return R_DT_1;
-
 
803
	else { /* this only "helps" when log_p = TRUE */
-
 
804
	    USE_PNORM;
-
 
805
	}
-
 
806
    }
-
 
807
 
-
 
808
    if (x <= 1. || x < alph) {
-
 
809
 
-
 
810
	pearson = 1;/* use pearson's series expansion. */
-
 
811
 
-
 
812
	arg = alph * log(x) - x - lgammafn(alph + 1.);
-
 
813
#ifdef DEBUG_p
-
 
814
	REprintf("Pearson  arg=%g ", arg);
-
 
815
#endif
-
 
816
	c = 1.;
-
 
817
	sum = 1.;
-
 
818
	a = alph;
-
 
819
	do {
-
 
820
	    a += 1.;
-
 
821
	    c *= x / a;
-
 
822
	    sum += c;
-
 
823
	} while (c > DBL_EPSILON * sum);
-
 
824
    }
-
 
825
    else { /* x >= max( 1, alph) */
-
 
826
 
-
 
827
	pearson = 0;/* use a continued fraction expansion */
-
 
828
 
-
 
829
	arg = alph * log(x) - x - lgammafn(alph);
-
 
830
#ifdef DEBUG_p
-
 
831
	REprintf("Cont.Fract. arg=%g ", arg);
-
 
832
#endif
-
 
833
	a = 1. - alph;
-
 
834
	b = a + x + 1.;
-
 
835
	pn1 = 1.;
-
 
836
	pn2 = x;
-
 
837
	pn3 = x + 1.;
-
 
838
	pn4 = x * b;
-
 
839
	sum = pn3 / pn4;
-
 
840
	for (n = 1; ; n++) {
-
 
841
	    a += 1.;/* =   n+1 -alph */
-
 
842
	    b += 2.;/* = 2(n+1)-alph+x */
-
 
843
	    an = a * n;
-
 
844
	    pn5 = b * pn3 - an * pn1;
-
 
845
	    pn6 = b * pn4 - an * pn2;
-
 
846
	    if (fabs(pn6) > 0.) {
-
 
847
		osum = sum;
-
 
848
		sum = pn5 / pn6;
-
 
849
		if (fabs(osum - sum) <= DBL_EPSILON * fmin2(1., sum))
-
 
850
		    break;
-
 
851
	    }
-
 
852
	    pn1 = pn3;
-
 
853
	    pn2 = pn4;
-
 
854
	    pn3 = pn5;
-
 
855
	    pn4 = pn6;
-
 
856
	    if (fabs(pn5) >= xlarge) {
-
 
857
		/* re-scale the terms in continued fraction if they are large */
-
 
858
#ifdef DEBUG_p
-
 
859
		REprintf(" [r] ");
-
 
860
#endif
-
 
861
		pn1 /= xlarge;
-
 
862
		pn2 /= xlarge;
-
 
863
		pn3 /= xlarge;
-
 
864
		pn4 /= xlarge;
-
 
865
	    }
-
 
866
	}
-
 
867
    }
-
 
868
 
-
 
869
    arg += log(sum);
-
 
870
 
-
 
871
    lower_tail = (lower_tail == pearson);
-
 
872
 
-
 
873
    if (log_p && lower_tail)
-
 
874
	return(arg);
-
 
875
    /* else */
-
 
876
    /* sum = exp(arg); and return   if(lower_tail) sum	else 1-sum : */
-
 
877
    return (lower_tail) ? exp(arg) : (log_p ? R_Log1_Exp(arg) : -expm1(arg));
-
 
878
}
-
 
879
 
-
 
880
#endif
-
 
881
/* R_USE_OLD_PGAMMA */
-