Changed all the licence notices in all the files.
[pspp-builds.git] / lib / gsl-extras / betadistinv.c
index a0838d27eb744b5ce54bddc051c294b264e55741..2c7c72badeea1776258c54f9177d92454079a71f 100644 (file)
@@ -1,6 +1,7 @@
 /* cdf/betadistinv.c
  *
- * Copyright (C) 2004 Jason H. Stover.
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ * Written by Jason H. Stover.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 /*
@@ -31,6 +32,7 @@
  * Cornish-Fisher type," Annals of Mathematical Statistics, volume 39, number 8,
  * August 1968, pages 1264-1273.
  */
+
 #include <config.h>
 #include <math.h>
 #include <gsl/gsl_math.h>
@@ -40,7 +42,7 @@
 #include <gsl/gsl_randist.h>
 #include "gsl-extras.h"
 
-#define BETAINV_INIT_ERR .01
+#define BETAINV_INIT_ERR .001
 #define BETADISTINV_N_TERMS 3
 #define BETADISTINV_MAXITER 20
 
@@ -389,7 +391,7 @@ gslextras_cdf_beta_Pinv ( const double p, const double a, const double b)
   err = beta_result - p;
   abserr = fabs(err);
   relerr = abserr / p;
-  while ( relerr > BETAINV_INIT_ERR && n_iter < 100)
+  while ( relerr > BETAINV_INIT_ERR)
     {
       tmp = new_guess_P ( state, lower, upper, 
                          p, a, b);
@@ -430,6 +432,19 @@ gslextras_cdf_beta_Pinv ( const double p, const double a, const double b)
          result = state;
          min_err = relerr;
        }
+      else
+       {
+         /*
+          * Lagrange polynomial failed to reduce the error.
+          * This will happen with a very skewed beta density. 
+          * Undo previous steps.
+          */
+         state = result;
+         beta_result = gsl_cdf_beta_P(state,a,b);
+         err = p - beta_result;
+         abserr = fabs(err);
+         relerr = abserr / p;
+       }
     }
 
   n_iter = 0;
@@ -580,7 +595,7 @@ gslextras_cdf_beta_Qinv (double q, double a, double b)
   err = beta_result - q;
   abserr = fabs(err);
   relerr = abserr / q;
-  while ( relerr > BETAINV_INIT_ERR && n_iter < 100)
+  while ( relerr > BETAINV_INIT_ERR)
     {
       n_iter++;
       tmp = new_guess_Q ( state, lower, upper, 
@@ -621,6 +636,19 @@ gslextras_cdf_beta_Qinv (double q, double a, double b)
          result = state;
          min_err = relerr;
        }
+      else
+       {
+         /*
+          * Lagrange polynomial failed to reduce the error.
+          * This will happen with a very skewed beta density. 
+          * Undo previous steps.
+          */
+         state = result;
+         beta_result = gsl_cdf_beta_P(state,a,b);
+         err = q - beta_result;
+         abserr = fabs(err);
+         relerr = abserr / q;
+       }
     }
 
   /*