10

If x = Interval[{-100,100}], then obviously x^2 + x = Interval[{-1/4,10100}], because as we know, x^2+x > -1/4. But Mathematica gives me:

x^2 + x /. x -> Interval[{-100, 100}]
(* Interval[{-100, 10100}] *)

How can I automatically get correct interval Interval[-1/4,10100] from Mathematica?

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
stiv
  • 269
  • 1
  • 8

4 Answers4

8

A possible approach for dependent intervals:

Interval@*Through@{MinValue, MaxValue}[u + u^2, {u} ∈ Interval[{-100, 100}]]
(* Interval[{-(1/4), 10100}] *)
ybeltukov
  • 43,673
  • 5
  • 108
  • 212
5
u = Interval[{-100, 100}]

According to ref / Interval / Possible Issues

Intervals are always assumed independent

so u + u^2 is something like v + u ^ 2 -> Interval[{-100, 100}] + Interval[{0, 10000}].

What can also be surprising, is the fact it is different from u + u * u which we can think of as v + u * w.

I the first example u^2 is at least 0 but in the second u can be -100 while w is 100 so the answer is: Interval[{-100, 100}] + Interval[{-10000, 10000}] -> Interval[{-10100, 10000}]

Kuba
  • 136,707
  • 13
  • 279
  • 740
4

A different way to go that captures more information than merely the intervals is:

result = TransformedDistribution[x^2 + x, Distributed[x, UniformDistribution[{-100, 100}]] ];
Plot[Evaluate[PDF[result, x]], {x, -1, 1}]
(* Discover that the likelihood of various results is not uniform. *)
Interval[{
  Minimize[{x, #}, x, Reals][[1]],
  Maximize[{x, #}, x, Reals][[1]]
} &[Reduce[PDF[result, x] > 0, x]]]

We can wrap this in a function (includes streamlining from @ybeltukov ):

dependentInterval[func_, marginVar_, varDef___] := Interval[{
  MinValue[{marginVar, #}, marginVar, Reals],
  MaxValue[{marginVar, #}, marginVar, Reals]
} &[Reduce[
  PDF[TransformedDistribution[func, Sequence /@ varDef], 
  marginVar] > 0, marginVar]
]]

dependentInterval[x^2 + x, x, Distributed[x, UniformDistribution[{-100, 100}]] ]
(* Interval[{-(1/4), 10100}] *)
Eric Towers
  • 3,040
  • 12
  • 14
3

You can use FunctionRange. For example:

IntervalReplace[expr_, x_ -> int_Interval] := Module[{f},
    f = Quiet[
        Check[
            FunctionRange[{expr,{x}\[Element]int},x,y],
            Message[IntervalRange::nmet];
            $Failed,
            FunctionRange::nmet
        ],
        FunctionRange::nmet
    ];
    ToInterval[f, y] /; f =!= $Failed
]

IntervalRange::nmet = FunctionRange::nmet;

Then:

IntervalReplace[x^2 + x, x -> Interval[{-100, 100}]]

Interval[{-(1/4), 10100}]

More complicated examples:

IntervalReplace[1/x + x, x -> Interval[{-100, 100}]]

Interval[{-\[Infinity], -2}, {2, \[Infinity]}]

IntervalReplace[x^2+DawsonF[x], x -> Interval[{-11,11}]] //N

Interval[{-0.201125, 121.046}]

Carl Woll
  • 130,679
  • 6
  • 243
  • 355