25
$\begingroup$

Open Intervals

Following up on this question, I was wondering whether Mma can handle open intervals. For example, the union of the intervals, $$1<x<5$$ and $$5<x<8$$

should not include the number 5. This is easy enough to do in one's head, but how can it be done, if at all, computationally?

Interval Complement

Also, is there a way to find the complement of two intervals? IntervalComplement[int1,int2,int3] should contain all the points in int1 that are not in the other intervals.


Edit:

Let's take Mark McClure's data as an example.

int1 = x < -2 || -1 <= x < 1 || x == 3 || 4 < x <= Pi^2;
int2 = -3 <= x < 0 || x > 1;

The intervals are shown below:

intervals

The Interval Complement (drawn above in blue on the x-axis) would seem to be:

x < -3 || 0 <= x < 1
$\endgroup$
  • $\begingroup$ Read this thread forums.wolfram.com/mathgroup/archive/2006/Oct/msg00258.html $\endgroup$ – Dr. belisarius Oct 1 '12 at 2:48
  • $\begingroup$ @belisarius Yes, Andrzej Kozlowski's IntervalComplement does work for closed intervals. Very nice! It seems like his code does not handle open intervals, relying, as it does, on Interval for input. $\endgroup$ – DavidC Oct 1 '12 at 2:57
  • $\begingroup$ Read thru the end :) forums.wolfram.com/mathgroup/archive/2006/Oct/msg00347.html $\endgroup$ – Dr. belisarius Oct 1 '12 at 3:02
  • 1
    $\begingroup$ I have now read through to the end. I did not feel that anything was resolved. I did not find compelling the attempted explanation of IntervalComplement's inherent contradiction. Furthermore, the discussions about inclusion or not of endpoints in intervals was biased by the fact that mms does not (apparently) recognize open intervals. Would you like to present your take on the discussion? $\endgroup$ – DavidC Oct 1 '12 at 3:18
  • 2
    $\begingroup$ I used Mathematica v.9 (or v. 8). I must have drawn everything "by hand". If I were to do it with v.10, I would use NumberLinePlot[{{-\[Infinity] < x < -2, -1 < x <= 1, 4 < x <= Pi^2}}, x] and so forth. $\endgroup$ – DavidC Jan 29 '15 at 16:06
28
$\begingroup$

I'd represent the sets using inequalities and/or equalities and then apply Reduce. Here's an example:

set1 = x < -2 || -1 <= x < 1 || x == 3 || 4 < x <= Pi^2;
set2 = -3 <= x < 0 || x > 1;
Reduce[set1 && set2]

enter image description here

Here's the complement of the union of the two intervals.

Reduce[!(set1 || set2)]

(* Out: x==1 *)

We might define an interval complement function as follows:

intervalComplement[bigInt_, moreInts__] := 
  Reduce[bigInt && (! (Or @@ {moreInts}))];

For example:

intervalComplement[-10 < x <= 10, -8 < x <= -6, 
  0 <= x <= 2, x == 3]
(* Out: -10 < x <= -8 || -6 < x < 0 || 2 < x < 3 || 3 < x <= 10 *)
$\endgroup$
  • $\begingroup$ You might want to take a look at the explanation and picture I placed in the question. $\endgroup$ – DavidC Oct 1 '12 at 4:31
  • $\begingroup$ @DavidCarraher I did. I also checked that my intervalComplement gave your desired answer. $\endgroup$ – Mark McClure Oct 1 '12 at 4:34
  • $\begingroup$ Very nice solution. It handles open intervals! $\endgroup$ – DavidC Oct 1 '12 at 16:04
  • $\begingroup$ @MarkMcClure, is there a WL function to map Interval to algebraic expresssion and back to Interval? $\endgroup$ – alancalvitti Nov 11 '15 at 17:57
  • $\begingroup$ @alancalvitti There is no such function that I know of, though it should be quite easy to create one using patterns. Something like toInequality[Interval[{a_,b_}], var_] := a<var<b. Then, for example, toInequality[Interval[{1, 2}], x] returns 1<x<2. Of course, you'd still need to decide whether you want open or closed intervals or some combination depending on the situation. $\endgroup$ – Mark McClure Nov 11 '15 at 18:09
11
$\begingroup$

Here's an implementation of interval complement that is meant to be used with Interval expressions. Interval represents closed intervals according to the documentation, and this is consistent with the things the built-in functions do with intervals. However, in this implementation of the interval complement I simply ignore whether an interval is open or closed. I realize that this is not exactly what you asked for. I wrote this because I needed it, and I thought it'd be useful to post it.


intervalInverse[Interval[int___]] := 
  Interval @@ 
    Partition[
      Flatten @ {int} /.
        {{-∞, mid___, ∞} :> {    mid   },
         {-∞, mid__    } :> {    mid, ∞},
         {    mid__,  ∞} :> {-∞, mid   },
         {    mid___   } :> {-∞, mid, ∞}},
      2
    ]

intervalComplement[a_Interval, b__Interval] := 
 IntervalIntersection[a, intervalInverse @ IntervalUnion[b]]

intervalInverse[a] will compute the complement $(-\infty, \infty) \setminus a$.

intervalComplement[a,b,c,...] will compute $a \setminus (b \cup c \cup \ldots )$.


Example usage:

In[]:= intervalInverse[Interval[{1, 2}]]
Out[]= Interval[{-∞, 1}, {2, ∞}]

In[]:= intervalComplement[Interval[{0, 10}], Interval[{2, 3}]]
Out[]= Interval[{0, 2}, {3, 10}]
$\endgroup$
  • 2
    $\begingroup$ Nice. It surprises me that something like this is not native to Mathematica, yet. $\endgroup$ – DavidC Feb 21 '14 at 13:36
  • $\begingroup$ @DavidCarraher My guess is that it's not implemented because the complement of two closed intervals is going to be an open interval, which can't be represented using Interval (if we keep the assumption that it always represents a closed ones). I was sloppy and ignored all this because it didn't matter for my application. That sloppyness results in things like this intervalInverse@intervalInverse[Interval[{1, 1}]] --> Interval[]. By taking the "inverse" twice I lost the endpoints of this zero-length non-empty closed interval and ended up with an empty interval. $\endgroup$ – Szabolcs Feb 21 '14 at 18:09
  • $\begingroup$ Yes, but is an empty interval any stranger than an empty set? Granted, it is an interval without location. On the other hand, an empty set is a set with no elements. $\endgroup$ – DavidC Feb 21 '14 at 19:48
  • $\begingroup$ @Szabolcs, Interval[{0,1}] ~ IntervalIntersection ~ Interval[{2,3}] ==> Interval[], empty interval. $\endgroup$ – alancalvitti Mar 22 '16 at 21:55
2
$\begingroup$

This is my code

{a = x > 1 && x < 5, b = x > 5 && x < 8}
{Reduce[a && b]}  

and

{a = x > 1 && x < 5, b = x >= 5 && x < 8}
{Reduce[a || b]}

Edit

Some examples

{a = x > 0 && x < 3, b = x > -1 && x < 2, c = x > -2 && x < 1} {Reduce[a && (b || c)],
Reduce[(a && b) || (a && c)], Reduce[a || (b && c)], Reduce[(a || b) && (a || c)]} 
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.