diff -r 877263efaacc doc/interpreter/arith.txi
--- a/doc/interpreter/arith.txi	Wed Jun 13 14:10:45 2012 -0700
+++ b/doc/interpreter/arith.txi	Thu Jun 14 17:00:00 2012 +0200
@@ -271,6 +271,8 @@
 
 @DOCSTRING(erfinv)
 
+@DOCSTRING(erfcinv)
+
 @DOCSTRING(gamma)
 
 @DOCSTRING(gammainc)
diff -r 877263efaacc liboctave/lo-specfun.cc
--- a/liboctave/lo-specfun.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/liboctave/lo-specfun.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -3221,6 +3221,75 @@
   return do_erfinv (x, false);
 }
 
+static double do_erfcinv (double x, bool refine)
+{
+  // Coefficients of rational approximation.
+  static const double a[] =
+    { -2.806989788730439e+01,  1.562324844726888e+02,
+      -1.951109208597547e+02,  9.783370457507161e+01,
+      -2.168328665628878e+01,  1.772453852905383e+00 };
+  static const double b[] =
+    { -5.447609879822406e+01,  1.615858368580409e+02,
+      -1.556989798598866e+02,  6.680131188771972e+01,
+      -1.328068155288572e+01 };
+  static const double c[] =
+    { -5.504751339936943e-03, -2.279687217114118e-01,
+      -1.697592457770869e+00, -1.802933168781950e+00,
+       3.093354679843505e+00,  2.077595676404383e+00 };
+  static const double d[] =
+    {  7.784695709041462e-03,  3.224671290700398e-01,
+       2.445134137142996e+00,  3.754408661907416e+00 };
+
+  static const double spi2 =  8.862269254527579e-01; // sqrt(pi)/2.
+  static const double pbreak = 0.95150;
+  double y;
+
+  // Select case.
+  if (x <= 1+pbreak && x >= 1-pbreak)
+    {
+      // Middle region.
+      const double q = 0.5*(1-x), r = q*q;
+      const double yn = (((((a[0]*r + a[1])*r + a[2])*r + a[3])*r + a[4])*r + a[5])*q;
+      const double yd = ((((b[0]*r + b[1])*r + b[2])*r + b[3])*r + b[4])*r + 1.0;
+      y = yn / yd;
+    }
+  else if (x < 2.0 && x > 0.0)
+    {
+      // Tail region.
+      const double q = x < 1 ? sqrt (-2*log (0.5*x)) : sqrt (-2*log (0.5*(2-x)));
+      const double yn = ((((c[0]*q + c[1])*q + c[2])*q + c[3])*q + c[4])*q + c[5];
+      const double yd = (((d[0]*q + d[1])*q + d[2])*q + d[3])*q + 1.0;
+      y = yn / yd;
+      if (x < 1-pbreak)
+        y *= -1;
+    }
+  else if (x == 0.0)
+    return octave_Inf;
+  else if (x == 2.0)
+    return -octave_Inf;
+  else
+    return octave_NaN;
+
+  if (refine)
+    {
+      // One iteration of Halley's method gives full precision.
+      double u = (erf(y) + x - 1) * spi2 * exp (y*y);
+      y -= u / (1 + y*u);
+    }
+
+  return y;
+}
+
+double erfcinv (double x)
+{
+  return do_erfcinv (x, true);
+}
+
+float erfcinv (float x)
+{
+  return do_erfcinv (x, false);
+}
+
 // Implementation based on the Fortran code by W.J.Cody
 // see http://www.netlib.org/specfun/erf.
 // Templatized and simplified workflow.
diff -r 877263efaacc liboctave/lo-specfun.h
--- a/liboctave/lo-specfun.h	Wed Jun 13 14:10:45 2012 -0700
+++ b/liboctave/lo-specfun.h	Thu Jun 14 17:00:00 2012 +0200
@@ -593,6 +593,9 @@
 extern OCTAVE_API double erfinv (double x);
 extern OCTAVE_API float erfinv (float x);
 
+extern OCTAVE_API double erfcinv (double x);
+extern OCTAVE_API float erfcinv (float x);
+
 extern OCTAVE_API double erfcx (double x);
 extern OCTAVE_API float erfcx (float x);
 
diff -r 877263efaacc scripts/statistics/distributions/stdnormal_inv.m
--- a/scripts/statistics/distributions/stdnormal_inv.m	Wed Jun 13 14:10:45 2012 -0700
+++ b/scripts/statistics/distributions/stdnormal_inv.m	Thu Jun 14 17:00:00 2012 +0200
@@ -37,7 +37,7 @@
     error ("stdnormal_inv: X must not be complex");
   endif
 
-  inv = sqrt (2) * erfinv (2 * x - 1);
+  inv = - sqrt (2) * erfcinv (2 * x);
 
 endfunction
 
diff -r 877263efaacc src/mappers.cc
--- a/src/mappers.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/mappers.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -547,7 +547,7 @@
 @end example\n\
 \n\
 @end ifnottex\n\
-@seealso{erfc, erfcx, erfinv}\n\
+@seealso{erfc, erfcx, erfinv, erfcinv}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -596,7 +596,7 @@
 @example\n\
 erf (@var{y}) == @var{x}\n\
 @end example\n\
-@seealso{erf, erfc, erfcx}\n\
+@seealso{erf, erfc, erfcinv, erfcx}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -626,6 +626,26 @@
 %!error erfinv (1, 2)
 */
 
