#include <assert.h>
#include <math.h>

#include "betaDF.h"

double negBinomialDF(long k, long n, double p)
/*
 * Для последовательности испытаний Бернулли вычисляется вероятность того,
 * что n-му успеху предшествуют k или меньше неудач, т.е. сумму
 * членов отрицательного биномиального распределения от 0 до k:
 *
 *   k
 *   --  ( n+j-1 )   n      j
 *   >   (       )  p  (1-p)
 *   --  (   j   )
 *  j=0
 *
 * При вычислении функции распределения ряд не суммируется.
 * Используется ее связь с бета-распределением:
 *
 * y = negBinomialDF(k, n, p) = betaDF(n, k+1, p).
 *
 * Все аргументы должны быть положительными, причем 0 < p < 1.
 */
{
   assert( (n > 0) && ( k >= 0 ) && (p >= 0.0) && (p <= 1.0) );
   return BetaDF(n, k+1).value(p);
}/*negBinomialDF*/ 

double rev_negBinomialDF(long k, long n, double y)
/*
 *
 * Ищется значение p, для которого negBinomialDF(k,n,p) = y.
 *
 */
{
   assert( (n > 0) && ( k >= 0 ) && (y >= 0.0) && (y <= 1.0) );
   return BetaDF(n, k+1).inv(y);
}/*rev_negBinomialDF*/

#ifdef TEST
#include <iostream.h>

LOCAL void
tryNeg(void)
{
   long m, n, x;
   double p;
   double alpha=0.95;

   while (1) {
      cout << "\n\n\rEnter integer n1: ";
      cin >> n;
      if (n <= 0)
     break;
      cout << "\rEnter integer n2: ";
      cin >> m;
      cout << "\rEnter p: ";
      cin >> p;
      x = negBinomialDF(n, m, p);
      cout << "\nF(" << n << m << p << ") = " << x;
   }

}/*tryNeg*/

LOCAL void
try_invNeg(void)
{
   long n1, n2;
   double bound, alpha=0.95;

   while (1) {
      cout << "\n\n\rEnter integer n1: ";
      cin >> n1;
      if (n1 <= 0)
     break;
      cout << "\rEnter integer n2: ";
      cin >> n2;
      bound = rev_negBinomialDF(n1,n2,alpha);
      cout << alpha << " bound = " << bound;
   }

}/*try_invNeg*/

void main(void)
{
   tryNeg();
   try_invNeg();
}

#endif

