Mercurial > octave
diff libinterp/corefcn/mappers.cc @ 15696:2fac72a256ce
Add complex erf,erfc,erfcx,erfi,dawson routines from Faddeeva package.
* libinterp/corefcn/mappers.cc: Add erfi and dawson mapper functions,
and add complex-argument test cases for erf, erfc, erfcx, erfi, and
dawson.
* libinterp/octave-value/ov-base.cc, libinterp/octave-value/ov-base.h:
Add erfi and dawson mapper functions.
* libinterp/octave-value/ov-complex.cc, libinterp/octave-value/ov-cx-mat.cc,
libinterp/octave-value/ov-cx-sparse.cc, libinterp/octave-value/ov-float.cc,
libinterp/octave-value/ov-flt-complex.cc,
libinterp/octave-value/ov-flt-cx-mat.cc,
libinterp/octave-value/ov-flt-re-mat.cc,
libinterp/octave-value/ov-re-mat.c,
libinterp/octave-value/ov-re-sparse.cc,
libinterp/octave-value/ov-scalar.cc,
libinterp/octave-value/ov.h:
Support erf, erfc, erfcx, erfi, and dawson mapper functions for
real and complex matrices and scalars.
* liboctave/cruft/Faddeeva/Faddeeva.cc, liboctave/cruft/Faddeeva/Faddeeva.hh:
liboctave/cruft/Faddeeva/module.mk, liboctave/cruft/Makefile.am:
Add Faddeeva package (from http://ab-initio.mit.edu/Faddeeva) to
libcruft, to provide the various complex-argument error functions.
* liboctave/numeric/lo-specfun.cc, liboctave/numeric/lo-specfun.h:
Add complex-argument erf, erfc, erfcx, erfi, and dawson functions
to liboctave API. Delete previous real-argument erfcx implementation
in favor of Faddeeva::erfcx (which seems to be slightly faster
in gcc/x86-64 benchmarks, with similar accuracy).
* doc/interpreter/arith.txi: Include erfi and dawson documentation.
author | Steven G. Johnson <stevenj@alum.mit.edu> |
---|---|
date | Tue, 27 Nov 2012 23:39:54 -0500 |
parents | 96b7343b8a41 |
children | 7cfb186592de |
line wrap: on
line diff
--- a/libinterp/corefcn/mappers.cc Tue Nov 27 16:38:13 2012 -0800 +++ b/libinterp/corefcn/mappers.cc Tue Nov 27 23:39:54 2012 -0500 @@ -547,7 +547,7 @@ @end example\n\ \n\ @end ifnottex\n\ -@seealso{erfc, erfcx, erfinv, erfcinv}\n\ +@seealso{erfc, erfcx, erfi, dawson, erfinv, erfcinv}\n\ @end deftypefn") { octave_value retval; @@ -584,6 +584,13 @@ %! assert (erfc (x), 1-v, 1.e-6); %! assert (erfinv (v), x, 1.e-6); +%!test +%! x = [1+2i,-1+2i,1e-6+2e-6i,0+2i]; +%! v = [-0.53664356577857-5.04914370344703i, 0.536643565778565-5.04914370344703i, 0.112837916709965e-5+0.225675833419178e-5i, 18.5648024145755526i]; +%! assert (erf (x), v, -1.e-10); +%! assert (erf (-x), -v, -1.e-10); +%! assert (erfc (x), 1-v, -1.e-10); + %!error erf () %!error erf (1, 2) */ @@ -596,7 +603,7 @@ @example\n\ erf (@var{y}) == @var{x}\n\ @end example\n\ -@seealso{erf, erfc, erfcx, erfcinv}\n\ +@seealso{erf, erfc, erfcx, erfi, dawson, erfcinv}\n\ @end deftypefn") { octave_value retval; @@ -634,7 +641,7 @@ @example\n\ erfc (@var{y}) == @var{x}\n\ @end example\n\ -@seealso{erfc, erf, erfcx, erfinv}\n\ +@seealso{erfc, erf, erfcx, erfi, dawson, erfinv}\n\ @end deftypefn") { octave_value retval; @@ -674,7 +681,7 @@ @ifnottex\n\ @w{@code{1 - erf (@var{z})}}.\n\ @end ifnottex\n\ -@seealso{erfcinv, erfcx, erf, erfinv}\n\ +@seealso{erfcinv, erfcx, erfi, dawson, erf, erfinv}\n\ @end deftypefn") { octave_value retval; @@ -707,11 +714,11 @@ @ifnottex\n\ \n\ @example\n\ -exp (z^2) * erfc (x)\n\ +exp (z^2) * erfc (z)\n\ @end example\n\ \n\ @end ifnottex\n\ -@seealso{erfc, erf, erfinv, erfcinv}\n\ +@seealso{erfc, erf, erfi, dawson, erfinv, erfcinv}\n\ @end deftypefn") { octave_value retval; @@ -724,12 +731,98 @@ } /* -## FIXME: Need a test for erfcx + +%!test +%! x = [1+2i,-1+2i,1e-6+2e-6i,0+2i]; +%! assert (erfcx (x), exp (x.^2) .* erfc(x), -1.e-10); + +%!test +%! x = [100, 100+20i]; +%! v = [0.0056416137829894329, 0.0054246791754558-0.00108483153786434i]; +%! assert (erfcx (x), v, -1.e-10); %!error erfcx () %!error erfcx (1, 2) */ +DEFUN (erfi, args, , + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} erfi (@var{z})\n\ +Compute the imaginary error function,\n\ +@tex\n\ +$$\n\ + -i {\\rm erf} (iz) \n\ +$$\n\ +@end tex\n\ +@ifnottex\n\ +\n\ +@example\n\ +-i * erf (i*z)\n\ +@end example\n\ +\n\ +@end ifnottex\n\ +@seealso{erfc, erf, erfcx, dawson, erfinv, erfcinv}\n\ +@end deftypefn") +{ + octave_value retval; + if (args.length () == 1) + retval = args(0).erfi (); + else + print_usage (); + + return retval; +} + +/* + +%!test +%! x = [-0.1, 0.1, 1, 1+2i,-1+2i,1e-6+2e-6i,0+2i]; +%! assert (erfi (x), -i * erf(i*x), -1.e-10); + +%!error erfi () +%!error erfi (1, 2) +*/ + +DEFUN (dawson, args, , + "-*- texinfo -*-\n\ +@deftypefn {Mapping Function} {} dawson (@var{z})\n\ +Compute the Dawson (scaled imaginary error) function,\n\ +@tex\n\ +$$\n\ + {\\sqrt{\\pi} \\over 2} e^{-z^2} {\\rm erfi} (z) \\equiv -i {\\sqrt{\\pi} \\over 2} e^{-z^2} {\\rm erf} (iz)\n\ +$$\n\ +@end tex\n\ +@ifnottex\n\ +\n\ +@example\n\ +(sqrt (pi) / 2) * exp (-z^2) * erfi (z)\n\ +@end example\n\ +\n\ +@end ifnottex\n\ +@seealso{erfc, erf, erfcx, erfi, erfinv, erfcinv}\n\ +@end deftypefn") +{ + octave_value retval; + if (args.length () == 1) + retval = args(0).dawson (); + else + print_usage (); + + return retval; +} + +/* + +%!test +%! x = [0.1, 1, 1+2i,-1+2i,1e-4+2e-4i,0+2i]; +%! v = [0.099335992397852861, 0.53807950691, -13.38892731648-11.828715104i, 13.38892731648-11.828715104i, 0.0001000000073333+0.000200000001333i, 48.160012114291i]; +%! assert (dawson (x), v, -1.e-10); +%! assert (dawson (-x), -v, -1.e-10); + +%!error dawson () +%!error dawson (1, 2) +*/ + DEFUN (exp, args, , "-*- texinfo -*-\n\ @deftypefn {Mapping Function} {} exp (@var{x})\n\