2
$\begingroup$

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).

Let's start with an equation:

eq = 0.013455``7*x == 2.455``4;
{#, InputForm[#]} &@ (x /. Solve[eq, x][[1]])

(* {182.5,182.4600520252694165677`4.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.013455`5.128883702099774*x == 2.455`4.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.45910714285714285714285714285714285714`16.255619765854984}
*)

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

x <= 182.4600520252694165677`4.089021500795006

Thanks for any help.

$\endgroup$
  • $\begingroup$ Can you introduce "slack" variables to represent the uncertainties in your data and then replace your inexact values with exact ones? $\endgroup$ – mikado May 10 '17 at 20:44
  • $\begingroup$ 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. $\endgroup$ – akm May 11 '17 at 13:17
  • 1
    $\begingroup$ by the way: Mathematica version 11.1.1 for Microsoft Windows (64-bit) (April 18, 2017) has the same issue $\endgroup$ – akm May 11 '17 at 13:18
1
$\begingroup$

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.013455``7] //InputForm

Interval[{0.0134548807907104492`5.128879854298511, 0.0134551192092895508`5.1288875498669455}]

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

Interval[0.013455``7] //N

Interval[{0.0134549, 0.0134551}]

So, for your equation, we have:

eq = 0.013455``7*x == 2.455``4;
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}]

$\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.