Interval arithmetic for DawsonF (or other special functions)

I am currently trying to estimate a complicated expression involving DawsonF using interval arithmetic. The interval arithmetic is partially supported by Mathematica (most of the elementary functions are defined for Interval[{...}] arguments) but the DawsonF function doesn't seem to be a part of that implementation (along with other special functions such as Hypergeometric1F1, which could be used instead of the DawsonF).

1. Is there any way to evaluate DawsonF on intervals using some built in Mathematica functions?

2. If not, are there any algorithms for computing DawsonF on intervals, which can be implemented in Mathematica? If so, can you please post a reference? The only paper on that topic, that I am aware of, is [1] but it looks dated (1992) and the algorithm presented there seems complicated (there is a lot of special cases).

I am interested in evaluating DawsonF on all subintervals of the real axis.

• The FunctionRange only works for the whole real line (or the complex plane) and even then FunctionRange[DawsonF[x], x, y, Reals] returns an inexact result -0.541044 <= y <= 0.541044.
– pwl
Commented Jan 30, 2016 at 8:59

intDawson[i_Interval] := Module[{peak, xpeak},
{peak, xpeak} = {NMaxValue[DawsonF[x], x], NArgMax[DawsonF[x], x]};
Interval[
If[IntervalMemberQ[i, xpeak], {#[[1]], peak}, #] &@
If[IntervalMemberQ[i, -xpeak], {-peak, #[[2]]}, #] &@
Sort[DawsonF @@ i // N]]
]

intDawson[Interval[{-10, 10}]]
(* Interval[{-0.541044, 0.541044}] *)

intDawson[Interval[{0, 10}]]
(* Interval[{-2.22507*10^-308, 0.541044}] *)
• In a sense this works but I need a guarantee that $x\in I$ implies $f(x)\in f(I)$. For that one has to prove rigorous error bounds for each step that involves a form of numerical approximation (like NMaxValue or Dawson[N[...]]). If you take a look at the paper I referenced the author does exactly that. Now that I think about it I am not even sure if the rigorous relation above holds for the interval arithmetic already implemented in Mathematica. It seems to hold but the code is closed source and they don't reference any papers or algorithms about it.
– pwl
Commented Feb 1, 2016 at 16:09

You can make use of my IntervalRange function for this purpose, reproduced below:

(* message *)
IntervalRange::nmet = "Unable to find the range with the available methods.";

(* main function *)
IntervalRange[f_, i_Interval] := With[
{reg = Catch[iRange[f, FromInterval[i, x], x], "FRFailure"]},
reg /; reg =!= $Failed ] (* find range using FunctionRange *) iRange[f_, reg_, x_] := Module[{prec = Precision[reg], rng}, rng = Quiet[ Check[ FunctionRange[{f[x], SetPrecision[reg, prec+10]}, x, y], Message[RangeInterval::nmet]; Throw[$Failed, "FRFailure"],

FunctionRange::nmet
],
FunctionRange::nmet
];
ToInterval[N[rng, prec], y]
]
iRange[f_, reg_Or, x_] := IntervalUnion @@ (iRange[f, #, x]& /@ reg)

(* ToInterval helper function *)
bounds[inequality_, x_] := First @ RegionBounds[ImplicitRegion[inequality, x]]
ToInterval[inequality_, x_] := With[{rng = bounds[inequality, x]},
SystemPrivateHoldSetValid[Interval[rng]]
]
t:ToInterval[_Or, _] := IntervalUnion @@ Thread[Unevaluated @ t, Or]

(* FromInterval helper function *)
FromInterval[Interval[a___],x_]:=Less[#1,x,#2]& @@@ Unevaluated[Or[a]]

Dr.belarisarius' examples:

IntervalRange[DawsonF, Interval[{-10, 10}]]
% //N

Interval[{DawsonF[ Root[{-(1/2) + DawsonF[#1] #1 &, -0.924138873004591767012823271504}]], DawsonF[Root[{-(1/2) + DawsonF[#1] #1 &, 0.924138873004591767012823271504}]]}]

Interval[{-0.541044, 0.541044}]

IntervalRange[DawsonF, Interval[{0, 10}]]
% //N

Interval[{0, DawsonF[Root[{-(1/2) + DawsonF[#1] #1 &, 0.924138873004591767012823271504}]]}]

Interval[{-2.22507*10^-308, 0.541044}]

If one is willing to mess with built-in symbols, it is possible to add support for Interval objects to DawsonF:

Unprotect[DawsonF];
DawsonF[i_Interval] /; !TrueQ@$$Interval := Block[{$$Interval = True},
IntervalRange[DawsonF, i]
]
Protect[DawsonF];

Then:

DawsonF[Interval[{-10,10}]]
DawsonF[Interval[{0, 10}]]
DawsonF[Interval[{-2, -1}, {1, 2}]]

Interval[{DawsonF[ Root[{-(1/2) + DawsonF[#1] #1 &, -0.924138873004591767012823271504}]], DawsonF[Root[{-(1/2) + DawsonF[#1] #1 &, 0.924138873004591767012823271504}]]}]

Interval[{0, DawsonF[Root[{-(1/2) + DawsonF[#1] #1 &, 0.924138873004591767012823271504}]]}]

Interval[{-DawsonF[1], -DawsonF[2]}, {DawsonF[2], DawsonF[1]}]