+DEFUN (erfcinv, args, ,
+    "-*- texinfo -*-\n\
+@deftypefn {Mapping Function} {} erfcinv (@var{x})\n\
+Compute the inverse complementary error function, i.e., @var{y} such that\n\
+\n\
+@example\n\
+erfc (@var{y}) == @var{x}\n\
+@end example\n\
+@seealso{erfinv, erf, erfc, erfcx}\n\
+@end deftypefn")
+{
+  octave_value retval;
+  if (args.length () == 1)
+    retval = args(0).erfcinv ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
 DEFUN (erfc, args, ,
     "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} erfc (@var{z})\n\
@@ -636,7 +656,7 @@
 @ifnottex\n\
 @w{@code{1 - erf (@var{z})}}.\n\
 @end ifnottex\n\
-@seealso{erfcx, erf, erfinv}\n\
+@seealso{erfcx, erf, erfinv, erfcinv}\n\
 @end deftypefn")
 {
   octave_value retval;
diff -r 877263efaacc src/ov-base.cc
--- a/src/ov-base.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-base.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -1191,6 +1191,7 @@
       "cosh",
       "erf",
       "erfinv",
+      "erfcinv",
       "erfc",
       "exp",
       "expm1",
diff -r 877263efaacc src/ov-base.h
--- a/src/ov-base.h	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-base.h	Thu Jun 14 17:00:00 2012 +0200
@@ -688,6 +688,7 @@
       umap_cosh,
       umap_erf,
       umap_erfinv,
+      umap_erfcinv,
       umap_erfc,
       umap_erfcx,
       umap_exp,
diff -r 877263efaacc src/ov-float.cc
--- a/src/ov-float.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-float.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -291,6 +291,7 @@
       SCALAR_MAPPER (atanh, rc_atanh);
       SCALAR_MAPPER (erf, ::erff);
       SCALAR_MAPPER (erfinv, ::erfinv);
+      SCALAR_MAPPER (erfcinv, ::erfcinv);
       SCALAR_MAPPER (erfc, ::erfcf);
       SCALAR_MAPPER (erfcx, ::erfcx);
       SCALAR_MAPPER (gamma, xgamma);
diff -r 877263efaacc src/ov-flt-re-mat.cc
--- a/src/ov-flt-re-mat.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-flt-re-mat.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -784,6 +784,7 @@
       RC_ARRAY_MAPPER (atanh, FloatComplex, rc_atanh);
       ARRAY_MAPPER (erf, float, ::erff);
       ARRAY_MAPPER (erfinv, float, ::erfinv);
+      ARRAY_MAPPER (erfcinv, float, ::erfcinv);
       ARRAY_MAPPER (erfc, float, ::erfcf);
       ARRAY_MAPPER (erfcx, float, ::erfcx);
       ARRAY_MAPPER (gamma, float, xgamma);
diff -r 877263efaacc src/ov-re-mat.cc
--- a/src/ov-re-mat.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-re-mat.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -907,6 +907,7 @@
       RC_ARRAY_MAPPER (atanh, Complex, rc_atanh);
       ARRAY_MAPPER (erf, double, ::erf);
       ARRAY_MAPPER (erfinv, double, ::erfinv);
+      ARRAY_MAPPER (erfcinv, double, ::erfcinv);
       ARRAY_MAPPER (erfc, double, ::erfc);
       ARRAY_MAPPER (erfcx, double, ::erfcx);
       ARRAY_MAPPER (gamma, double, xgamma);
diff -r 877263efaacc src/ov-re-sparse.cc
--- a/src/ov-re-sparse.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-re-sparse.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -910,6 +910,7 @@
       ARRAY_MAPPER (atanh, Complex, rc_atanh);
       ARRAY_MAPPER (erf, double, ::erf);
       ARRAY_MAPPER (erfinv, double, ::erfinv);
+      ARRAY_MAPPER (erfcinv, double, ::erfcinv);
       ARRAY_MAPPER (erfc, double, ::erfc);
       ARRAY_MAPPER (gamma, double, xgamma);
       ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
diff -r 877263efaacc src/ov-scalar.cc
--- a/src/ov-scalar.cc	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov-scalar.cc	Thu Jun 14 17:00:00 2012 +0200
@@ -307,6 +307,7 @@
       SCALAR_MAPPER (atanh, rc_atanh);
       SCALAR_MAPPER (erf, ::erf);
       SCALAR_MAPPER (erfinv, ::erfinv);
+      SCALAR_MAPPER (erfcinv, ::erfcinv);
       SCALAR_MAPPER (erfc, ::erfc);
       SCALAR_MAPPER (erfcx, ::erfcx);
       SCALAR_MAPPER (gamma, xgamma);
diff -r 877263efaacc src/ov.h
--- a/src/ov.h	Wed Jun 13 14:10:45 2012 -0700
+++ b/src/ov.h	Thu Jun 14 17:00:00 2012 +0200
@@ -1120,6 +1120,7 @@
   MAPPER_FORWARD (cosh)
   MAPPER_FORWARD (erf)
   MAPPER_FORWARD (erfinv)
+  MAPPER_FORWARD (erfcinv)
   MAPPER_FORWARD (erfc)
   MAPPER_FORWARD (erfcx)
   MAPPER_FORWARD (exp)
