jkunlin 8 年 前
コミット
abd8ccee91
4 ファイル変更6934 行追加0 行削除
  1. 34 0
      main.cpp
  2. 3985 0
      truncated_normal.cpp
  3. 91 0
      truncated_normal.hpp
  4. 2824 0
      truncated_normal_prb.cpp

+ 34 - 0
main.cpp

@@ -0,0 +1,34 @@
+// =====================================================================================
+//
+//       Filename:  main.cpp
+//
+//    Description:
+//
+//        Version:  1.0
+//        Created:  2018年 06月 25日 星期一 16:48:05 CST
+//       Revision:  none
+//       Compiler:  g++
+//
+//         Author:  Jinkun Lin, jkunlin@gmail.com
+//   Organization:  School of EECS, Peking University
+//
+// =====================================================================================
+#include "truncated_normal.hpp"
+#include <iostream>
+
+int main() {
+  double a;
+  double mu, sigma;
+  int seed;
+
+  a = 1;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  for (int i = 0; i < 10000000; ++i) {
+    cout << int(truncated_normal_a_sample(mu, sigma, a, seed)) << endl;
+  }
+
+  return 0;
+}

+ 3985 - 0
truncated_normal.cpp

@@ -0,0 +1,3985 @@
+#include <cmath>
+#include <cstdlib>
+#include <ctime>
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+using namespace std;
+
+#include "truncated_normal.hpp"
+
+//****************************************************************************80
+
+int i4_uniform_ab(int a, int b, int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    I4_UNIFORM_AB returns a scaled pseudorandom I4 between A and B.
+//
+//  Discussion:
+//
+//    The pseudorandom number should be uniformly distributed
+//    between A and B.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    02 October 2012
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Paul Bratley, Bennett Fox, Linus Schrage,
+//    A Guide to Simulation,
+//    Second Edition,
+//    Springer, 1987,
+//    ISBN: 0387964673,
+//    LC: QA76.9.C65.B73.
+//
+//    Bennett Fox,
+//    Algorithm 647:
+//    Implementation and Relative Efficiency of Quasirandom
+//    Sequence Generators,
+//    ACM Transactions on Mathematical Software,
+//    Volume 12, Number 4, December 1986, pages 362-376.
+//
+//    Pierre L'Ecuyer,
+//    Random Number Generation,
+//    in Handbook of Simulation,
+//    edited by Jerry Banks,
+//    Wiley, 1998,
+//    ISBN: 0471134031,
+//    LC: T57.62.H37.
+//
+//    Peter Lewis, Allen Goodman, James Miller,
+//    A Pseudo-Random Number Generator for the System/360,
+//    IBM Systems Journal,
+//    Volume 8, Number 2, 1969, pages 136-143.
+//
+//  Parameters:
+//
+//    Input, int A, B, the limits of the interval.
+//
+//    Input/output, int &SEED, the "seed" value, which should NOT be 0.
+//    On output, SEED has been updated.
+//
+//    Output, int I4_UNIFORM_AB, a number between A and B.
+//
+{
+  int c;
+  const int i4_huge = 2147483647;
+  int k;
+  float r;
+  int value;
+
+  if (seed == 0) {
+    cerr << "\n";
+    cerr << "I4_UNIFORM_AB - Fatal error!\n";
+    cerr << "  Input value of SEED = 0.\n";
+    exit(1);
+  }
+  //
+  //  Guarantee A <= B.
+  //
+  if (b < a) {
+    c = a;
+    a = b;
+    b = c;
+  }
+
+  k = seed / 127773;
+
+  seed = 16807 * (seed - k * 127773) - k * 2836;
+
+  if (seed < 0) {
+    seed = seed + i4_huge;
+  }
+
+  r = (float)(seed)*4.656612875E-10;
+  //
+  //  Scale R to lie between A-0.5 and B+0.5.
+  //
+  r = (1.0 - r) * ((float)a - 0.5) + r * ((float)b + 0.5);
+  //
+  //  Use rounding to convert R to an integer between A and B.
+  //
+  value = round(r);
+  //
+  //  Guarantee A <= VALUE <= B.
+  //
+  if (value < a) {
+    value = a;
+  }
+  if (b < value) {
+    value = b;
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_01_cdf(double x)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_CDF evaluates the Normal 01 CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    10 February 1999
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    A G Adams,
+//    Areas Under the Normal Curve,
+//    Algorithm 39,
+//    Computer j.,
+//    Volume 12, pages 197-198, 1969.
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the CDF.
+//
+//    Output, double CDF, the value of the CDF.
+//
+{
+  double a1 = 0.398942280444;
+  double a2 = 0.399903438504;
+  double a3 = 5.75885480458;
+  double a4 = 29.8213557808;
+  double a5 = 2.62433121679;
+  double a6 = 48.6959930692;
+  double a7 = 5.92885724438;
+  double b0 = 0.398942280385;
+  double b1 = 3.8052E-08;
+  double b2 = 1.00000615302;
+  double b3 = 3.98064794E-04;
+  double b4 = 1.98615381364;
+  double b5 = 0.151679116635;
+  double b6 = 5.29330324926;
+  double b7 = 4.8385912808;
+  double b8 = 15.1508972451;
+  double b9 = 0.742380924027;
+  double b10 = 30.789933034;
+  double b11 = 3.99019417011;
+  double cdf;
+  double q;
+  double y;
+  //
+  //  |X| <= 1.28.
+  //
+  if (fabs(x) <= 1.28) {
+    y = 0.5 * x * x;
+
+    q = 0.5 -
+        fabs(x) * (a1 - a2 * y / (y + a3 - a4 / (y + a5 + a6 / (y + a7))));
+    //
+    //  1.28 < |X| <= 12.7
+    //
+  } else if (fabs(x) <= 12.7) {
+    y = 0.5 * x * x;
+
+    q = exp(-y) * b0 /
+        (fabs(x) - b1 +
+         b2 / (fabs(x) + b3 +
+               b4 / (fabs(x) - b5 +
+                     b6 / (fabs(x) + b7 -
+                           b8 / (fabs(x) + b9 + b10 / (fabs(x) + b11))))));
+    //
+    //  12.7 < |X|
+    //
+  } else {
+    q = 0.0;
+  }
+  //
+  //  Take account of negative X.
+  //
+  if (x < 0.0) {
+    cdf = q;
+  } else {
+    cdf = 1.0 - q;
+  }
+
+  return cdf;
+}
+//****************************************************************************80
+
+double normal_01_cdf_inv(double p)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_CDF_INV inverts the standard normal CDF.
+//
+//  Discussion:
+//
+//    The result is accurate to about 1 part in 10**16.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    27 December 2004
+//
+//  Author:
+//
+//    Original FORTRAN77 version by Michael Wichura.
+//    C++ version by John Burkardt.
+//
+//  Reference:
+//
+//    Michael Wichura,
+//    The Percentage Points of the Normal Distribution,
+//    Algorithm AS 241,
+//    Applied Statistics,
+//    Volume 37, Number 3, pages 477-484, 1988.
+//
+//  Parameters:
+//
+//    Input, double P, the value of the cumulative probability
+//    densitity function.  0 < P < 1.  If P is outside this range, an
+//    "infinite" value is returned.
+//
+//    Output, double NORMAL_01_CDF_INV, the normal deviate value
+//    with the property that the probability of a standard normal deviate being
+//    less than or equal to this value is P.
+//
+{
+  double a[8] = {3.3871328727963666080,    1.3314166789178437745E+2,
+                 1.9715909503065514427E+3, 1.3731693765509461125E+4,
+                 4.5921953931549871457E+4, 6.7265770927008700853E+4,
+                 3.3430575583588128105E+4, 2.5090809287301226727E+3};
+  double b[8] = {1.0,
+                 4.2313330701600911252E+1,
+                 6.8718700749205790830E+2,
+                 5.3941960214247511077E+3,
+                 2.1213794301586595867E+4,
+                 3.9307895800092710610E+4,
+                 2.8729085735721942674E+4,
+                 5.2264952788528545610E+3};
+  double c[8] = {1.42343711074968357734,    4.63033784615654529590,
+                 5.76949722146069140550,    3.64784832476320460504,
+                 1.27045825245236838258,    2.41780725177450611770E-1,
+                 2.27238449892691845833E-2, 7.74545014278341407640E-4};
+  double const1 = 0.180625;
+  double const2 = 1.6;
+  double d[8] = {1.0,
+                 2.05319162663775882187,
+                 1.67638483018380384940,
+                 6.89767334985100004550E-1,
+                 1.48103976427480074590E-1,
+                 1.51986665636164571966E-2,
+                 5.47593808499534494600E-4,
+                 1.05075007164441684324E-9};
+  double e[8] = {6.65790464350110377720,    5.46378491116411436990,
+                 1.78482653991729133580,    2.96560571828504891230E-1,
+                 2.65321895265761230930E-2, 1.24266094738807843860E-3,
+                 2.71155556874348757815E-5, 2.01033439929228813265E-7};
+  double f[8] = {1.0,
+                 5.99832206555887937690E-1,
+                 1.36929880922735805310E-1,
+                 1.48753612908506148525E-2,
+                 7.86869131145613259100E-4,
+                 1.84631831751005468180E-5,
+                 1.42151175831644588870E-7,
+                 2.04426310338993978564E-15};
+  double q;
+  double r;
+  double split1 = 0.425;
+  double split2 = 5.0;
+  double value;
+
+  if (p <= 0.0) {
+    value = -r8_huge();
+    return value;
+  }
+
+  if (1.0 <= p) {
+    value = r8_huge();
+    return value;
+  }
+
+  q = p - 0.5;
+
+  if (fabs(q) <= split1) {
+    r = const1 - q * q;
+    value = q * r8poly_value_horner(7, a, r) / r8poly_value_horner(7, b, r);
+  } else {
+    if (q < 0.0) {
+      r = p;
+    } else {
+      r = 1.0 - p;
+    }
+
+    if (r <= 0.0) {
+      value = r8_huge();
+    } else {
+      r = sqrt(-log(r));
+
+      if (r <= split2) {
+        r = r - const2;
+        value = r8poly_value_horner(7, c, r) / r8poly_value_horner(7, d, r);
+      } else {
+        r = r - split2;
+        value = r8poly_value_horner(7, e, r) / r8poly_value_horner(7, f, r);
+      }
+    }
+
+    if (q < 0.0) {
+      value = -value;
+    }
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+void normal_01_cdf_values(int &n_data, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_CDF_VALUES returns some values of the Normal 01 CDF.
+//
+//  Discussion:
+//
+//    In Mathematica, the function can be evaluated by:
+//
+//      Needs["Statistics`ContinuousDistributions`"]
+//      dist = NormalDistribution [ 0, 1 ]
+//      CDF [ dist, x ]
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    28 August 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Milton Abramowitz, Irene Stegun,
+//    Handbook of Mathematical Functions,
+//    National Bureau of Standards, 1964,
+//    ISBN: 0-486-61272-4,
+//    LC: QA47.A34.
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 17
+
+  static double fx_vec[N_MAX] = {
+      0.5000000000000000E+00, 0.5398278372770290E+00, 0.5792597094391030E+00,
+      0.6179114221889526E+00, 0.6554217416103242E+00, 0.6914624612740131E+00,
+      0.7257468822499270E+00, 0.7580363477769270E+00, 0.7881446014166033E+00,
+      0.8159398746532405E+00, 0.8413447460685429E+00, 0.9331927987311419E+00,
+      0.9772498680518208E+00, 0.9937903346742239E+00, 0.9986501019683699E+00,
+      0.9997673709209645E+00, 0.9999683287581669E+00};
+
+  static double x_vec[N_MAX] = {
+      0.0000000000000000E+00, 0.1000000000000000E+00, 0.2000000000000000E+00,
+      0.3000000000000000E+00, 0.4000000000000000E+00, 0.5000000000000000E+00,
+      0.6000000000000000E+00, 0.7000000000000000E+00, 0.8000000000000000E+00,
+      0.9000000000000000E+00, 0.1000000000000000E+01, 0.1500000000000000E+01,
+      0.2000000000000000E+01, 0.2500000000000000E+01, 0.3000000000000000E+01,
+      0.3500000000000000E+01, 0.4000000000000000E+01};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double normal_01_mean()
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_MEAN returns the mean of the Normal 01 PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    18 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Output, double MEAN, the mean of the PDF.
+//
+{
+  double mean;
+
+  mean = 0.0;
+
+  return mean;
+}
+//****************************************************************************80
+
+double normal_01_moment(int order)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_MOMENT evaluates moments of the Normal 01 PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Output, double NORMAL_01_MOMENT, the value of the moment.
+//
+{
+  double value;
+
+  if ((order % 2) == 0) {
+    value = r8_factorial2(order - 1);
+  } else {
+    value = 0.0;
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_01_pdf(double x)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_PDF evaluates the Normal 01 PDF.
+//
+//  Discussion:
+//
+//    The Normal 01 PDF is also called the "Standard Normal" PDF, or
+//    the Normal PDF with 0 mean and standard deviation 1.
+//
+//    PDF(X) = exp ( - 0.5 * X^2 ) / sqrt ( 2 * PI )
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    18 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the PDF.
+//
+//    Output, double PDF, the value of the PDF.
+//
+{
+  double pdf;
+  const double r8_pi = 3.14159265358979323;
+
+  pdf = exp(-0.5 * x * x) / sqrt(2.0 * r8_pi);
+
+  return pdf;
+}
+//****************************************************************************80
+
+double normal_01_sample(int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_SAMPLE samples the standard normal probability distribution.
+//
+//  Discussion:
+//
+//    The standard normal probability distribution function (PDF) has
+//    mean 0 and standard deviation 1.
+//
+//    The Box-Muller method is used, which is efficient, but
+//    generates two values at a time.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    26 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input/output, int &SEED, a seed for the random number generator.
+//
+//    Output, double NORMAL_01_SAMPLE, a normally distributed random value.
+//
+{
+  double r1;
+  double r2;
+  const double r8_pi = 3.14159265358979323;
+  double x;
+
+  r1 = r8_uniform_01(seed);
+  r2 = r8_uniform_01(seed);
+  x = sqrt(-2.0 * log(r1)) * cos(2.0 * r8_pi * r2);
+
+  return x;
+}
+//****************************************************************************80
+
+double normal_01_variance()
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_VARIANCE returns the variance of the Normal 01 PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    18 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Output, double VARIANCE, the variance of the PDF.
+//
+{
+  double variance;
+
+  variance = 1.0;
+
+  return variance;
+}
+//****************************************************************************80
+
+double normal_ms_cdf(double x, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_CDF evaluates the Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the CDF.
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Output, double NORMAL_MS_CDF, the value of the CDF.
+//
+{
+  double cdf;
+  double y;
+
+  y = (x - mu) / sigma;
+
+  cdf = normal_01_cdf(y);
+
+  return cdf;
+}
+//****************************************************************************80
+
+double normal_ms_cdf_inv(double cdf, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_CDF_INV inverts the Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Algorithm AS 111,
+//    Applied Statistics,
+//    Volume 26, pages 118-121, 1977.
+//
+//  Parameters:
+//
+//    Input, double CDF, the value of the CDF.
+//    0.0 <= CDF <= 1.0.
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Output, double NORMAL_MS_CDF_INV, the corresponding argument.
+//
+{
+  double x;
+  double x2;
+
+  if (cdf < 0.0 || 1.0 < cdf) {
+    cout << "\n";
+    cout << "NORMAL_MS_CDF_INV - Fatal error!\n";
+    cout << "  CDF < 0 or 1 < CDF.\n";
+    exit(1);
+  }
+
+  x2 = normal_01_cdf_inv(cdf);
+
+  x = mu + sigma * x2;
+
+  return x;
+}
+//****************************************************************************80
+
+double normal_ms_mean(double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MEAN returns the mean of the Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Output, double NORMAL_MS_MEAN, the mean of the PDF.
+//
+{
+  double mean;
+
+  mean = mu;
+
+  return mean;
+}
+//****************************************************************************80
+
+double normal_ms_moment(int order, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MOMENT evaluates moments of the Normal PDF.
+//
+//  Discussion:
+//
+//    The formula was posted by John D Cook.
+//
+//    Order  Moment
+//    -----  ------
+//      0    1
+//      1    mu
+//      2    mu^2 +         sigma^2
+//      3    mu^3 +  3 mu   sigma^2
+//      4    mu^4 +  6 mu^2 sigma^2 +   3      sigma^4
+//      5    mu^5 + 10 mu^3 sigma^2 +  15 mu   sigma^4
+//      6    mu^6 + 15 mu^4 sigma^2 +  45 mu^2 sigma^4 +  15      sigma^6
+//      7    mu^7 + 21 mu^5 sigma^2 + 105 mu^3 sigma^4 + 105 mu   sigma^6
+//      8    mu^8 + 28 mu^6 sigma^2 + 210 mu^4 sigma^4 + 420 mu^2 sigma^6
+//           + 105 sigma^8
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Input, double MU, the mean of the distribution.
+//
+//    Input, double SIGMA, the standard deviation of the distribution.
+//
+//    Output, double NORMAL_MS_MOMENT, the value of the central moment.
+//
+{
+  int j;
+  int j_hi;
+  double value;
+
+  j_hi = (order / 2);
+
+  value = 0.0;
+  for (j = 0; j <= j_hi; j++) {
+    value = value +
+            r8_choose(order, 2 * j) * r8_factorial2(2 * j - 1) *
+                pow(mu, order - 2 * j) * pow(sigma, 2 * j);
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_ms_moment_central(int order, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MOMENT_CENTRAL evaluates central moments of the Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Input, double MU, the mean of the distribution.
+//
+//    Input, double SIGMA, the standard deviation of the distribution.
+//
+//    Output, double NORMAL_MS_MOMENT_CENTRAL, the value of the central moment.
+//
+{
+  double value;
+
+  if ((order % 2) == 0) {
+    value = r8_factorial2(order - 1) * pow(sigma, order);
+  } else {
+    value = 0.0;
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_ms_moment_central_values(int order, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MOMENT_CENTRAL_VALUES: moments 0 through 10 of the Normal PDF.
+//
+//  Discussion:
+//
+//    The formula was posted by John D Cook.
+//
+//    Order  Moment
+//    -----  ------
+//      0    1
+//      1    0
+//      2    sigma^2
+//      3    0
+//      4    3 sigma^4
+//      5    0
+//      6    15 sigma^6
+//      7    0
+//      8    105 sigma^8
+//      9    0
+//     10    945 sigma^10
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER <= 10.
+//
+//    Input, double MU, the mean of the distribution.
+//
+//    Input, double SIGMA, the standard deviation of the distribution.
+//
+//    Output, double NORMAL_MS_MOMENT_CENTRAL_VALUES, the value of the
+//    central moment.
+//
+{
+  double value;
+
+  if (order == 0) {
+    value = 1.0;
+  } else if (order == 1) {
+    value = 0.0;
+  } else if (order == 2) {
+    value = pow(sigma, 2);
+  } else if (order == 3) {
+    value = 0.0;
+  } else if (order == 4) {
+    value = 3.0 * pow(sigma, 4);
+  } else if (order == 5) {
+    value = 0.0;
+  } else if (order == 6) {
+    value = 15.0 * pow(sigma, 6);
+  } else if (order == 7) {
+    value = 0.0;
+  } else if (order == 8) {
+    value = 105.0 * pow(sigma, 8);
+  } else if (order == 9) {
+    value = 0.0;
+  } else if (order == 10) {
+    value = 945.0 * pow(sigma, 10);
+  } else {
+    cerr << "\n";
+    cerr << "NORMAL_MS_MOMENT_CENTRAL_VALUES - Fatal error!\n";
+    cerr << "  Only ORDERS 0 through 10 are available.\n";
+    exit(1);
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_ms_moment_values(int order, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MOMENT_VALUES evaluates moments 0 through 8 of the Normal PDF.
+//
+//  Discussion:
+//
+//    The formula was posted by John D Cook.
+//
+//    Order  Moment
+//    -----  ------
+//      0    1
+//      1    mu
+//      2    mu^2 +         sigma^2
+//      3    mu^3 +  3 mu   sigma^2
+//      4    mu^4 +  6 mu^2 sigma^2 +   3      sigma^4
+//      5    mu^5 + 10 mu^3 sigma^2 +  15 mu   sigma^4
+//      6    mu^6 + 15 mu^4 sigma^2 +  45 mu^2 sigma^4 +  15      sigma^6
+//      7    mu^7 + 21 mu^5 sigma^2 + 105 mu^3 sigma^4 + 105 mu   sigma^6
+//      8    mu^8 + 28 mu^6 sigma^2 + 210 mu^4 sigma^4 + 420 mu^2 sigma^6
+//           + 105 sigma^8
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER <= 8.
+//
+//    Input, double MU, the mean of the distribution.
+//
+//    Input, double SIGMA, the standard deviation of the distribution.
+//
+//    Output, double NORMAL_MS_MOMENT_VALUES, the value of the central moment.
+//
+{
+  double value;
+
+  if (order == 0) {
+    value = 1.0;
+  } else if (order == 1) {
+    value = mu;
+  } else if (order == 2) {
+    value = pow(mu, 2) + pow(sigma, 2);
+  } else if (order == 3) {
+    value = pow(mu, 3) + 3.0 * mu * pow(sigma, 2);
+  } else if (order == 4) {
+    value = pow(mu, 4) + 6.0 * pow(mu, 2) * pow(sigma, 2) + 3.0 * pow(sigma, 4);
+  } else if (order == 5) {
+    value = pow(mu, 5) + 10.0 * pow(mu, 3) * pow(sigma, 2) +
+            15.0 * mu * pow(sigma, 4);
+  } else if (order == 6) {
+    value = pow(mu, 6) + 15.0 * pow(mu, 4) * pow(sigma, 2) +
+            45.0 * pow(mu, 2) * pow(sigma, 4) + 15.0 * pow(sigma, 6);
+  } else if (order == 7) {
+    value = pow(mu, 7) + 21.0 * pow(mu, 5) * pow(sigma, 2) +
+            105.0 * pow(mu, 3) * pow(sigma, 4) + 105.0 * mu * pow(sigma, 6);
+  } else if (order == 8) {
+    value = pow(mu, 8) + 28.0 * pow(mu, 6) * pow(sigma, 2) +
+            210.0 * pow(mu, 4) * pow(sigma, 4) +
+            420.0 * pow(mu, 2) * pow(sigma, 6) + 105.0 * pow(sigma, 8);
+  } else {
+    cerr << "\n";
+    cerr << "NORMAL_MS_MOMENT_VALUES - Fatal error!\n";
+    cerr << "  Only ORDERS 0 through 8 are available.\n";
+    exit(1);
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double normal_ms_pdf(double x, double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_PDF evaluates the Normal PDF.
+//
+//  Discussion:
+//
+//    PDF(MU,SIGMA;X)
+//      = exp ( - 0.5 * ( ( X - MU ) / SIGMA )^2 )
+//      / ( SIGMA * SQRT ( 2 * PI ) )
+//
+//    The normal PDF is also known as the Gaussian PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the PDF.
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Output, double NORMAL_MS_PDF, the value of the PDF.
+//
+{
+  double pdf;
+  const double r8_pi = 3.14159265358979323;
+  double y;
+
+  y = (x - mu) / sigma;
+
+  pdf = exp(-0.5 * y * y) / (sigma * sqrt(2.0 * r8_pi));
+
+  return pdf;
+}
+//****************************************************************************80
+
+double normal_ms_sample(double mu, double sigma, int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_SAMPLE samples the Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    20 November 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Input/output, int &SEED, a seed for the random number generator.
+//
+//    Output, double NORMAL_MS_SAMPLE, a sample of the PDF.
+//
+{
+  double x;
+
+  x = normal_01_sample(seed);
+
+  x = mu + sigma * x;
+
+  return x;
+}
+//****************************************************************************80
+
+double normal_ms_variance(double mu, double sigma)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_VARIANCE returns the variance of the Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 September 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the parameters of the PDF.
+//    0.0 < SIGMA.
+//
+//    Output, double NORMAL_MS_VARIANCE, the variance of the PDF.
+//
+{
+  double variance;
+
+  variance = sigma * sigma;
+
+  return variance;
+}
+//****************************************************************************80
+
+double r8_abs(double x)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_ABS returns the absolute value of an R8.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 November 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the quantity whose absolute value is desired.
+//
+//    Output, double R8_ABS, the absolute value of X.
+//
+{
+  double value;
+
+  if (0.0 <= x) {
+    value = x;
+  } else {
+    value = -x;
+  }
+  return value;
+}
+//****************************************************************************80
+
+double r8_choose(int n, int k)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_CHOOSE computes the binomial coefficient C(N,K) as an R8.
+//
+//  Discussion:
+//
+//    The value is calculated in such a way as to avoid overflow and
+//    roundoff.  The calculation is done in R8 arithmetic.
+//
+//    The formula used is:
+//
+//      C(N,K) = N! / ( K! * (N-K)! )
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    09 June 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    ML Wolfson, HV Wright,
+//    Algorithm 160:
+//    Combinatorial of M Things Taken N at a Time,
+//    Communications of the ACM,
+//    Volume 6, Number 4, April 1963, page 161.
+//
+//  Parameters:
+//
+//    Input, int N, K, the values of N and K.
+//
+//    Output, double R8_CHOOSE, the number of combinations of N
+//    things taken K at a time.
+//
+{
+  int i;
+  int mn;
+  int mx;
+  double value;
+
+  if (k < n - k) {
+    mn = k;
+    mx = n - k;
+  } else {
+    mn = n - k;
+    mx = k;
+  }
+
+  if (mn < 0) {
+    value = 0.0;
+  } else if (mn == 0) {
+    value = 1.0;
+  } else {
+    value = (double)(mx + 1);
+
+    for (i = 2; i <= mn; i++) {
+      value = (value * (double)(mx + i)) / (double)i;
+    }
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double r8_factorial2(int n)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_FACTORIAL2 computes the double factorial function.
+//
+//  Discussion:
+//
+//    FACTORIAL2( N ) = Product ( N * (N-2) * (N-4) * ... * 2 )  (N even)
+//                    = Product ( N * (N-2) * (N-4) * ... * 1 )  (N odd)
+//
+//  Example:
+//
+//     N Value
+//
+//     0     1
+//     1     1
+//     2     2
+//     3     3
+//     4     8
+//     5    15
+//     6    48
+//     7   105
+//     8   384
+//     9   945
+//    10  3840
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    22 January 2008
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the argument of the double factorial
+//    function.  If N is less than 1, R8_FACTORIAL2 is returned as 1.0.
+//
+//    Output, double R8_FACTORIAL2, the value of Factorial2(N).
+//
+{
+  int n_copy;
+  double value;
+
+  value = 1.0;
+
+  if (n < 1) {
+    return value;
+  }
+
+  n_copy = n;
+
+  while (1 < n_copy) {
+    value = value * (double)n_copy;
+    n_copy = n_copy - 2;
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+void r8_factorial2_values(int &n_data, int &n, double &f)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_FACTORIAL2_VALUES returns values of the double factorial function.
+//
+//  Formula:
+//
+//    FACTORIAL2( N ) = Product ( N * (N-2) * (N-4) * ... * 2 )  (N even)
+//                    = Product ( N * (N-2) * (N-4) * ... * 1 )  (N odd)
+//
+//    In Mathematica, the function can be evaluated by:
+//
+//      n!!
+//
+//  Example:
+//
+//     N    N!!
+//
+//     0     1
+//     1     1
+//     2     2
+//     3     3
+//     4     8
+//     5    15
+//     6    48
+//     7   105
+//     8   384
+//     9   945
+//    10  3840
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Milton Abramowitz, Irene Stegun,
+//    Handbook of Mathematical Functions,
+//    National Bureau of Standards, 1964,
+//    ISBN: 0-486-61272-4,
+//    LC: QA47.A34.
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//    Daniel Zwillinger,
+//    CRC Standard Mathematical Tables and Formulae,
+//    30th Edition,
+//    CRC Press, 1996, page 16.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, int &N, the argument of the function.
+//
+//    Output, double &F, the value of the function.
+//
+{
+#define N_MAX 16
+
+  static double f_vec[N_MAX] = {
+      1.0,   1.0,   2.0,    3.0,     8.0,     15.0,     48.0,     105.0,
+      384.0, 945.0, 3840.0, 10395.0, 46080.0, 135135.0, 645120.0, 2027025.0};
+
+  static int n_vec[N_MAX] = {0, 1, 2,  3,  4,  5,  6,  7,
+                             8, 9, 10, 11, 12, 13, 14, 15};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    n = 0;
+    f = 0.0;
+  } else {
+    n = n_vec[n_data - 1];
+    f = f_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double r8_huge()
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_HUGE returns a "huge" R8.
+//
+//  Discussion:
+//
+//    HUGE_VAL is the largest representable legal real number, and is usually
+//    defined in math.h, or sometimes in stdlib.h.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    08 May 2003
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Output, double R8_HUGE, a "huge" real value.
+//
+{
+  return HUGE_VAL;
+}
+//****************************************************************************80
+
+double r8_log_2(double x)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_LOG_2 returns the logarithm base 2 of the absolute value of an R8.
+//
+//  Discussion:
+//
+//    value = Log ( |X| ) / Log ( 2.0 )
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    22 March 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the number whose base 2 logarithm is desired.
+//    X should not be 0.
+//
+//    Output, double R8_LOG_2, the logarithm base 2 of the absolute
+//    value of X.  It should be true that |X| = 2^R_LOG_2.
+//
+{
+  double value;
+
+  if (x == 0.0) {
+    value = -r8_huge();
+  } else {
+    value = log(fabs(x)) / log(2.0);
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double r8_mop(int i)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_MOP returns the I-th power of -1 as an R8 value.
+//
+//  Discussion:
+//
+//    An R8 is an double value.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    16 November 2007
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int I, the power of -1.
+//
+//    Output, double R8_MOP, the I-th power of -1.
+//
+{
+  double value;
+
+  if ((i % 2) == 0) {
+    value = 1.0;
+  } else {
+    value = -1.0;
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double r8_uniform_01(int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_UNIFORM_01 returns a unit pseudorandom R8.
+//
+//  Discussion:
+//
+//    This routine implements the recursion
+//
+//      seed = 16807 * seed mod ( 2^31 - 1 )
+//      unif = seed / ( 2^31 - 1 )
+//
+//    The integer arithmetic never requires more than 32 bits,
+//    including a sign bit.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 August 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Paul Bratley, Bennett Fox, Linus Schrage,
+//    A Guide to Simulation,
+//    Springer Verlag, pages 201-202, 1983.
+//
+//    Bennett Fox,
+//    Algorithm 647:
+//    Implementation and Relative Efficiency of Quasirandom
+//    Sequence Generators,
+//    ACM Transactions on Mathematical Software,
+//    Volume 12, Number 4, pages 362-376, 1986.
+//
+//  Parameters:
+//
+//    Input/output, int &SEED, the "seed" value.  Normally, this
+//    value should not be 0.  On output, SEED has been updated.
+//
+//    Output, double R8_UNIFORM_01, a new pseudorandom variate, strictly between
+//    0 and 1.
+//
+{
+  int k;
+  double r;
+
+  k = seed / 127773;
+
+  seed = 16807 * (seed - k * 127773) - k * 2836;
+
+  if (seed < 0) {
+    seed = seed + 2147483647;
+  }
+
+  r = (double)(seed)*4.656612875E-10;
+
+  return r;
+}
+//****************************************************************************80
+
+void r8poly_print(int n, double a[], string title)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8POLY_PRINT prints out a polynomial.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    26 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the dimension of A.
+//
+//    Input, double A[N+1], the polynomial coefficients.
+//    A(0) is the constant term and
+//    A(N) is the coefficient of X^N.
+//
+//    Input, string TITLE, a title.
+//
+{
+  int i;
+  double mag;
+  int n2;
+  char plus_minus;
+
+  cout << "\n";
+  cout << title << "\n";
+  cout << "\n";
+
+  if (n <= 0) {
+    cout << "  p(x) = 0\n";
+    return;
+  }
+
+  if (a[n] < 0.0) {
+    plus_minus = '-';
+  } else {
+    plus_minus = ' ';
+  }
+
+  mag = fabs(a[n]);
+
+  if (2 <= n) {
+    cout << "  p(x) = " << plus_minus << setw(14) << mag << " * x ^ " << n
+         << "\n";
+  } else if (n == 1) {
+    cout << "  p(x) = " << plus_minus << setw(14) << mag << " * x\n";
+  } else if (n == 0) {
+    cout << "  p(x) = " << plus_minus << setw(14) << mag << "\n";
+  }
+
+  for (i = n - 1; 0 <= i; i--) {
+    if (a[i] < 0.0) {
+      plus_minus = '-';
+    } else {
+      plus_minus = '+';
+    }
+
+    mag = fabs(a[i]);
+
+    if (mag != 0.0) {
+      if (2 <= i) {
+        cout << "         " << plus_minus << setw(14) << mag << " * x ^ " << i
+             << "\n";
+      } else if (i == 1) {
+        cout << "         " << plus_minus << setw(14) << mag << " * x\n";
+      } else if (i == 0) {
+        cout << "         " << plus_minus << setw(14) << mag << "\n";
+      }
+    }
+  }
+
+  return;
+}
+//****************************************************************************80
+
+double r8poly_value_horner(int m, double c[], double x)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8POLY_VALUE_HORNER evaluates a polynomial using Horner's method.
+//
+//  Discussion:
+//
+//    The polynomial
+//
+//      p(x) = c0 + c1 * x + c2 * x^2 + ... + cm * x^m
+//
+//    is to be evaluated at the value X.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    02 January 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int M, the degree of the polynomial.
+//
+//    Input, double C[M+1], the coefficients of the polynomial.
+//    A[0] is the constant term.
+//
+//    Input, double X, the point at which the polynomial is to be evaluated.
+//
+//    Output, double R8POLY_VALUE_HORNER, the value of the polynomial at X.
+//
+{
+  int i;
+  double value;
+
+  value = c[m];
+
+  for (i = m - 1; 0 <= i; i--) {
+    value = value * x + c[i];
+  }
+
+  return value;
+}
+//****************************************************************************80
+
+double *r8vec_linspace_new(int n, double a_first, double a_last)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_LINSPACE_NEW creates a vector of linearly spaced values.
+//
+//  Discussion:
+//
+//    An R8VEC is a vector of R8's.
+//
+//    4 points evenly spaced between 0 and 12 will yield 0, 4, 8, 12.
+//
+//    In other words, the interval is divided into N-1 even subintervals,
+//    and the endpoints of intervals are used as the points.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    29 March 2011
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of entries in the vector.
+//
+//    Input, double A_FIRST, A_LAST, the first and last entries.
+//
+//    Output, double R8VEC_LINSPACE_NEW[N], a vector of linearly spaced data.
+//
+{
+  double *a;
+  int i;
+
+  a = new double[n];
+
+  if (n == 1) {
+    a[0] = (a_first + a_last) / 2.0;
+  } else {
+    for (i = 0; i < n; i++) {
+      a[i] = ((double)(n - 1 - i) * a_first + (double)(i)*a_last) /
+             (double)(n - 1);
+    }
+  }
+  return a;
+}
+//****************************************************************************80
+
+double r8vec_max(int n, double *dvec)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_MAX returns the value of the maximum element in an R8VEC.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    15 October 1998
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of entries in the array.
+//
+//    Input, double *RVEC, a pointer to the first entry of the array.
+//
+//    Output, double R8VEC_MAX, the value of the maximum element.  This
+//    is set to 0.0 if N <= 0.
+//
+{
+  int i;
+  double rmax;
+  double *r8vec_pointer;
+
+  if (n <= 0) {
+    return 0.0;
+  }
+
+  for (i = 0; i < n; i++) {
+    if (i == 0) {
+      rmax = *dvec;
+      r8vec_pointer = dvec;
+    } else {
+      r8vec_pointer++;
+      if (rmax < *r8vec_pointer) {
+        rmax = *r8vec_pointer;
+      }
+    }
+  }
+
+  return rmax;
+}
+//****************************************************************************80
+
+double r8vec_mean(int n, double x[])
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_MEAN returns the mean of an R8VEC.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    01 May 1999
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of entries in the vector.
+//
+//    Input, double X[N], the vector whose mean is desired.
+//
+//    Output, double R8VEC_MEAN, the mean, or average, of the vector entries.
+//
+{
+  int i;
+  double mean;
+
+  mean = 0.0;
+  for (i = 0; i < n; i++) {
+    mean = mean + x[i];
+  }
+
+  mean = mean / (double)n;
+
+  return mean;
+}
+//****************************************************************************80
+
+double r8vec_min(int n, double *dvec)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_MIN returns the value of the minimum element in an R8VEC.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    15 October 1998
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of entries in the array.
+//
+//    Input, double *RVEC, a pointer to the first entry of the array.
+//
+//    Output, double R8VEC_MIN, the value of the minimum element.  This
+//    is set to 0.0 if N <= 0.
+//
+{
+  int i;
+  double rmin;
+  double *r8vec_pointer;
+
+  if (n <= 0) {
+    return 0.0;
+  }
+
+  for (i = 0; i < n; i++) {
+    if (i == 0) {
+      rmin = *dvec;
+      r8vec_pointer = dvec;
+    } else {
+      r8vec_pointer++;
+      if (*r8vec_pointer < rmin) {
+        rmin = *r8vec_pointer;
+      }
+    }
+  }
+
+  return rmin;
+}
+//****************************************************************************80
+
+void r8vec_print(int n, double a[], string title)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_PRINT prints an R8VEC.
+//
+//  Discussion:
+//
+//    An R8VEC is a vector of R8's.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    16 August 2004
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of components of the vector.
+//
+//    Input, double A[N], the vector to be printed.
+//
+//    Input, string TITLE, a title.
+//
+{
+  int i;
+
+  cout << "\n";
+  cout << title << "\n";
+  cout << "\n";
+  for (i = 0; i < n; i++) {
+    cout << "  " << setw(8) << i << ": " << setw(14) << a[i] << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+double r8vec_variance(int n, double x[])
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_VARIANCE returns the variance of an R8VEC.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    01 May 1999
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int N, the number of entries in the vector.
+//
+//    Input, double X[N], the vector whose variance is desired.
+//
+//    Output, double R8VEC_VARIANCE, the variance of the vector entries.
+//
+{
+  int i;
+  double mean;
+  double variance;
+
+  mean = r8vec_mean(n, x);
+
+  variance = 0.0;
+  for (i = 0; i < n; i++) {
+    variance = variance + (x[i] - mean) * (x[i] - mean);
+  }
+
+  if (1 < n) {
+    variance = variance / (double)(n - 1);
+  } else {
+    variance = 0.0;
+  }
+
+  return variance;
+}
+//****************************************************************************80
+
+void timestamp()
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TIMESTAMP prints the current YMDHMS date as a time stamp.
+//
+//  Example:
+//
+//    31 May 2001 09:45:54 AM
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    08 July 2009
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    None
+//
+{
+#define TIME_SIZE 40
+
+  static char time_buffer[TIME_SIZE];
+  const struct std::tm *tm_ptr;
+  size_t len;
+  std::time_t now;
+
+  now = std::time(NULL);
+  tm_ptr = std::localtime(&now);
+
+  len = std::strftime(time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr);
+
+  std::cout << time_buffer << "\n";
+
+  return;
+#undef TIME_SIZE
+}
+//****************************************************************************80
+
+double truncated_normal_ab_cdf(double x, double mu, double sigma, double a,
+                               double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_CDF evaluates the truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the CDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Output, double TRUNCATED_NORMAL_AB_CDF, the value of the CDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double beta;
+  double beta_cdf;
+  double cdf;
+  double xi;
+  double xi_cdf;
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+  xi_cdf = normal_01_cdf(xi);
+
+  cdf = (xi_cdf - alpha_cdf) / (beta_cdf - alpha_cdf);
+
+  return cdf;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_cdf_values(int &n_data, double &mu, double &sigma,
+                                    double &a, double &b, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_CDF_VALUES: values of the Truncated Normal CDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval [A,B].
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    13 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &A, &B, the lower and upper truncation limits.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double a_vec[N_MAX] = {50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+                                50.0, 50.0, 50.0, 50.0, 50.0};
+
+  static double b_vec[N_MAX] = {150.0, 150.0, 150.0, 150.0, 150.0, 150.0,
+                                150.0, 150.0, 150.0, 150.0, 150.0};
+
+  static double fx_vec[N_MAX] = {
+      0.3371694242213513, 0.3685009225506048, 0.4006444233448185,
+      0.4334107066903040, 0.4665988676496338, 0.5000000000000000,
+      0.5334011323503662, 0.5665892933096960, 0.5993555766551815,
+      0.6314990774493952, 0.6628305757786487};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    a = 0.0;
+    b = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    a = a_vec[n_data - 1];
+    b = b_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_ab_cdf_inv(double cdf, double mu, double sigma,
+                                   double a, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_CDF_INV inverts the truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double CDF, the value of the CDF.
+//    0.0 <= CDF <= 1.0.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Output, double TRUNCATED_NORMAL_AB_CDF_INV, the corresponding argument.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double beta;
+  double beta_cdf;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  if (cdf < 0.0 || 1.0 < cdf) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_CDF_INV - Fatal error!\n";
+    cerr << "  CDF < 0 or 1 < CDF.\n";
+    exit(1);
+  }
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+
+  xi_cdf = (beta_cdf - alpha_cdf) * cdf + alpha_cdf;
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_ab_mean(double mu, double sigma, double a, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_MEAN returns the mean of the truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Output, double TRUNCATED_NORMAL_AB_MEAN, the mean of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double alpha_pdf;
+  double beta;
+  double beta_cdf;
+  double beta_pdf;
+  double mean;
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+
+  alpha_pdf = normal_01_pdf(alpha);
+  beta_pdf = normal_01_pdf(beta);
+
+  mean = mu + sigma * (alpha_pdf - beta_pdf) / (beta_cdf - alpha_cdf);
+
+  return mean;
+}
+//****************************************************************************80
+
+double truncated_normal_ab_moment(int order, double mu, double sigma, double a,
+                                  double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_MOMENT: moments of the truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Phoebus Dhrymes,
+//    Moments of Truncated Normal Distributions,
+//    May 2005.
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//    0.0 < S.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//    A < B.
+//
+//    Output, double TRUNCATED_NORMAL_AB_MOMENT, the moment of the PDF.
+//
+{
+  double a_cdf;
+  double a_h;
+  double a_pdf;
+  double b_cdf;
+  double b_h;
+  double b_pdf;
+  double ir;
+  double irm1;
+  double irm2;
+  double moment;
+  int r;
+
+  if (order < 0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_MOMENT - Fatal error!\n";
+    cerr << "  ORDER < 0.\n";
+    exit(1);
+  }
+
+  if (sigma <= 0.0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_MOMENT - Fatal error!\n";
+    cerr << "  SIGMA <= 0.0.\n";
+    exit(1);
+  }
+
+  if (b <= a) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_MOMENT - Fatal error!\n";
+    cerr << "  B <= A.\n";
+    exit(1);
+  }
+
+  a_h = (a - mu) / sigma;
+  a_pdf = normal_01_pdf(a_h);
+  a_cdf = normal_01_cdf(a_h);
+
+  if (a_cdf == 0.0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_MOMENT - Fatal error!\n";
+    cerr << "  PDF/CDF ratio fails, because A_CDF too small.\n";
+    cerr << "  A_PDF = " << a_pdf << "\n";
+    cerr << "  A_CDF = " << a_cdf << "\n";
+    exit(1);
+  }
+
+  b_h = (b - mu) / sigma;
+  b_pdf = normal_01_pdf(b_h);
+  b_cdf = normal_01_cdf(b_h);
+
+  if (b_cdf == 0.0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_AB_MOMENT - Fatal error!\n";
+    cerr << "  PDF/CDF ratio fails, because B_CDF too small.\n";
+    cerr << "  B_PDF = " << b_pdf << "\n";
+    cerr << "  B_CDF = " << b_cdf << "\n";
+    exit(1);
+  }
+
+  moment = 0.0;
+  irm2 = 0.0;
+  irm1 = 0.0;
+
+  for (r = 0; r <= order; r++) {
+    if (r == 0) {
+      ir = 1.0;
+    } else if (r == 1) {
+      ir = -(b_pdf - a_pdf) / (b_cdf - a_cdf);
+    } else {
+      ir =
+          (double)(r - 1) * irm2 -
+          (pow(b_h, r - 1) * b_pdf - pow(a_h, r - 1) * a_pdf) / (b_cdf - a_cdf);
+    }
+
+    moment =
+        moment + r8_choose(order, r) * pow(mu, order - r) * pow(sigma, r) * ir;
+
+    irm2 = irm1;
+    irm1 = ir;
+  }
+
+  return moment;
+}
+//****************************************************************************80
+
+double truncated_normal_ab_pdf(double x, double mu, double sigma, double a,
+                               double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_PDF evaluates the truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the PDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Output, double TRUNCATED_NORMAL_AB_PDF, the value of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double beta;
+  double beta_cdf;
+  double pdf;
+  double xi;
+  double xi_pdf;
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+  xi_pdf = normal_01_pdf(xi);
+
+  pdf = xi_pdf / (beta_cdf - alpha_cdf) / sigma;
+
+  return pdf;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_pdf_values(int &n_data, double &mu, double &sigma,
+                                    double &a, double &b, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_PDF_VALUES: values of the Truncated Normal PDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval [A,B].
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    13 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &A, &B, the lower and upper truncation limits.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double a_vec[N_MAX] = {50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+                                50.0, 50.0, 50.0, 50.0, 50.0};
+
+  static double b_vec[N_MAX] = {150.0, 150.0, 150.0, 150.0, 150.0, 150.0,
+                                150.0, 150.0, 150.0, 150.0, 150.0};
+
+  static double fx_vec[N_MAX] = {
+      0.01543301171801836, 0.01588394472270638, 0.01624375997031919,
+      0.01650575046469259, 0.01666496869385951, 0.01671838200940538,
+      0.01666496869385951, 0.01650575046469259, 0.01624375997031919,
+      0.01588394472270638, 0.01543301171801836};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    a = 0.0;
+    b = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    a = a_vec[n_data - 1];
+    b = b_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_ab_sample(double mu, double sigma, double a, double b,
+                                  int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_SAMPLE samples the truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Input/output, int &SEED, a seed for the random number
+//    generator.
+//
+//    Output, double TRUNCATED_NORMAL_AB_SAMPLE, a sample of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double beta;
+  double beta_cdf;
+  double u;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+
+  u = r8_uniform_01(seed);
+  xi_cdf = alpha_cdf + u * (beta_cdf - alpha_cdf);
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_ab_variance(double mu, double sigma, double a, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_VARIANCE returns the variance of the truncated Normal
+//    PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, B, the lower and upper truncation limits.
+//
+//    Output, double TRUNCATED_NORMAL_AB_VARIANCE, the variance of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double alpha_pdf;
+  double beta;
+  double beta_cdf;
+  double beta_pdf;
+  double variance;
+
+  alpha = (a - mu) / sigma;
+  beta = (b - mu) / sigma;
+
+  alpha_pdf = normal_01_pdf(alpha);
+  beta_pdf = normal_01_pdf(beta);
+
+  alpha_cdf = normal_01_cdf(alpha);
+  beta_cdf = normal_01_cdf(beta);
+
+  variance =
+      sigma * sigma *
+      (1.0 + (alpha * alpha_pdf - beta * beta_pdf) / (beta_cdf - alpha_cdf) -
+       pow((alpha_pdf - beta_pdf) / (beta_cdf - alpha_cdf), 2));
+
+  return variance;
+}
+//****************************************************************************80
+
+double truncated_normal_a_cdf(double x, double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_CDF evaluates the lower truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the CDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_CDF, the value of the CDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double cdf;
+  double xi;
+  double xi_cdf;
+
+  alpha = (a - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  xi_cdf = normal_01_cdf(xi);
+
+  cdf = (xi_cdf - alpha_cdf) / (1.0 - alpha_cdf);
+
+  return cdf;
+}
+//****************************************************************************80
+
+void truncated_normal_a_cdf_values(int &n_data, double &mu, double &sigma,
+                                   double &a, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_CDF_VALUES: values of the Lower Truncated Normal CDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval [A,+oo).
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &A, the lower truncation limit.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double a_vec[N_MAX] = {50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+                                50.0, 50.0, 50.0, 50.0, 50.0};
+
+  static double fx_vec[N_MAX] = {
+      0.3293202045481688, 0.3599223134505957, 0.3913175216041539,
+      0.4233210140873113, 0.4557365629792204, 0.4883601253415709,
+      0.5209836877039214, 0.5533992365958304, 0.5854027290789878,
+      0.6167979372325460, 0.6474000461349729};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    a = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    a = a_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_a_cdf_inv(double cdf, double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_CDF_INV inverts the lower truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double CDF, the value of the CDF.
+//    0.0 <= CDF <= 1.0.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_CDF_INV, the corresponding argument.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  if (cdf < 0.0 || 1.0 < cdf) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_A_CDF_INV - Fatal error!\n";
+    cerr << "  CDF < 0 or 1 < CDF.\n";
+    exit(1);
+  }
+
+  alpha = (a - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+
+  xi_cdf = (1.0 - alpha_cdf) * cdf + alpha_cdf;
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_a_mean(double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_MEAN returns the mean of the lower truncated Normal
+//    PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_MEAN, the mean of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double alpha_pdf;
+  double mean;
+
+  alpha = (a - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+
+  alpha_pdf = normal_01_pdf(alpha);
+
+  mean = mu + sigma * alpha_pdf / (1.0 - alpha_cdf);
+
+  return mean;
+}
+//****************************************************************************80
+
+double truncated_normal_a_moment(int order, double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_MOMENT: moments of the lower truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Phoebus Dhrymes,
+//    Moments of Truncated Normal Distributions,
+//    May 2005.
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_MOMENT, the moment of the PDF.
+//
+{
+  double moment;
+
+  moment = r8_mop(order) * truncated_normal_b_moment(order, -mu, sigma, -a);
+
+  return moment;
+}
+//****************************************************************************80
+
+double truncated_normal_a_pdf(double x, double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_PDF evaluates the lower truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the PDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_PDF, the value of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double pdf;
+  double xi;
+  double xi_pdf;
+
+  alpha = (a - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+  xi_pdf = normal_01_pdf(xi);
+
+  pdf = xi_pdf / (1.0 - alpha_cdf) / sigma;
+
+  return pdf;
+}
+//****************************************************************************80
+
+void truncated_normal_a_pdf_values(int &n_data, double &mu, double &sigma,
+                                   double &a, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_PDF_VALUES: values of the Lower Truncated Normal PDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval [A,+oo).
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &A, the lower truncation limit.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double a_vec[N_MAX] = {50.0, 50.0, 50.0, 50.0, 50.0, 50.0,
+                                50.0, 50.0, 50.0, 50.0, 50.0};
+
+  static double fx_vec[N_MAX] = {
+      0.01507373507401876, 0.01551417047139894, 0.01586560931024694,
+      0.01612150073158793, 0.01627701240029317, 0.01632918226724295,
+      0.01627701240029317, 0.01612150073158793, 0.01586560931024694,
+      0.01551417047139894, 0.01507373507401876};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    a = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    a = a_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_a_sample(double mu, double sigma, double a, int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_SAMPLE samples the lower truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Input/output, int &SEED, a seed for the random number
+//    generator.
+//
+//    Output, double TRUNCATED_NORMAL_A_SAMPLE, a sample of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double u;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  alpha = (a - mu) / sigma;
+
+  alpha_cdf = normal_01_cdf(alpha);
+
+  u = r8_uniform_01(seed);
+  xi_cdf = alpha_cdf + u * (1.0 - alpha_cdf);
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_a_variance(double mu, double sigma, double a)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_VARIANCE: variance of the lower truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double A, the lower truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_A_VARIANCE, the variance of the PDF.
+//
+{
+  double alpha;
+  double alpha_cdf;
+  double alpha_pdf;
+  double variance;
+
+  alpha = (a - mu) / sigma;
+
+  alpha_pdf = normal_01_pdf(alpha);
+
+  alpha_cdf = normal_01_cdf(alpha);
+
+  variance = sigma * sigma * (1.0 + alpha * alpha_pdf / (1.0 - alpha_cdf) -
+                              pow(alpha_pdf / (1.0 - alpha_cdf), 2));
+
+  return variance;
+}
+//****************************************************************************80
+
+double truncated_normal_b_cdf(double x, double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_CDF evaluates the upper truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the CDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_CDF, the value of the CDF.
+//
+{
+  double beta;
+  double beta_cdf;
+  double cdf;
+  double xi;
+  double xi_cdf;
+
+  beta = (b - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  beta_cdf = normal_01_cdf(beta);
+  xi_cdf = normal_01_cdf(xi);
+
+  cdf = xi_cdf / beta_cdf;
+
+  return cdf;
+}
+//****************************************************************************80
+
+void truncated_normal_b_cdf_values(int &n_data, double &mu, double &sigma,
+                                   double &b, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_CDF_VALUES: values of the upper Truncated Normal CDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval (-oo,B].
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &B, the upper truncation limit.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double b_vec[N_MAX] = {150.0, 150.0, 150.0, 150.0, 150.0, 150.0,
+                                150.0, 150.0, 150.0, 150.0, 150.0};
+
+  static double fx_vec[N_MAX] = {
+      0.3525999538650271, 0.3832020627674540, 0.4145972709210122,
+      0.4466007634041696, 0.4790163122960786, 0.5116398746584291,
+      0.5442634370207796, 0.5766789859126887, 0.6086824783958461,
+      0.6400776865494043, 0.6706797954518312};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    b = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    b = b_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_b_cdf_inv(double cdf, double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_CDF_INV inverts the upper truncated Normal CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double CDF, the value of the CDF.
+//    0.0 <= CDF <= 1.0.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_CDF_INV, the corresponding argument.
+//
+{
+  double beta;
+  double beta_cdf;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  if (cdf < 0.0 || 1.0 < cdf) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_B_CDF_INV - Fatal error!\n";
+    cerr << "  CDF < 0 or 1 < CDF.\n";
+    exit(1);
+  }
+
+  beta = (b - mu) / sigma;
+
+  beta_cdf = normal_01_cdf(beta);
+
+  xi_cdf = beta_cdf * cdf;
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_b_mean(double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_MEAN returns the mean of the upper truncated Normal
+//    PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_MEAN, the mean of the PDF.
+//
+{
+  double beta;
+  double beta_cdf;
+  double beta_pdf;
+  double mean;
+
+  beta = (b - mu) / sigma;
+
+  beta_cdf = normal_01_cdf(beta);
+
+  beta_pdf = normal_01_pdf(beta);
+
+  mean = mu - sigma * beta_pdf / beta_cdf;
+
+  return mean;
+}
+//****************************************************************************80
+
+double truncated_normal_b_moment(int order, double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_MOMENT: moments of the upper truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Phoebus Dhrymes,
+//    Moments of Truncated Normal Distributions,
+//    May 2005.
+//
+//  Parameters:
+//
+//    Input, int ORDER, the order of the moment.
+//    0 <= ORDER.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_MOMENT, the moment of the PDF.
+//
+{
+  double f;
+  double h;
+  double h_cdf;
+  double h_pdf;
+  double ir;
+  double irm1;
+  double irm2;
+  double moment;
+  int r;
+
+  if (order < 0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_B_MOMENT - Fatal error!\n";
+    cerr << "  ORDER < 0.\n";
+    exit(1);
+  }
+
+  h = (b - mu) / sigma;
+  h_pdf = normal_01_pdf(h);
+  h_cdf = normal_01_cdf(h);
+
+  if (h_cdf == 0.0) {
+    cerr << "\n";
+    cerr << "TRUNCATED_NORMAL_B_MOMENT - Fatal error!\n";
+    cerr << "  CDF((B-MU)/SIGMA) = 0.\n";
+    exit(1);
+  }
+
+  f = h_pdf / h_cdf;
+
+  moment = 0.0;
+  irm2 = 0.0;
+  irm1 = 0.0;
+
+  for (r = 0; r <= order; r++) {
+    if (r == 0) {
+      ir = 1.0;
+    } else if (r == 1) {
+      ir = -f;
+    } else {
+      ir = -pow(h, r - 1) * f + (double)(r - 1) * irm2;
+    }
+
+    moment =
+        moment + r8_choose(order, r) * pow(mu, order - r) * pow(sigma, r) * ir;
+
+    irm2 = irm1;
+    irm1 = ir;
+  }
+
+  return moment;
+}
+//****************************************************************************80
+
+double truncated_normal_b_pdf(double x, double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_PDF evaluates the upper truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double X, the argument of the PDF.
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_PDF, the value of the PDF.
+//
+{
+  double beta;
+  double beta_cdf;
+  double pdf;
+  double xi;
+  double xi_pdf;
+
+  beta = (b - mu) / sigma;
+  xi = (x - mu) / sigma;
+
+  beta_cdf = normal_01_cdf(beta);
+  xi_pdf = normal_01_pdf(xi);
+
+  pdf = xi_pdf / beta_cdf / sigma;
+
+  return pdf;
+}
+//****************************************************************************80
+
+void truncated_normal_b_pdf_values(int &n_data, double &mu, double &sigma,
+                                   double &b, double &x, double &fx)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_PDF_VALUES: values of the Upper Truncated Normal PDF.
+//
+//  Discussion:
+//
+//    The Normal distribution, with mean Mu and standard deviation Sigma,
+//    is truncated to the interval (-oo,B].
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    Stephen Wolfram,
+//    The Mathematica Book,
+//    Fourth Edition,
+//    Cambridge University Press, 1999,
+//    ISBN: 0-521-64314-7,
+//    LC: QA76.95.W65.
+//
+//  Parameters:
+//
+//    Input/output, int &N_DATA.  The user sets N_DATA to 0 before the
+//    first call.  On each call, the routine increments N_DATA by 1, and
+//    returns the corresponding data; when there is no more data, the
+//    output value of N_DATA will be 0 again.
+//
+//    Output, double &MU, the mean of the distribution.
+//
+//    Output, double &SIGMA, the standard deviation of the distribution.
+//
+//    Output, double &B, the upper truncation limit.
+//
+//    Output, double &X, the argument of the function.
+//
+//    Output, double &FX, the value of the function.
+//
+{
+#define N_MAX 11
+
+  static double b_vec[N_MAX] = {150.0, 150.0, 150.0, 150.0, 150.0, 150.0,
+                                150.0, 150.0, 150.0, 150.0, 150.0};
+
+  static double fx_vec[N_MAX] = {
+      0.01507373507401876, 0.01551417047139894, 0.01586560931024694,
+      0.01612150073158793, 0.01627701240029317, 0.01632918226724295,
+      0.01627701240029317, 0.01612150073158793, 0.01586560931024694,
+      0.01551417047139894, 0.01507373507401876};
+
+  static double mu_vec[N_MAX] = {100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
+                                 100.0, 100.0, 100.0, 100.0, 100.0};
+
+  static double sigma_vec[N_MAX] = {25.0, 25.0, 25.0, 25.0, 25.0, 25.0,
+                                    25.0, 25.0, 25.0, 25.0, 25.0};
+
+  static double x_vec[N_MAX] = {90.0,  92.0,  94.0,  96.0,  98.0, 100.0,
+                                102.0, 104.0, 106.0, 108.0, 110.0};
+
+  if (n_data < 0) {
+    n_data = 0;
+  }
+
+  n_data = n_data + 1;
+
+  if (N_MAX < n_data) {
+    n_data = 0;
+    b = 0.0;
+    mu = 0.0;
+    sigma = 0.0;
+    x = 0.0;
+    fx = 0.0;
+  } else {
+    b = b_vec[n_data - 1];
+    mu = mu_vec[n_data - 1];
+    sigma = sigma_vec[n_data - 1];
+    x = x_vec[n_data - 1];
+    fx = fx_vec[n_data - 1];
+  }
+
+  return;
+#undef N_MAX
+}
+//****************************************************************************80
+
+double truncated_normal_b_sample(double mu, double sigma, double b, int &seed)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_SAMPLE samples the upper truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    21 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Input/output, int &SEED, a seed for the random number
+//    generator.
+//
+//    Output, double TRUNCATED_NORMAL_B_SAMPLE, a sample of the PDF.
+//
+{
+  double beta;
+  double beta_cdf;
+  double u;
+  double x;
+  double xi;
+  double xi_cdf;
+
+  beta = (b - mu) / sigma;
+
+  beta_cdf = normal_01_cdf(beta);
+
+  u = r8_uniform_01(seed);
+  xi_cdf = u * beta_cdf;
+  xi = normal_01_cdf_inv(xi_cdf);
+
+  x = mu + sigma * xi;
+
+  return x;
+}
+//****************************************************************************80
+
+double truncated_normal_b_variance(double mu, double sigma, double b)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_VARIANCE: variance of the upper truncated Normal PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    14 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, double MU, SIGMA, the mean and standard deviation of the
+//    parent Normal distribution.
+//
+//    Input, double B, the upper truncation limit.
+//
+//    Output, double TRUNCATED_NORMAL_B_VARIANCE, the variance of the PDF.
+//
+{
+  double beta;
+  double beta_cdf;
+  double beta_pdf;
+  double variance;
+
+  beta = (b - mu) / sigma;
+
+  beta_pdf = normal_01_pdf(beta);
+
+  beta_cdf = normal_01_cdf(beta);
+
+  variance = sigma * sigma *
+             (1.0 - beta * beta_pdf / beta_cdf - pow(beta_pdf / beta_cdf, 2));
+
+  return variance;
+}

+ 91 - 0
truncated_normal.hpp

@@ -0,0 +1,91 @@
+#include <string>
+using namespace std;
+
+int i4_uniform_ab(int a, int b, int &seed);
+
+double normal_01_cdf(double x);
+double normal_01_cdf_inv(double cdf);
+void normal_01_cdf_values(int &n_data, double &x, double &fx);
+double normal_01_mean();
+double normal_01_moment(int order);
+double normal_01_pdf(double x);
+double normal_01_sample(int &seed);
+double normal_01_variance();
+
+double normal_ms_cdf(double x, double mu, double sigma);
+double normal_ms_cdf_inv(double cdf, double mu, double sigma);
+double normal_ms_mean(double mu, double sigma);
+double normal_ms_moment(int order, double mu, double sigma);
+double normal_ms_moment_central(int order, double mu, double sigma);
+double normal_ms_moment_central_values(int order, double mu, double sigma);
+double normal_ms_moment_values(int order, double mu, double sigma);
+double normal_ms_pdf(double x, double mu, double sigma);
+double normal_ms_sample(double mu, double sigma, int &seed);
+double normal_ms_variance(double mu, double sigma);
+
+double r8_abs(double x);
+double r8_choose(int n, int k);
+double r8_factorial2(int n);
+void r8_factorial2_values(int &n_data, int &n, double &f);
+double r8_huge();
+double r8_log_2(double x);
+double r8_mop(int i);
+double r8_uniform_01(int &seed);
+
+void r8poly_print(int n, double a[], string title);
+double r8poly_value_horner(int n, double a[], double x);
+
+double *r8vec_linspace_new(int n, double a_first, double a_last);
+double r8vec_max(int n, double x[]);
+double r8vec_mean(int n, double x[]);
+double r8vec_min(int n, double x[]);
+void r8vec_print(int n, double a[], string title);
+double r8vec_variance(int n, double x[]);
+
+void timestamp();
+
+double truncated_normal_ab_cdf(double x, double mu, double sigma, double a,
+                               double b);
+void truncated_normal_ab_cdf_values(int &n_data, double &mu, double &sigma,
+                                    double &a, double &b, double &x,
+                                    double &fx);
+double truncated_normal_ab_cdf_inv(double cdf, double mu, double sigma,
+                                   double a, double b);
+double truncated_normal_ab_mean(double mu, double sigma, double a, double b);
+double truncated_normal_ab_moment(int order, double mu, double sigma, double a,
+                                  double b);
+double truncated_normal_ab_pdf(double x, double mu, double sigma, double a,
+                               double b);
+void truncated_normal_ab_pdf_values(int &n_data, double &mu, double &sigma,
+                                    double &a, double &b, double &x,
+                                    double &fx);
+double truncated_normal_ab_sample(double mu, double sigma, double a, double b,
+                                  int &seed);
+double truncated_normal_ab_variance(double mu, double sigma, double a,
+                                    double b);
+
+double truncated_normal_a_cdf(double x, double mu, double sigma, double a);
+void truncated_normal_a_cdf_values(int &n_data, double &mu, double &sigma,
+                                   double &a, double &x, double &fx);
+double truncated_normal_a_cdf_inv(double cdf, double mu, double sigma,
+                                  double a);
+double truncated_normal_a_mean(double mu, double sigma, double a);
+double truncated_normal_a_moment(int order, double mu, double sigma, double a);
+double truncated_normal_a_pdf(double x, double mu, double sigma, double a);
+void truncated_normal_a_pdf_values(int &n_data, double &mu, double &sigma,
+                                   double &a, double &x, double &fx);
+double truncated_normal_a_sample(double mu, double sigma, double a, int &seed);
+double truncated_normal_a_variance(double mu, double sigma, double a);
+
+double truncated_normal_b_cdf(double x, double mu, double sigma, double b);
+void truncated_normal_b_cdf_values(int &n_data, double &mu, double &sigma,
+                                   double &b, double &x, double &fx);
+double truncated_normal_b_cdf_inv(double cdf, double mu, double sigma,
+                                  double b);
+double truncated_normal_b_mean(double mu, double sigma, double b);
+double truncated_normal_b_moment(int order, double mu, double sigma, double b);
+double truncated_normal_b_pdf(double x, double mu, double sigma, double b);
+void truncated_normal_b_pdf_values(int &n_data, double &mu, double &sigma,
+                                   double &b, double &x, double &fx);
+double truncated_normal_b_sample(double mu, double sigma, double b, int &seed);
+double truncated_normal_b_variance(double mu, double sigma, double b);

+ 2824 - 0
truncated_normal_prb.cpp

@@ -0,0 +1,2824 @@
+# include <cstdlib>
+# include <iostream>
+# include <iomanip>
+# include <cmath>
+# include <ctime>
+
+using namespace std;
+
+# include "truncated_normal.hpp"
+
+int main ( );
+
+void i4_uniform_ab_test ( );
+
+void normal_01_cdf_test ( );
+void normal_01_cdf_inv_test ( );
+void normal_01_mean_test ( );
+void normal_01_moment_test ( );
+void normal_01_pdf_test ( );
+void normal_01_sample_test ( );
+void normal_01_variance_test ( );
+
+void normal_ms_cdf_test ( );
+void normal_ms_cdf_inv_test ( );
+void normal_ms_mean_test ( );
+void normal_ms_moment_test ( );
+void normal_ms_moment_central_test ( );
+void normal_ms_pdf_test ( );
+void normal_ms_sample_test ( );
+void normal_ms_variance_test ( );
+
+void r8_choose_test ( );
+void r8_factorial2_test ( );
+void r8_mop_test ( );
+void r8_uniform_01_test ( );
+
+void r8poly_print_test ( );
+void r8poly_value_horner_test ( );
+
+void r8vec_linspace_new_test ( );
+void r8vec_print_test ( );
+
+void truncated_normal_a_cdf_test ( );
+void truncated_normal_a_cdf_inv_test ( );
+void truncated_normal_a_mean_test ( );
+void truncated_normal_a_moment_test ( );
+void truncated_normal_a_pdf_test ( );
+void truncated_normal_a_sample_test ( );
+void truncated_normal_a_variance_test ( );
+
+void truncated_normal_ab_cdf_test ( );
+void truncated_normal_ab_cdf_inv_test ( );
+void truncated_normal_ab_mean_test ( );
+void truncated_normal_ab_moment_test ( );
+void truncated_normal_ab_pdf_test ( );
+void truncated_normal_ab_sample_test ( );
+void truncated_normal_ab_variance_test ( );
+
+void truncated_normal_b_cdf_test ( );
+void truncated_normal_b_cdf_inv_test ( );
+void truncated_normal_b_mean_test ( );
+void truncated_normal_b_moment_test ( );
+void truncated_normal_b_pdf_test ( );
+void truncated_normal_b_sample_test ( );
+void truncated_normal_b_variance_test ( );
+
+//****************************************************************************80
+
+int main ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    MAIN is the main program for TRUNCATED_NORMAL_PRB.
+//
+//  Discussion:
+//
+//    TRUNCATED_NORMAL_PRB tests the TRUNCATED_NORMAL library.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  timestamp ( );
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_PRB\n";
+  cout << "  C++ version.\n";
+  cout << "  Test the TRUNCATED_NORMAL library.\n";
+//
+//  Utilities.
+//
+  i4_uniform_ab_test ( );
+  r8_choose_test ( );
+  r8_factorial2_test ( );
+  r8_mop_test ( );
+  r8_uniform_01_test ( );
+  r8poly_print_test ( );
+  r8poly_value_horner_test ( ); 
+  r8vec_linspace_new_test ( );
+  r8vec_print_test ( );
+//
+//  Library.
+//
+  normal_01_cdf_test ( );
+  normal_01_cdf_inv_test ( );
+  normal_01_mean_test ( );
+  normal_01_moment_test ( );
+  normal_01_pdf_test ( );
+  normal_01_sample_test ( );
+  normal_01_variance_test ( );
+
+  normal_ms_cdf_test ( );
+  normal_ms_cdf_inv_test ( );
+  normal_ms_mean_test ( );
+  normal_ms_moment_test ( );
+  normal_ms_moment_central_test ( );
+  normal_ms_pdf_test ( );
+  normal_ms_sample_test ( );
+  normal_ms_variance_test ( );
+
+  truncated_normal_a_cdf_test ( );
+  truncated_normal_a_cdf_inv_test ( );
+  truncated_normal_a_mean_test ( );
+  truncated_normal_a_moment_test ( );
+  truncated_normal_a_pdf_test ( );
+  truncated_normal_a_sample_test ( );
+  truncated_normal_a_variance_test ( );
+
+  truncated_normal_ab_cdf_test ( );
+  truncated_normal_ab_cdf_inv_test ( );
+  truncated_normal_ab_mean_test ( );
+  truncated_normal_ab_moment_test ( );
+  truncated_normal_ab_pdf_test ( );
+  truncated_normal_ab_sample_test ( );
+  truncated_normal_ab_variance_test ( );
+
+  truncated_normal_b_cdf_test ( );
+  truncated_normal_b_cdf_inv_test ( );
+  truncated_normal_b_mean_test ( );
+  truncated_normal_b_moment_test ( );
+  truncated_normal_b_pdf_test ( );
+  truncated_normal_b_sample_test ( );
+  truncated_normal_b_variance_test ( );
+//
+//  Terminate.
+//
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_PRB\n";
+  cout << "  Normal end of execution.\n";
+  cout << "\n";
+  timestamp ( );
+
+  return 0;
+}
+//****************************************************************************80
+
+void i4_uniform_ab_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    I4_UNIFORM_AB_TEST tests I4_UNIFORM_AB.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    27 October 2014
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int a = -100;
+  int b = 200;
+  int i;
+  int j;
+  int seed = 123456789;
+
+  cout << "\n";
+  cout << "I4_UNIFORM_AB_TEST\n";
+  cout << "  I4_UNIFORM_AB computes pseudorandom values\n";
+  cout << "  in an interval [A,B].\n";
+
+  cout << "\n";
+  cout << "  The lower endpoint A = " << a << "\n";
+  cout << "  The upper endpoint B = " << b << "\n";
+  cout << "  The initial seed is " << seed << "\n";
+  cout << "\n";
+
+  for ( i = 1; i <= 20; i++ )
+  {
+    j = i4_uniform_ab ( a, b, seed );
+
+    cout << "  " << setw(8) << i
+         << "  " << setw(8) << j << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_cdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_CDF_TEST tests NORMAL_01_CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    27 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double cdf1;
+  double cdf2;
+  int n_data;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_01_CDF_TEST\n";
+  cout << "  NORMAL_01_CDF evaluates the Normal 01 CDF;\n";
+  cout << "\n";
+  cout << "       X              CDF                       CDF\n";
+  cout << "                     (exact)                   (computed)\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    normal_01_cdf_values ( n_data, x, cdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+
+    cdf2 = normal_01_cdf ( x );
+
+    cout << "  " << setw(14) << x
+         << "  " << setw(24) << cdf1
+         << "  " << setw(24) << cdf2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_cdf_inv_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_CDF_INV_TEST tests NORMAL_01_CDF_INV.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    28 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double cdf;
+  int n_data;
+  double x1;
+  double x2;
+
+  cout << "\n";
+  cout << "NORMAL_01_CDF_INV_TEST\n";
+  cout << "  NORMAL_01_CDF_INV inverts the Normal 01 CDF;\n";
+  cout << "\n";
+  cout << "      CDF             X                         X\n";
+  cout << "                     (exact)                   (computed)\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    normal_01_cdf_values ( n_data, x1, cdf );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+
+    x2 = normal_01_cdf_inv ( cdf );
+
+    cout << "  " << setw(14) << cdf
+         << "  " << setw(24) << x1
+         << "  " << setw(24) << x2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_mean_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_MEAN_TEST tests NORMAL_01_MEAN.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    01 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double mean;
+  int sample_num;
+  int seed = 123456789;
+  double *x;
+  double xmax;
+  double xmin;
+
+  cout << "\n";
+  cout << "NORMAL_01_MEAN_TEST\n";
+  cout << "  NORMAL_01_MEAN computes the Normal 01 mean;\n";
+
+  mean = normal_01_mean ( );
+
+  cout << "\n";
+  cout << "  PDF mean =     " << mean     << "\n";
+
+  sample_num = 1000;
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = normal_01_sample ( seed );
+  }
+
+  mean = r8vec_mean ( sample_num, x );
+  xmax = r8vec_max ( sample_num, x );
+  xmin = r8vec_min ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num  << "\n";
+  cout << "  Sample mean =     " << mean     << "\n";
+  cout << "  Sample maximum =  " << xmax     << "\n";
+  cout << "  Sample minimum =  " << xmin     << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_moment_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_MOMENT_TEST tests NORMAL_01_MOMENT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    01 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double moment;
+  int order;
+
+  cout << "\n";
+  cout << "NORMAL_01_MOMENT_TEST\n";
+  cout << "  NORMAL_01_MOMENT evaluates Normal 01 moments;\n";
+  cout << "\n";
+  cout << "      Order              Moment\n";
+  cout << "\n";
+
+  for ( order = 0; order <= 10; order++ )
+  {
+    moment = normal_01_moment ( order );
+
+    cout << "  " << setw(14) << order
+         << "  " << setw(14) << moment << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_pdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_PDF_TEST tests NORMAL_01_PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    01 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double pdf;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_01_PDF_TEST\n";
+  cout << "  NORMAL_01_PDF evaluates the Normal 01 PDF;\n";
+  cout << "\n";
+  cout << "       X              PDF\n";
+  cout << "\n";
+
+  for ( i = - 20; i <= 20; i++ )
+  {
+    x = ( double ) ( i ) / 10.0;
+
+    pdf = normal_01_pdf ( x );
+
+    cout << "  " << setw(14) << x
+         << "  " << setw(14) << pdf << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_sample_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_SAMPLE_TEST tests NORMAL_01_SAMPLE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    26 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  int seed;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_01_SAMPLE_TEST\n";
+  cout << "  NORMAL_01_SAMPLE returns samples from the normal\n";
+  cout << "  distribution with mean 0 and standard deviation 1.\n";
+  cout << "\n";
+
+  seed = 123456789;
+
+  for ( i = 1; i <= 10; i++ )
+  {
+    x = normal_01_sample ( seed );
+    cout << "  " << setw(4) << i
+         << "  " << setw(14) << x << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_01_variance_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_01_VARIANCE_TEST tests NORMAL_01_VARIANCE;
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    02 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  int sample_num;
+  int seed = 123456789;
+  double variance;
+  double *x;
+
+  cout << "\n";
+  cout << "NORMAL_01_VARIANCE_TEST\n";
+  cout << "  NORMAL_01_VARIANCE computes the Normal 01 variance;\n";
+
+  variance = normal_01_variance ( );
+
+  cout << "\n";
+  cout << "  PDF variance = " << variance << "\n";
+
+  sample_num = 1000;
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = normal_01_sample ( seed );
+  }
+
+  variance = r8vec_variance ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num  << "\n";
+  cout << "  Sample variance = " << variance << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_cdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_CDF_TEST tests NORMAL_MS_CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    05 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double cdf;
+  int i;
+  double mu;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_MS_CDF_TEST\n";
+  cout << "  NORMAL_MS_CDF evaluates the Normal MS CDF;\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+  cout << "\n";
+  cout << "       X              CDF\n";
+  cout << "\n";
+
+  for ( i = - 20; i <= +20; i++ )
+  {
+    x = mu + sigma * ( double ) ( i ) / 10.0;
+    cdf = normal_ms_cdf ( x, mu, sigma );
+    cout << "  " << setw(14) << x
+         << "  " << setw(24) << cdf << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_cdf_inv_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_CDF_INV_TEST tests NORMAL_MS_CDF_INV.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    04 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double cdf;
+  int i;
+  double mu;
+  double sigma;
+  double x;
+  double x2;
+
+  cout << "\n";
+  cout << "NORMAL_MS_CDF_INV_TEST\n";
+  cout << "  NORMAL_MS_CDF_INV inverts the Normal MS CDF;\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+
+  cout << "\n";
+  cout << "       X            CDF           CDF_INV\n";
+  cout << "\n";
+
+  for ( i = - 20; i <= +20; i++ )
+  {
+    x = mu + sigma * ( double ) ( i ) / 10.0;
+    cdf = normal_ms_cdf ( x, mu, sigma );
+    x2 = normal_ms_cdf_inv ( cdf, mu, sigma );
+    cout << "  " << setw(14) << x
+         << "  " << setw(14) << cdf
+         << "  " << setw(14) << x2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_mean_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MEAN_TEST tests NORMAL_MS_MEAN.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    04 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double mean;
+  double mu;
+  int sample_num;
+  int seed = 123456789;
+  double sigma;
+  double *x;
+  double xmax;
+  double xmin;
+
+  cout << "\n";
+  cout << "NORMAL_MS_MEAN_TEST\n";
+  cout << "  NORMAL_MS_MEAN computes the Normal MS mean.\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+
+  mean = normal_ms_mean ( mu, sigma );
+
+  cout << "\n";
+  cout << "  PDF mean = " << mean << "\n";
+
+  sample_num = 1000;
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = normal_ms_sample ( mu, sigma, seed );
+  }
+
+  mean = r8vec_mean ( sample_num, x );
+  xmax = r8vec_max ( sample_num, x );
+  xmin = r8vec_min ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample mean =     " << mean << "\n";
+  cout << "  Sample maximum =  " << xmax << "\n";
+  cout << "  Sample minimum =  " << xmin << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_moment_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MOMENT_MS_TEST tests NORMAL_MS_MOMENT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double moment1;
+  double moment2;
+  double mu;
+  double mu_test[4] = { 0.0, 2.0, 10.0, 0.0 };
+  int order;
+  double sigma;
+  double sigma_test[4] = { 1.0, 1.0, 2.0, 2.0 };
+  int test;
+  int test_num = 4;
+ 
+  cout << "\n";
+  cout << "NORMAL_MOMENT_MS_TEST\n";
+  cout << "  NORMAL_MS_MOMENT evaluates the moments of the Normal MS distribution.\n";
+
+  for ( test = 0; test < test_num; test++ )
+  {
+    mu = mu_test[test];
+    sigma = sigma_test[test];
+    cout << "\n";
+    cout << "  Mu = " << mu
+         << "  Sigma = " << sigma << "\n";
+    cout << " Order  Moment\n";
+    cout << "\n";
+    for ( order = 0; order <= 8; order++ )
+    {
+      moment1 = normal_ms_moment ( order, mu, sigma );
+      moment2 = normal_ms_moment_values ( order, mu, sigma );
+      cout << "  " << setw(2) << order
+           << "  " << setw(14) << moment1 
+           << "  " << setw(14) << moment2 << "\n";
+    }
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_moment_central_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_MOMENT_CENTRAL_TEST tests NORMAL_MS_MOMENT_CENTRAL.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double moment1;
+  double moment2;
+  double mu;
+  double mu_test[4] = { 0.0, 2.0, 10.0, 0.0 };
+  int order;
+  double sigma;
+  double sigma_test[4] = { 1.0, 1.0, 2.0, 2.0 };
+  int test;
+  int test_num = 4;
+ 
+  cout << "\n";
+  cout << "NORMAL_MS_MOMENT_CENTRAL_TEST\n";
+  cout << "  NORMAL_MS_MOMENT_CENTRAL evaluates the central moments of the\n";
+  cout << "  Normal MS distribution.\n";
+
+  for ( test = 0; test < test_num; test++ )
+  {
+    mu = mu_test[test];
+    sigma = sigma_test[test];
+    cout << "\n";
+    cout << "  Mu = " << mu
+         << "  Sigma = " << sigma << "\n";
+    cout << " Order  Moment\n";
+    cout << "\n";
+    for ( order = 0; order <= 8; order++ )
+    {
+      moment1 = normal_ms_moment_central ( order, mu, sigma );
+      moment2 = normal_ms_moment_central_values ( order, mu, sigma );
+      cout << "  " << setw(2) << order
+           << "  " << setw(14) << moment1 
+           << "  " << setw(14) << moment2 << "\n";
+    }
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_pdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_PDF_TEST tests NORMAL_MS_PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    04 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double mu;
+  double pdf;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_MS_PDF_TEST\n";
+  cout << "  NORMAL_MS_PDF evaluates the Normal MS PDF;\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+
+  cout << "\n";
+  cout << "       X              PDF\n";
+  cout << "\n";
+
+  for ( i = - 20; i <= +20; i++ )
+  {
+    x = mu + sigma * ( double ) ( i ) / 10.0;
+    pdf = normal_ms_pdf ( mu, sigma, x );
+    cout << "  " << setw(14) << x
+         << "  " << setw(24) << pdf << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_sample_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_SAMPLE_TEST tests NORMAL_MS_SAMPLE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    04 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double mu;
+  int seed;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "NORMAL_MS_SAMPLE_TEST\n";
+  cout << "  NORMAL_MS_SAMPLE returns samples from the Normal MS PDF.\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+
+  cout << "\n";
+
+  seed = 123456789;
+
+  for ( i = 1; i <= 10; i++ )
+  {
+    x = normal_ms_sample ( mu, sigma, seed );
+    cout << "  " << setw(4) << i
+         << "  " << setw(14) << x << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void normal_ms_variance_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    NORMAL_MS_VARIANCE_TEST tests NORMAL_MS_VARIANCE;
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    04 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i;
+  double mu;
+  int sample_num;
+  int seed = 123456789;
+  double sigma;
+  double variance;
+  double *x;
+
+  cout << "\n";
+  cout << "NORMAL_MS_VARIANCE_TEST\n";
+  cout << "  NORMAL_MS_VARIANCE computes the Normal MS variance;\n";
+
+  mu = 100.0;
+  sigma = 15.0;
+
+  cout << "\n";
+  cout << "  Parameter MU = " << mu << "\n";
+  cout << "  Parameteter SIGMA = " << sigma << "\n";
+
+  variance = normal_ms_variance ( mu, sigma );
+
+  cout << "\n";
+  cout << "  PDF variance = " << variance << "\n";
+
+  sample_num = 1000;
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = normal_ms_sample ( mu, sigma, seed );
+  }
+
+  variance = r8vec_variance ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample variance = " << variance << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void r8_choose_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_CHOOSE_TEST tests R8_CHOOSE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    26 July 2014
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double cnk;
+  int k;
+  int n;
+
+  cout << "\n";
+  cout << "R8_CHOOSE_TEST\n";
+  cout << "  R8_CHOOSE evaluates C(N,K).\n";
+  cout << "\n";
+  cout << "         N         K       CNK\n";
+ 
+  for ( n = 0; n <= 5; n++ )
+  {
+    cout << "\n";
+    for ( k = 0; k <= n; k++ )
+    {
+      cnk = r8_choose ( n, k );
+      cout << setw(10) << n << "  "
+           << setw(8) << k << "  "
+           << setw(14) << cnk << "\n";
+    }
+  }
+ 
+  return;
+}
+//****************************************************************************80
+
+void r8_factorial2_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_FACTORIAL2_TEST tests R8_FACTORIAL2.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    08 February 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double f1;
+  double f2;
+  int n;
+  int n_data;
+  streamsize ss;
+//
+//  Save the current precision.
+//
+  ss = cout.precision ( );
+
+  cout << "\n";
+  cout << "R8_FACTORIAL2_TEST\n";
+  cout << "  R8_FACTORIAL2 evaluates the double factorial function.\n";
+  cout << "\n";
+  cout << "    N                Exact                  Computed\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    r8_factorial2_values ( n_data, n, f1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+
+    f2 = r8_factorial2 ( n );
+
+    cout << "  "
+         << setw(4) << n << "  "
+         << setprecision(16) << setw(24) << f1 << "  "
+         << setprecision(16) << setw(24) << f2 << "\n";
+  }
+//
+//  Restore the default precision.
+//
+  cout.precision ( ss );
+
+  return;
+}
+//****************************************************************************80
+
+void r8_mop_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_MOP_TEST tests R8_MOP.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    06 December 2014
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  int i4;
+  int i4_max;
+  int i4_min;
+  double r8;
+  int seed = 123456789;
+  int test;
+
+  cout << "\n";
+  cout << "R8_MOP_TEST\n";
+  cout << "  R8_MOP evaluates (-1.0)^I4 as an R8.\n";
+  cout << "\n";
+  cout << "    I4  R8_MOP(I4)\n";
+  cout << "\n";
+
+  i4_min = -100;
+  i4_max = +100;
+
+  for ( test = 1; test <= 10; test++ )
+  {
+    i4 = i4_uniform_ab ( i4_min, i4_max, seed );
+    r8 = r8_mop ( i4 );
+    cout << "  "
+         << setw(4) << i4 << "  "
+         << setw(4) <<r8 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void r8_uniform_01_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8_UNIFORM_01_TEST tests R8_UNIFORM_01.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    12 September 2005
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+# define N 1000
+
+  int i;
+  double max;
+  double mean;
+  double min;
+  int n;
+  int seed = 123456789;
+  double x[N];
+  double variance;
+
+  cout << "\n";
+  cout << "R8_UNIFORM_01_TEST\n";
+  cout << "  R8_UNIFORM_01 samples a uniform random distribution in [0,1].\n";
+  cout << "  distributed random numbers.\n";
+  cout << "  Using initial random number seed = " << seed << "\n";
+
+  for ( i = 0; i < N; i++ )
+  {
+    x[i] = r8_uniform_01 ( seed );
+  }
+
+  cout << "\n";
+  cout << "  First few values:\n";
+  cout << "\n";
+  for ( i = 0; i < 10; i++ )
+  {
+    cout << "  " << setw(6) << i
+         << "  " << setw(14) << x[i] << "\n";
+  }
+  min = r8vec_min ( N, x );
+  max = r8vec_max ( N, x );
+  mean = r8vec_mean ( N, x );
+  variance = r8vec_variance ( N, x );
+
+  cout << "\n";
+  cout << "  Number of samples was " << N << "\n";
+  cout << "  Minimum value was " << min << "\n";
+  cout << "  Maximum value was " << max << "\n";
+  cout << "  Average value was " << mean << "\n";
+  cout << "  Variance was      " << variance << "\n";
+
+  return;
+# undef N
+}
+//****************************************************************************80
+
+void r8poly_print_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8POLY_PRINT_TEST tests R8POLY_PRINT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    03 January 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double c[6] = { 2.0, -3.4, 56.0, 0.0, 0.78, 9.0 };
+  int m = 5;
+
+  cout << "\n";
+  cout << "R8POLY_PRINT_TEST\n";
+  cout << "  R8POLY_PRINT prints an R8POLY.\n";
+
+  r8poly_print ( m, c, "  The R8POLY:" );
+
+  return;
+}
+//****************************************************************************80
+
+void r8poly_value_horner_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8POLY_VALUE_HORNER_TEST tests R8POLY_VALUE_HORNER.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    02 January 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double c[5] = { 24.0, -50.0, +35.0, -10.0, 1.0 };
+  int i;
+  int m = 4;
+  int n = 16;
+  double p;
+  double *x;
+  double x_hi;
+  double x_lo;
+
+  cout << "\n";
+  cout << "R8POLY_VALUE_HORNER_TEST\n";
+  cout << "  R8POLY_VALUE_HORNER evaluates a polynomial at\n";
+  cout << "  one point, using Horner's method.\n";
+
+  r8poly_print ( m, c, "  The polynomial coefficients:" );
+
+  x_lo = 0.0;
+  x_hi = 5.0;
+  x = r8vec_linspace_new ( n, x_lo, x_hi );
+
+  cout << "\n";
+  cout << "   I    X    P(X)\n";
+  cout << "\n";
+
+  for ( i = 0; i < n; i++ )
+  {
+    p = r8poly_value_horner ( m, c, x[i] );
+    cout << "  " << setw(2) << i
+         << "  " << setw(8) << x[i]
+         << "  " << setw(14) << p << "\n";
+  }
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void r8vec_linspace_new_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_LINSPACE_NEW_TEST tests R8VEC_LINSPACE_NEW.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    03 June 2012
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  int n = 5;
+  double *x;
+
+  cout << "\n";
+  cout << "R8VEC_LINSPACE_NEW_TEST\n";
+  cout << "  For a R8VEC:\n";
+  cout << "  R8VEC_LINSPACE_NEW: evenly spaced points between A and B;\n";
+
+  a = 10.0;
+  b = 20.0;
+
+  x = r8vec_linspace_new ( n, a, b );
+  r8vec_print ( n, x, "  r8vec_linspace ( 5, 10, 20 )" );
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void r8vec_print_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    R8VEC_PRINT_TEST tests R8VEC_PRINT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    31 August 2014
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a[4] = { 123.456, 0.000005, -1.0E+06, 3.14159265 };
+  int n = 4;
+
+  cout << "\n";
+  cout << "TEST1335\n";
+  cout << "  R8VEC_PRINT prints an R8VEC.\n";
+
+  r8vec_print ( n, a, "  The R8VEC:" );
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_cdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_A_CDF_TEST tests TRUNCATED_NORMAL_A_CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double cdf1;
+  double cdf2;
+  double mu;
+  int n_data;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_CDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_A_CDF evaluates\n";
+  cout << "  the lower Truncated Normal Cumulative Density Function.\n";
+  cout << "\n";
+  cout << "        MU       S         A         X        CDF1           CDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_a_cdf_values ( n_data, mu, sigma, a, x, cdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    cdf2 = truncated_normal_a_cdf ( x, mu, sigma, a );
+
+    cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << a
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << cdf1
+         << "  " << setprecision(16) << setw(24) << cdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_cdf_inv_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_CDF_INV_TEST tests TRUNCATED_NORMAL_A_CDF_INV.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double cdf;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+  double x2;
+
+  a = 50.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_CDF_INV_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_A_CDF_INV inverts the CDF of\n";
+  cout << "  the lower Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << ",+oo)\n";
+  cout << "\n";
+  cout << "       X            CDF           CDF_INV\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_a_sample ( mu, sigma, a, seed );
+    cdf = truncated_normal_a_cdf ( x, mu, sigma, a );
+    x2 = truncated_normal_a_cdf_inv ( cdf, mu, sigma, a );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x
+         << "  " << setw(14) << cdf
+         << "  " << setw(14) << x2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_mean_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_MEAN_TEST tests TRUNCATED_NORMAL_A_MEAN.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  int i;
+  double mean;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double *x;
+  double xmax;
+  double xmin;
+
+  a = 50.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_MEAN_TEST\n";
+  cout << "  TRUNCATED_NORMAL_A_MEAN computes the mean\n";
+  cout << "  of the lower Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << ",+oo)\n";
+
+  mean = truncated_normal_a_mean ( mu, sigma, a );
+
+  cout << "\n";
+  cout << "  PDF mean = " << mean << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_a_sample ( mu, sigma, a, seed );
+  }
+
+  mean = r8vec_mean ( sample_num, x );
+  xmax = r8vec_max ( sample_num, x );
+  xmin = r8vec_min ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample mean =     " << mean << "\n";
+  cout << "  Sample maximum =  " << xmax << "\n";
+  cout << "  Sample minimum =  " << xmin << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_moment_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_MOMENT_TEST tests TRUNCATED_NORMAL_A_MOMENT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double a_test[6] = {
+    0.0, -10.0, 10.0, -10.0, 10.0, -10.0 };
+  double moment;
+  double mu;
+  double mu_test[6] = {
+    0.0,  0.0,  0.0,  0.0, 0.0, -5.0 };
+  int order;
+  double sigma;
+  double sigma_test[6] = {
+    1.0,  1.0,  1.0, 2.0, 2.0, 1.0 };
+  int test;
+  int test_num;
+
+  test_num = 6;
+ 
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_MOMENT_TEST\n";
+  cout << "  TRUNCATED_NORMAL_A_MOMENT evaluates the moments\n";
+  cout << "  of the Lower Truncated Normal Distribution.\n";
+
+  for ( test = 0; test < test_num; test++ )
+  {
+    mu = mu_test[test];
+    sigma = sigma_test[test];
+    a = a_test[test];
+    cout << "\n";
+    cout << "  Test = " << test 
+         << ", Mu = " << mu 
+         << ", Sigma = " << sigma 
+         << ", A = " << a << "\n";
+    cout << " Order  Moment\n";
+    cout << "\n";
+    for ( order = 0; order <= 8; order++ )
+    {
+      moment = truncated_normal_a_moment ( order, mu, sigma, a );
+      cout << "  " << setw(2) << order
+           << "  " << setw(14) << moment << "\n";
+    }
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_pdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_A_PDF_TEST tests TRUNCATED_NORMAL_A_PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double mu;
+  int n_data;
+  double pdf1;
+  double pdf2;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_PDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_A_PDF evaluates the PDF of\n";
+  cout << "  the lower Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "        MU       S         A         X        PDF1        PDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_a_pdf_values ( n_data, mu, sigma, a, x, pdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    pdf2 = truncated_normal_a_pdf ( x, mu, sigma, a );
+
+   cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << a
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << pdf1
+         << "  " << setprecision(16)<< setw(24) << pdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_sample_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_SAMPLE_TEST tests TRUNCATED_NORMAL_A_SAMPLE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+
+  a = 50.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_SAMPLE_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_A_SAMPLE samples\n";
+  cout << "  the lower Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << ",+oo)\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_a_sample ( mu, sigma, a, seed );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_a_variance_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_A_VARIANCE_TEST tests TRUNCATED_NORMAL_A_VARIANCE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  int i;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double variance;
+  double *x;
+
+  a = 50.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_A_VARIANCE_TEST\n";
+  cout << "  TRUNCATED_NORMAL_A_VARIANCE computes the variance\n";
+  cout << "  of the lower Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << ",+oo)\n";
+
+  variance = truncated_normal_a_variance ( mu, sigma, a );
+
+  cout << "\n";
+  cout << "  PDF variance = " << variance << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_a_sample ( mu, sigma, a, seed );
+  }
+
+  variance = r8vec_variance ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample variance = " << variance << "\n";
+ 
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_cdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_AB_CDF_TEST tests TRUNCATED_NORMAL_AB_CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    13 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  double cdf1;
+  double cdf2;
+  double mu;
+  int n_data;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_CDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_AB_CDF evaluates\n";
+  cout << "  the Truncated Normal Cumulative Density Function.\n";
+  cout << "\n";
+  cout << "        MU       S         A         B         X        CDF1           CDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_ab_cdf_values ( n_data, mu, sigma, a, b, x, cdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    cdf2 = truncated_normal_ab_cdf ( x, mu, sigma, a, b );
+
+    cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << a
+         << "  " << setw(8) << b
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << cdf1
+         << "  " << setprecision(16) << setw(24) << cdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_cdf_inv_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_CDF_INV_TEST tests TRUNCATED_NORMAL_AB_CDF_INV.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  double cdf;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+  double x2;
+
+  a = 50.0;
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_CDF_INV_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_AB_CDF_INV inverts the CDF of\n";
+  cout << "  the Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << "," << b << "]\n";
+  cout << "\n";
+  cout << "       X            CDF           CDF_INV\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_ab_sample ( mu, sigma, a, b, seed );
+    cdf = truncated_normal_ab_cdf ( x, mu, sigma, a, b );
+    x2 = truncated_normal_ab_cdf_inv ( cdf, mu, sigma, a, b );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x
+         << "  " << setw(14) << cdf
+         << "  " << setw(14) << x2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_mean_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_MEAN_TEST tests TRUNCATED_NORMAL_AB_MEAN.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  int i;
+  double mean;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double *x;
+  double xmax;
+  double xmin;
+
+  a = 50.0;
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_MEAN_TEST\n";
+  cout << "  TRUNCATED_NORMAL_AB_MEAN computes the mean\n";
+  cout << "  of the Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << "," << b << "]\n";
+
+  mean = truncated_normal_ab_mean ( mu, sigma, a, b );
+
+  cout << "\n";
+  cout << "  PDF mean = " << mean << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_ab_sample ( mu, sigma, a, b, seed );
+  }
+
+  mean = r8vec_mean ( sample_num, x );
+  xmax = r8vec_max ( sample_num, x );
+  xmin = r8vec_min ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample mean =     " << mean << "\n";
+  cout << "  Sample maximum =  " << xmax << "\n";
+  cout << "  Sample minimum =  " << xmin << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_moment_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_MOMENT_TEST tests TRUNCATED_NORMAL_AB_MOMENT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double a_test[9] = {
+    -1.0, 0.0, -1.0, -1.0,  0.0, 0.5, -2.0, -4.0, 4.0  };
+  double b;
+  double b_test[9] = {
+    1.0, 1.0,  0.0,  1.0,  2.0, 2.0,  2.0,  4.0, 7.0 };
+  double moment;
+  double mu;
+  double mu_test[9] = {
+    0.0, 0.0,  0.0,  0.0,  1.0, 0.0,  0.0,  0.0, 5.0 };
+  int order;
+  double sigma;
+  double sigma_test[9] = {
+    1.0, 1.0,  1.0,  2.0,  1.0, 1.0,  1.0,  1.0, 0.5 };
+  int test;
+  int test_num;
+
+  test_num = 9;
+ 
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_MOMENT_TEST\n";
+  cout << "  TRUNCATED_NORMAL_AB_MOMENT evaluates the moments\n";
+  cout << "  of the Truncated Normal PDF:\n";
+
+  for ( test = 0; test < test_num; test++ )
+  {
+    mu = mu_test[test];
+    sigma = sigma_test[test];
+    a = a_test[test];
+    b = b_test[test];
+    cout << "\n";
+    cout << "  Test = " << test 
+         << ", Mu = " << mu 
+         << ", Sigma = " << sigma 
+         << ", A = " << a
+         << ", B = " << b << "\n";
+    cout << " Order  Moment\n";
+    cout << "\n";
+    for ( order = 0; order <= 8; order++ )
+    {
+      moment = truncated_normal_ab_moment ( order, mu, sigma, a, b );
+      cout << "  " << setw(2) << order
+           << "  " << setw(14) << moment << "\n";
+    }
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_pdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_AB_PDF_TEST tests TRUNCATED_NORMAL_AB_PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    13 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  double mu;
+  int n_data;
+  double pdf1;
+  double pdf2;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_PDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_AB_PDF evaluates\n";
+  cout << "  the Truncated Normal Probability Density Function.\n";
+  cout << "\n";
+  cout << "        MU       S         A         B         X        PDF1        PDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_ab_pdf_values ( n_data, mu, sigma, a, b, x, pdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    pdf2 = truncated_normal_ab_pdf ( x, mu, sigma, a, b );
+
+   cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << a
+         << "  " << setw(8) << b
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << pdf1
+         << "  " << setprecision(16)<< setw(24) << pdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_sample_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_SAMPLE_TEST tests TRUNCATED_NORMAL_AB_SAMPLE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+
+  a = 50.0;
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_SAMPLE_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_AB_SAMPLE samples\n";
+  cout << "  the Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << "," << b << "]\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_ab_sample ( mu, sigma, a, b, seed );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_ab_variance_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_AB_VARIANCE_TEST tests TRUNCATED_NORMAL_AB_VARIANCE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double a;
+  double b;
+  int i;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double variance;
+  double *x;
+
+  a = 50.0;
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_AB_VARIANCE_TEST\n";
+  cout << "  TRUNCATED_NORMAL_AB_VARIANCE computes the variance\n";
+  cout << "  of the Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval [" << a << "," << b << "]\n";
+
+  variance = truncated_normal_ab_variance ( mu, sigma, a, b );
+
+  cout << "\n";
+  cout << "  PDF variance = " << variance << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_ab_sample ( mu, sigma, a, b, seed );
+  }
+
+  variance = r8vec_variance ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample variance = " << variance << "\n";
+ 
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_cdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_B_CDF_TEST tests TRUNCATED_NORMAL_B_CDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  double cdf1;
+  double cdf2;
+  double mu;
+  int n_data;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_CDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_B_CDF evaluates\n";
+  cout << "  the upper Truncated Normal Cumulative Density Function.\n";
+  cout << "\n";
+  cout << "        MU       S         B         X        CDF1           CDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_b_cdf_values ( n_data, mu, sigma, b, x, cdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    cdf2 = truncated_normal_b_cdf ( x, mu, sigma, b );
+
+    cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << b
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << cdf1
+         << "  " << setprecision(16) << setw(24) << cdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_cdf_inv_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_CDF_INV_TEST tests TRUNCATED_NORMAL_B_CDF_INV.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  double cdf;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+  double x2;
+
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_CDF_INV_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_B_CDF_INV inverts the CDF of\n";
+  cout << "  the upper Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval (-oo," << b << "]\n";
+  cout << "\n";
+  cout << "       X            CDF           CDF_INV\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_b_sample ( mu, sigma, b, seed );
+    cdf = truncated_normal_b_cdf ( x, mu, sigma, b );
+    x2 = truncated_normal_b_cdf_inv ( cdf, mu, sigma, b );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x
+         << "  " << setw(14) << cdf
+         << "  " << setw(14) << x2 << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_mean_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_MEAN_TEST tests TRUNCATED_NORMAL_B_MEAN.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  int i;
+  double mean;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double *x;
+  double xmax;
+  double xmin;
+
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_MEAN_TEST\n";
+  cout << "  TRUNCATED_NORMAL_B_MEAN computes the mean\n";
+  cout << "  of the upper Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval (-oo," << b << "]\n";
+
+  mean = truncated_normal_b_mean ( mu, sigma, b );
+
+  cout << "\n";
+  cout << "  PDF mean = " << mean << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_b_sample ( mu, sigma, b, seed );
+  }
+
+  mean = r8vec_mean ( sample_num, x );
+  xmax = r8vec_max ( sample_num, x );
+  xmin = r8vec_min ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample mean =     " << mean << "\n";
+  cout << "  Sample maximum =  " << xmax << "\n";
+  cout << "  Sample minimum =  " << xmin << "\n";
+
+  delete [] x;
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_moment_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_MOMENT_TEST tests TRUNCATED_NORMAL_B_MOMENT.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    03 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  double b_test[6] = {
+    0.0, 10.0, -10.0, 10.0, -10.0, 10.0 };
+  double moment;
+  double mu;
+  double mu_test[6] = {
+    0.0,  0.0,  0.0,  0.0, 0.0, 5.0 };
+  int order;
+  double sigma;
+  double sigma_test[6] = {
+    1.0,  1.0,  1.0, 2.0, 2.0, 1.0 };
+  int test;
+  int test_num;
+
+  test_num = 6;
+ 
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_MOMENT_TEST\n";
+  cout << "  For the Upper Truncated Normal PDF:\n";
+  cout << "  TRUNCATED_NORMAL_B_MOMENT evaluates the moments.\n";
+
+  for ( test = 0; test < test_num; test++ )
+  {
+    mu = mu_test[test];
+    sigma = sigma_test[test];
+    b = b_test[test];
+    cout << "\n";
+    cout << "  Test = " << test 
+         << ", Mu = " << mu 
+         << ", Sigma = " << sigma 
+         << ", B = " << b << "\n";
+    cout << " Order  Moment\n";
+    cout << "\n";
+    for ( order = 0; order <= 8; order++ )
+    {
+      moment = truncated_normal_b_moment ( order, mu, sigma, b );
+      cout << "  " << setw(2) << order
+           << "  " << setw(14) << moment << "\n";
+    }
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_pdf_test ( )
+
+//****************************************************************************80
+//
+//  Purpose: 
+//
+//    TRUNCATED_NORMAL_B_PDF_TEST tests TRUNCATED_NORMAL_B_PDF.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license. 
+//
+//  Modified:
+//
+//    14 September 2013
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  double mu;
+  int n_data;
+  double pdf1;
+  double pdf2;
+  double sigma;
+  double x;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_PDF_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_B_PDF evaluates\n";
+  cout << "  the upper Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "        MU       S         B         X        PDF1        PDF2\n";
+  cout << "\n";
+
+  n_data = 0;
+
+  for ( ; ; )
+  {
+    truncated_normal_b_pdf_values ( n_data, mu, sigma, b, x, pdf1 );
+
+    if ( n_data == 0 )
+    {
+      break;
+    }
+    pdf2 = truncated_normal_b_pdf ( x, mu, sigma, b );
+
+   cout << "  " << setw(8) << mu
+         << "  " << setw(8) << sigma
+         << "  " << setw(8) << b
+         << "  " << setw(8) << x
+         << "  " << setprecision(16) << setw(24) << pdf1
+         << "  " << setprecision(16)<< setw(24) << pdf2 << "\n";
+  }
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_sample_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_SAMPLE_TEST tests TRUNCATED_NORMAL_B_SAMPLE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  int i;
+  double mu;
+  int sample_num = 10;
+  int seed;
+  double sigma;
+  double x;
+
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_SAMPLE_TEST:\n";
+  cout << "  TRUNCATED_NORMAL_B_SAMPLE samples\n";
+  cout << "  the upper Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval (-oo," << b << "]\n";
+  cout << "\n";
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x = truncated_normal_b_sample ( mu, sigma, b, seed );
+    cout << "  " << setw(2) << i
+         << "  " << setw(14) << x << "\n";
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void truncated_normal_b_variance_test ( )
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TRUNCATED_NORMAL_B_VARIANCE_TEST tests TRUNCATED_NORMAL_B_VARIANCE.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    07 March 2015
+//
+//  Author:
+//
+//    John Burkardt
+//
+{
+  double b;
+  int i;
+  double mu;
+  int sample_num = 1000;
+  int seed;
+  double sigma;
+  double variance;
+  double *x;
+
+  b = 150.0;
+  mu = 100.0;
+  sigma = 25.0;
+  seed = 123456789;
+
+  cout << "\n";
+  cout << "TRUNCATED_NORMAL_B_VARIANCE_TEST\n";
+  cout << "  TRUNCATED_NORMAL_B_VARIANCE computes the variance\n";
+  cout << "  of the upper Truncated Normal Distribution.\n";
+  cout << "\n";
+  cout << "  The parent normal distribution has\n";
+  cout << "    mean =               " << mu << "\n";
+  cout << "    standard deviation = " << sigma << "\n";
+  cout << "  The parent distribution is truncated to\n";
+  cout << "  the interval (-oo," << b << "]\n";
+
+  variance = truncated_normal_b_variance ( mu, sigma, b );
+
+  cout << "\n";
+  cout << "  PDF variance = " << variance << "\n";
+
+  x = new double[sample_num];
+
+  for ( i = 0; i < sample_num; i++ )
+  {
+    x[i] = truncated_normal_b_sample ( mu, sigma, b, seed );
+  }
+
+  variance = r8vec_variance ( sample_num, x );
+
+  cout << "\n";
+  cout << "  Sample size =     " << sample_num << "\n";
+  cout << "  Sample variance = " << variance << "\n";
+ 
+  delete [] x;
+
+  return;
+}