# How to set a tolerance level for equality constraints

Given two equality constraints: x+y==250 and z+p==65 where x=190, y=50, z=45, p=15, I want to specify an error-tolerance level of e=0.05 below which the first equality should be TRUE and above which the second equality be FALSE.

{x=190, y=50, z=45, p=15};
eq1= x+y==250;   (* e=0.0416 is the percentage change from 250*)
eq2= z+p==65;    (* e=0.0833 is the percentage change from 65*)

(*Mathematica output*)
(*FALSE, FALSE*)

(*I like to receive for given e=0.05*)
(*TRUE, FALSE*)


How can I set the error-tolerance level of e=0.05 for the two constraints?

Any idea?

• Search the site for $EqualTolerance Sep 15 '19 at 16:25 • @MichaelE2: I can give a specific tolerance level for the system of equations, but my question is about an error-tolerance calculated as percentage change in the equality concerned. As far as I know you can not set the tolerance level to percentage changes because every equation has a different level of percentage change. Sep 15 '19 at 17:33 • A proper objection to $EqualTolerance would be that you do not want to use machine precision floats, but would like something that works on, say, exact input such as shown (except for e=0.05). Otherwise, it does what you desire: Block[{Internal$EqualTolerance = MachinePrecision + Log10[0.05]}, {eq1 = x + y == 250., eq2 = z + p == 65.} ] Sep 15 '19 at 19:24 • @MichelE2: Thank you very much for this answer. Here, what does MachinePrecision+Log10[0.05] do? I know it generates the output I want, but I did not understand what your code does. Sep 15 '19 at 22:40 • Why are you asking for equality when you don't want equality? You seem to want$0.95 \cdot 250 \leq x+y \leq 1.05 \cdot 250$as your first relation, so why isn't this what you are computing? Sep 16 '19 at 4:05 ## 3 Answers ClearAll[choppedEqual] SetAttributes[choppedEqual, {HoldFirst, Listable}] choppedEqual[a_ == b_, c_] := Chop[N@(a - b)/a, c] == 0.  Examples: choppedEqual[x + y == 250, .05]  True choppedEqual[z + p == 65, .05]  False choppedEqual[{x + y == 250, z + p == 65}, .05]  {True, False} • Yes, you solved my problem. Thank you so much. Regards.. Sep 15 '19 at 19:26 • @TugrulTemel, my pleasure. Thank you for the accept. – kglr Sep 15 '19 at 19:31 • In real case, I have many equations to be tested. It will be time consuming to enter each equation in the format you use. Is there any other way to format choppedEqual[x + y, 250, .0416] automatically, separating the left (x+y) and right 250 sides of each equation? Sep 15 '19 at 22:46 • @Tugrul, please see the new version. – kglr Sep 15 '19 at 23:02 • @Tugrul, I originally misread e=0.0416 and e=0.0833 as different tolerance levels you wished to apply to eq1 and eq2, respectively. It is fixed now. – kglr Sep 16 '19 at 18:34 Some more ways, with the relative error e = 0.05: Block[{Internal$EqualTolerance = MachinePrecision + Log10[e]},
{x + y == 250., z + p == 65.} (* advantage: equations written in terms of == *)
]
(*  {True, False}  *)

{SetPrecision[x + y, -Log10[e]] == SetPrecision[250, -Log10[e]],
SetPrecision[z + p, -Log10[e]] == SetPrecision[65, -Log10[e]]}
(*  {True, False}  *)

svn = NDSolveScaledVectorNorm[Infinity, {e, 0}];
{svn[{x + y - 250}, {250}] < 1, svn[{z + p - 65}, {65}] < 1}
(*  {True, False}  *)

• The first seems to be the obviously correct way to do this, to my eyes at least. Sep 15 '19 at 20:28
• @MichaelE2: The first option will be my choice because it uses the equations in terms of ==. What I do not understand is what MachinePrecision+Log10[e] imposes as the tolerance level? What kind of number is that? Sep 15 '19 at 23:10
• @TugrulTemel See mathematica.stackexchange.com/questions/86815/… and stackoverflow.com/a/6626748 for some discussion. Setting \$EqualTolerance to a causes two numbers to be considered equal if they agree except for the lower-order a digits (base 10), which means that machine-precision numbers would be considered equal if the relative error is less than 10^(MachinePrecision - a). Hence if it is set to MachinePrecision - a, they would be equal if the relative error is less than 10^a, where a = Log10[e]. Sep 16 '19 at 1:08
• @MichaelE2: Thank you very much for your explanation and reference for reading. Sep 16 '19 at 10:10

You can use Congruent.

ClearAll[Congruent]
TOL = 0.05;
Congruent[a_, b_] :=
If[Abs[a - b] > 0, Abs[a - b] / Norm[{a, b}, Infinity] <= TOL, True];


your answer does not show how I test these equations with Congruent. Can you show me how I use Congruent?

Please note that lines 37 and 39 on the attached screenshot use Congruent.

It can be seen in the linked function page that the infix symbol of Congruent ("≡") can be entered as "Esc === Esc".

x + y ≡ 250
(* True *)

z + p ≡ 65
(* False *)


Using Block we can also make bulk evaluations of many equalities.

Block[{Equal = Congruent},
{x + y == 250, z + p == 65}
]

(* {True, False} *)

• You seemed to answer the question, but I did not understand what you propose. I have two specific equations and your answer does not show how I test these equations with Congruent. Can you show me how I use Congruent? Sep 15 '19 at 17:27
• @TugrulTemel See the update of my answer. Sep 15 '19 at 19:22
• Now I understand the code, though it is still not so clear how I enter the constraints to be tested. Sep 15 '19 at 23:13
• @TugrulTemel You can use Block[{Equal = Congruent},...]` -- see my answer update. Sep 16 '19 at 0:09