# How to solve an inequality using low precision (< MachinePrecision)?

I would like to use low precision data (based on measurement results with a low precision) to solve a set of inequalities. I have prepared a minimum working example to demonstrate the issue. I am using Mathematica version 11.1.0 for Linux x86 (64-bit) (March 13, 2017).

eq = 0.0134557*x == 2.4554;
{#, InputForm[#]} &@ (x /. Solve[eq, x][])

(* {182.5,182.46005202526941656774.089021500795006} *)


The result has a precision of approx. 4 digits. The input equation (fixed Accuracy) is converted to a fixed Precision expression:

InputForm @ eq

(* 0.0134555.128883702099774*x == 2.4554.390051496458987 *)


My real word problem is an inequality (more precisely: a set of inequalities, but let's keep it simple for this demonstration). Solve is not able to find a solution now:

Solve[eq /. Equal -> LessEqual, x]

(*
Solve::fulldim: The solution set contains a full-dimensional component; use Reduce for complete solution information.
Solve::ratnz: Solve was unable to solve the system with inexact coefficients. The answer was obtained by solving a corresponding exact system and numericizing the result.

{{}}
*)


If I use Reduce, I get a solution, but the precision is much larger than expected (i.e., a precision of approximately 16 which is even greater than \$MachinePrecision):

{#, InputForm[#]} &@ (Reduce[eq /. Equal -> LessEqual, x])

(*
Reduce::ratnz: Reduce was unable to solve the system with inexact coefficients. The answer was obtained by solving a corresponding exact system and numericizing the result.

{x <= 182.4591071428571,x <= 182.4591071428571428571428571428571428571416.255619765854984}
*)


How can I solve the inequality (either with Solve or Reduce) with correct precision? We should expect:

x <= 182.46005202526941656774.089021500795006


Thanks for any help.

• Can you introduce "slack" variables to represent the uncertainties in your data and then replace your inexact values with exact ones? – mikado May 10 '17 at 20:44
• I have tried this approach with two slack variables eq = SetPrecision[(0.013455 + e1)*x <= (2.455 + e2), MachinePrecision + 1] (I had to exceed MachinePrecision first to get it work). Afterwards, Reduce[eq, x, Reals] /. {e1 -> SetAccuracy[0., 7], e2 -> SetAccuracy[0., 4]} gave me a low precision answer. I would prefer a solution without slack variables. – akm May 11 '17 at 13:17
• by the way: Mathematica version 11.1.1 for Microsoft Windows (64-bit) (April 18, 2017) has the same issue – akm May 11 '17 at 13:18

One idea is to use Interval objects instead of reals. In your example, I would first apply Interval to your low precision number:

Interval[0.0134557] //InputForm


Interval[{0.01345488079071044925.128879854298511, 0.01345511920928955085.1288875498669455}]

and then convert the end points of the interval into machine precision:

Interval[0.0134557] //N


Interval[{0.0134549, 0.0134551}]

So, for your equation, we have:

eq = 0.0134557*x == 2.4554;
ieq = eq /. r_Real :> N @ Interval[r]


x Interval[{0.0134549, 0.0134551}] == Interval[{2.45488, 2.45512}]

Then, you can use Solve as usual (I included a domain restriction because is avoids some error messages later):

Solve[ieq, x, Reals]


{{x -> Interval[{182.449, 182.471}]}}

For the inequality:

leq = LessEqual @@ ieq;


Solve again doesn't work:

Solve[leq, x, Reals]


Solve::fdimc: When parameter values satisfy the condition True, the solution set contains a full-dimensional component; use Reduce for complete solution information.

{}

But this time Reduce works fine:

Reduce[leq, x, Reals]
`

x <= Interval[{182.449, 182.471}]