# Converting inequalities to intervals

I have an inequality, ie: 1.57116 < g < 14.1405

There will be a large set of similar inequalities, and I want to find the intersection of them all. I figured it would be easier to convert the inequalities to intervals first. Then find the intersection.

Is there an easy way to convert inequalities to intervals as the inequalities are generated? Alternatively, a way to find the intersection of a group of inequalities.

• Try Reduce[3 < x < 5 && 2 < x < 4] Jul 18 '13 at 14:34
• Interval represents closed intervals. Do you wish to keep track of open and half-open intervals? Jul 18 '13 at 14:56

I voted once to close this question as OP gave us not enough information about what is the desired output and the context.

Since I can't vote to close the second time I decided to write something :)

Couple of thoughs at the begining.

First of all, I'd use Reduce to deal with this problem and convert only the result. But if you ask I find it a good exercise to try doing what you ask for.

Pattern approach, as suggested by Anon, is no a bad idea. One just has to remember the issue I've pointed out in comments. Also, the origin of inequalities is important too.

in = Reduce[3 < x < 5 && 2 < x < 4] (*progenitor of the inequality :)*)
in // FullForm
in // LogicalExpand // FullForm (*modyfied*)
3 < x < 4 // FullForm (*typed by hand*)

Inequality[3,Less,x,Less,4]
And[Less[3,x],Less[x,4]]
Less[3,x,4]


All the same, all different. That's why I think using LogicalExpand for preventive purposes is a good idea. It will create, not the most compact solution, but matching the same pattern.

Reduce[3 < x < 5 && 2 < x < 4] (*automatic and modyfied*)
3 < x < 4 // LogicalExpand // FullForm (*by hand & modyfied*)

And[Less[3,x],Less[x,4]]
And[Less[3,x],Less[x,4]]


But still we can see that there is some kind of inconsitence which will result in to much complicated patterns or to many of them. I mean that there is: Less[3,x] And Less[x,4] which could be also written Greater[x, 3] And Less[x, 4]. Good to know that we can convert all to consistent form with Reduce:

3 > x // FullForm
Reduce[3 > x] // FullForm

Greater[3,x]
Less[x,3]


Ok, now we can create solution, step by step:

(3 > x || x > 4 /. i_[s_?NumericQ, f_] :> Reduce[i[s, f]])

x < 3 || x > 4

x < 3 || x > 4 /. {i_[s_, f_?NumericQ] :> Which[
MemberQ[{Greater, GreaterEqual}, i], Interval[{f, Infinity}],
MemberQ[{Less, LessEqual}, i], Interval[{-Infinity, f}]
]
}

Interval[{-Infinity, 3}] || Interval[{4, Infinity}]

Interval[{-Infinity, 3}] || Interval[{4, Infinity}] /. {Or -> IntervalUnion,
And -> IntervalIntersection}

Interval[{-Infinity, 3}, {4, Infinity}]


And all together

conv[ineq_] := Fold[
ReplaceAll[#, #2] &,
ineq // LogicalExpand,
{
i_[s_?NumericQ, f_] :> Reduce[i[s, f]]
,
{i_[s_, f_?NumericQ] :> Which[
MemberQ[{Greater, GreaterEqual}, i], Interval[{f, Infinity}],
MemberQ[{Less, LessEqual}, i], Interval[{-Infinity, f}]
]
}
,
{Or -> IntervalUnion, And -> IntervalIntersection}
}
]

conv[Reduce[3 < x < 5 && 2 < x < 4]]

Interval[{3, 4}]

conv[3 < x < 5 && 2 < x < 4]

Interval[{3, 4}]


This solution assumes that intervals all always closed. Maybe I will generalize this if I will find some time in the future.

Since version 10, there is RegionBounds that can be used to do exactly this kind of job if the boolean expression is first converted to an ImplicitRegion:

boole = {
1.57116 < x < 14.1405,
0 < x < 1,
0 < x < 10,
0 <= x <= 1,
x == 2,
0 < x < 1 && -1 < x < 2,
0 < x < 1 && 3 < x < 4,
0 < x < 1 || 3 < x < 4,
0 < x < Infinity,
Element[x, Integers],
x < 3 || x > 4
};

reg = ImplicitRegion[#, x] & /@ boole;

TableForm[
{RegionBounds[#, "Minimal"], RegionBounds[#, "Sufficient"],
RegionBounds[#, "Finite"]} & /@ reg,
TableHeadings -> {boole, {"Minimal", "Sufficient", "Finite"}},
TableDepth -> 2]


Default is "Minimal", but for some cases, it might not return a proper interval. "Finite" returns a finite (not necessarily the smallest) bounding region for unbounded regions, e.g. halflines, halfplanes, etc. This is useful if one wants to provide a default interval for example to a Slider that is used to manipulate x that is by default not bound.

RegionBounds works in any dimensions:

boole = {
0 < x < 1 && 0 < y < 1,
0 <= x < 1 && -1 < y <= 2,
0 <= x,
x^2 + y^2 <= 1,
x^2 + y^2 <= 1 && Gamma[x - y] <= x + y,
x^2 + y^2 <= 4 || (x - 3)^2 + y^2 <= 3
};

reg = ImplicitRegion[#, {x, y}] & /@ boole;

TableForm[{Quiet@RegionPlot[#, ImageSize -> 60, FrameTicks -> None,
PlotRange -> {{-3, 3}, {-3, 3}}], RegionBounds[#, "Minimal"],
RegionBounds[#, "Sufficient"], RegionBounds[#, "Finite"]} & /@
reg /. {_RegionBounds | _RegionPlot -> "..."},
TableHeadings -> {boole, {"RegionPlot", "Minimal", "Sufficient",
"Finite"}}, TableDepth -> 2]


Here's a refinement of @István's answer that produces Interval objects:$$\infty$$

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]


A couple examples showing the differences:

ToInterval[0<x<1 || 3<x<4, x]
ToInterval[x<3 || x>4, x]


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

Interval[{-∞, 3}, {4, ∞}]

vs.

RegionBounds @ ImplicitRegion[0<x<1 || 3<x<4, x]
RegionBounds @ ImplicitRegion[x<3 || x>4, x]


{{0, 4}}

{{-∞, ∞}}

Another more complicated example:

ToInterval[
Reduce[x^3 > 6 Sin[x] + 1, x],
x
] //N


Interval[{-1.7039, -0.168253}, {1.88567, ∞}]

Visualization:

Plot[{x^3, 6 Sin[x] + 1}, {x, -3, 4}, Filling -> {1 -> {{2}, {None,Blue}}}]


For each inequality:

Interval[Replace[1.57116 < g < 14.1405, Less[n__, __, m__] -> {n, m}]]


To find the intersection, as you have figured out, you can use IntervalIntersection.

• Be careful with a<x<b, Reduce, Piecewise etc like to create different wrapper for them Inequality[a, Less, x, Less, b]. But LogicalExpand will make your inequalities match to _[_,_].
– Kuba
Jul 18 '13 at 15:11
• If there are other types of inequalities than in the OP, this answer needs to be expanded for sure. Jul 18 '13 at 15:25
• Of course but I'm talking about his one. Look here Reduce[1 < x < 2] // FullForm.
– Kuba
Jul 18 '13 at 15:47
• @Kuba Alright, that complicates things a lot. LogicalExpand may be a good approach as you suggest, but otherwise writing patterns that specifically conforms to the sort of inequality formatting the OP is dealing with should be straight forward if one knows what it is. So I guess the message to the OP is to use FullForm on his inequalities to figure that out. Jul 18 '13 at 16:31