7
$\begingroup$

I am looking for a Mathematica function that takes an inequality as the input and gives back the width defined by upper bound - lower bound:

Example:

Fn[1 <= x <= 2.5]

1.5

If the inequality is evaluated to False (e.g., 2 <= x <= 1), then I need the function to return 0.

I truly appreciate your help.

$\endgroup$

3 Answers 3

12
$\begingroup$
f[ineq_, var_] := RegionMeasure[ImplicitRegion[ineq, var], Length[Flatten[{var}]]]

f[1 <= x <= 2.5, x]

1.5

This works also for some systems of inequalities in several variables:

f[{1 <= x <= 2.5, 0 <= y <= x}, {x, y}]

2.625

Edit:

This one-argument version treats all symbols in the first argument as variables:

f[ineq_] := f[ineq, DeleteDuplicates[Cases[ineq, _Symbol]]]
$\endgroup$
4
  • $\begingroup$ When the dimension of the region is less than Length[var], for example a line embedded in the 2D plane, then RegionMeasure gives the measure in the reduced dimension: f[{1 <= x <= 2.5, y == 0}, {x, y}] gives 1.5 (the length of the line instead of its area), which is not what's usually expected. Fix this with f[ineq_, var_] := RegionMeasure[ImplicitRegion[ineq, var], Length[var]], so that now f[{1 <= x <= 2.5, y == 0}, {x, y}] gives 0 as expected (the line has zero area). $\endgroup$
    – Roman
    Commented Jan 7, 2019 at 10:22
  • $\begingroup$ Good point! Thank your for remark; I fixed it. I should have been more cautious; these dimensional issues with regions is actually a frequent source of confusion. $\endgroup$ Commented Jan 7, 2019 at 10:28
  • $\begingroup$ I was too fast in commenting: the function now doesn't work for var=x since Length[x]=0. Maybe two separate definitions for var_Symbol (using dimension 1) and for var_List (using dimensions Length[var])? $\endgroup$
    – Roman
    Commented Jan 7, 2019 at 10:31
  • $\begingroup$ Yes even better! $\endgroup$
    – Roman
    Commented Jan 7, 2019 at 10:32
4
$\begingroup$
fn[expr_] := Module[{},
  If[! expr, Return [0]];
  If[Head[expr] == Inequality, Return[Abs[expr[[5]] - expr[[1]]]]];
  Return[Abs[expr[[3]] - expr[[1]]]];
  ]

fn[2 <= x <= 1]
(*0*)

fn[1 <= x <= 2.5]
(*1.5*)

fn[2.5 > x > 1]
(*1.5*)

Don't know if this works in all cases, but works in the simple cases you provide plus some.

$\endgroup$
3
$\begingroup$

To get a function that would handle the all the kinds of arguments I want it to handle turned out to be more of a challenge than I anticipated, but here is what I came up with.

Edit

This version is handle expressions that evaluate to False more robustly.

ClearAll[fn, helper1, helper2]

SetAttributes[fn, HoldFirst]
fn[expr_] := If[expr, helper1[expr], helper2[expr], helper1[expr]]

SetAttributes[helper1, HoldFirst]
helper1[expr : _Inequality | _Less | _LessEqual | _Greater | _GreaterEqual] :=
  Module[{args = List @@ Unevaluated[expr], a, b},
    {a, b} = MinMax[Select[args, NumericQ]];
    b - a]
helper1[___] = $Failed;

SetAttributes[helper2, HoldFirst]
helper2[expr : _Inequality | _Less | _LessEqual | _Greater | _GreaterEqual] := 0;
helper2[___] = $Failed;

###Tests

fn[1 < x <= 2.5]

1.5

fn[1 < x <= π]

-1 + π

fn[1 >= x > π]

0

fn[1 >= x > -1]

2

fn[-1 < 1 <= 2.5]

3.5

fn[1 < x < 3 < y < 5]

4

fn[1.5 < 2]

0.5

fn["garbage"]

$Failed

fn[1 == 1]

$Failed

 fn[1 != 1]

$Failed

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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