4

I have two intervals:

i1 = Interval[{1,4}];
i2 = Interval[{2,3}];

I need a function that subtracts i2 from i1, returning:

Interval[{1,2},{3,4}]

In other words, is there an analog of the Complement function for intervals? And if not, how would one implement it?

verse
  • 1,287
  • 6
  • 18
  • 4
    On the right side of this page, you'll see a list of related questions. One of the related questions is about finding complements of intervals:?

    http://mathematica.stackexchange.com/questions/11345/can-mathematica-handle-open-intervals-interval-complements?rq=1

    – Searke Mar 30 '16 at 02:28
  • Please note that Interval objects represent closed intervals. If you complement two such overlapping intervals, the result will have an interval with an open end. You can't represent that on Mathematica with a plain Interval object. – kirma Mar 30 '16 at 04:17
  • 2
    @Searke, I've seen that answer, but it does not seem to be very scalable. I have thousands of intervals, and it would be hard to redefine all of them as inequalities. – verse Mar 30 '16 at 05:35
  • @kirma, In my particular application it doesn't matter whether the intervals or open or closed, if there's a way to represent the resulting set as a closed interval (even if strictly speaking it should be open), I'd love to know it. – verse Mar 30 '16 at 05:35

2 Answers2

6

If you do not bother about the endpoints, you could define a complement function in the following way:

complement[x_Interval] := Interval @@ Partition[Flatten[{-\[Infinity], List @@ x, \[Infinity]}], 2]


complement[Interval[{1,2}]]
(* Interval[{-\[Infinity],1},{2,\[Infinity]}]*)

complement[Interval[{1,2},{3,4}]]
(*Interval[{-\[Infinity],1},{2,3},{4,\[Infinity]}]*)

Subtracting can be done with IntervalIntersection:

a=Interval[{0, 10}];
b=Interval[{1,3}, {7, 12}];
IntervalIntersection[a, complement[b]]

(*Interval[{0,1},{3,7}]*)
Fred Simons
  • 10,181
  • 18
  • 49
2
ClearAll[itrF, slitrF, intervalComplementF]
slitrF = Statistics`Library`IntervalToRegion;
itrF[x_][Interval[p : {_, _} ..]] := Or @@ (slitrF[#, x] & /@ Interval /@ {p});
intervalComplementF = Interval @@ (Reduce[itrF[x]@# && Not[itrF[x]@#2], x, Reals] /. 
  { Or -> List , Inequality[a_, __, b_] :> {a, b}, 
  Less[_, a_] | LessEqual[_, a_] :> {-Infinity, a}, 
  Greater[_, b_] | GreaterEqual[_, b_] :> {b, Infinity}} ) &;

Examples:

i1 = Interval[{1, 4}];
i2 = Interval[{2, 3}]; 
intervalComplementF[i1, i2]

Interval[{1, 2}, {3, 4}]

a = Interval[{0, 10}];
b = Interval[{1, 3}, {7, 12}];
intervalComplementF[a, b]

Interval[{0, 1}, {3, 7}]

intervalComplementF[Interval[{-Infinity, Infinity}], Interval[{2, 3}, {5, 6}]]

Interval[{-Infinity, 2}, {3, 5}, {6, Infinity}]

kglr
  • 394,356
  • 18
  • 477
  • 896