4

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?

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Tugrul Temel
  • 6,193
  • 3
  • 12
  • 32
  • 2
    Search the site for $EqualTolerance – Michael E2 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. – Tugrul Temel Sep 15 '19 at 17:33
  • 1
    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.} ] – Michael E2 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. – Tugrul Temel 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? – Eric Towers Sep 16 '19 at 04:05
  • @EricTowers: I want equality but the calculations show that the equality does not hold. Therefore, I want to know how much the equality deviates from the true level. If the deviation is not much relative to the error-tolerance level e=0.05, then I will assume that the equality holds. – Tugrul Temel Sep 16 '19 at 10:07

3 Answers3

6

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];

enter image description here

Addendum

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} *)
Anton Antonov
  • 37,787
  • 3
  • 100
  • 178
6

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 = NDSolve`ScaledVectorNorm[Infinity, {e, 0}];
{svn[{x + y - 250}, {250}] < 1, svn[{z + p - 65}, {65}] < 1}
(*  {True, False}  *)
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • The first seems to be the obviously correct way to do this, to my eyes at least. – b3m2a1 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? – Tugrul Temel Sep 15 '19 at 23:10
  • 3
    @TugrulTemel See https://mathematica.stackexchange.com/questions/86815/can-someone-please-explain-internalsameqtolerance/86819#86819 and https://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]. – Michael E2 Sep 16 '19 at 01:08
  • @MichaelE2: Thank you very much for your explanation and reference for reading. – Tugrul Temel Sep 16 '19 at 10:10
5
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}

kglr
  • 394,356
  • 18
  • 477
  • 896
  • Yes, you solved my problem. Thank you so much. Regards.. – Tugrul Temel 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? – Tugrul Temel Sep 15 '19 at 22:46
  • 1
    @Tugrul, please see the new version. – kglr Sep 15 '19 at 23:02
  • In your revised answer, I did not see how you included the error-tolerance level of e=0.05, but your answers are correct. I see that you do some calculations that I do not fully understand. – Tugrul Temel Sep 16 '19 at 10:55
  • 1
    @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
  • Thank you so much for your prompt reply and revised answer. It works perfectly. Regards, – Tugrul Temel Sep 16 '19 at 21:34