Skip to main content
Tweeted twitter.com/StackMma/status/1501256443114057733
Became Hot Network Question
added 14 characters in body
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution was to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple, but I think it slowsmight slightly slow things down:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution was to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple, but I think it slows things down:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution was to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple, but I think it might slightly slow things down:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);
deleted 225 characters in body
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution iswas to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple, but I think it slows things down:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

In my opinion this is much more clear than changing $MachinePrecision or anything like that, and you don't need to know what machine epsilon, etc is... see below for more technical answers.

The only reason I would ditch this is if it's drastically slower...

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution is to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

In my opinion this is much more clear than changing $MachinePrecision or anything like that, and you don't need to know what machine epsilon, etc is... see below for more technical answers.

The only reason I would ditch this is if it's drastically slower...

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?


EDIT: My solution was to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple, but I think it slows things down:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);
added my solution
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?

 

EDITEDIT: My solution is to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It looks scary but it'sIt's extremely simple:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

In my opinion this is much more clear than changing $MachinePrecision or anything like that, and you don't need to know what machine epsilon, etc is... see below for more technical answers.

The only reason I would ditch this is if it's drastically slower...

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?

EDIT: My solution is to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It looks scary but it's extremely simple:

Unprotect[Equal];
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

I'm running a program that evaluates equalities after I substitute all symbols for numbers. The equalities on floats are giving me trouble. My program is reaching a point where something like the following is being evaluated: 2.304793200735844`*^-8 == 2.30479302310016`*^-8 . This gives False, despite the difference being 1.77636*10^-15, which is below the Chop threshold of 10^-10. Running Chop on both numbers obviously doesn't fix the problem, since neither number is individually below the threshold.

Chop[2.304793200735844`*^-8 - 2.30479302310016`*^-8 ]==0 gives the correct result, but I can't easily make this change as not all comparisons are between floats or even lists of floats (Chop[a-b] == 0 or {0,0,0,...} is not always a valid way to test equality between a and b).

I want to avoid overcomplicating my program: I don't want to do a ReplaceAll on a_==b_ /; (a and b are numbers) -> Chop[a-b]==0 as this is very complicated, requires something like Hold, and doesn't resolve the same exact issues which arise in the case of float inequality comparisons. There's gotta be a better way! If there's not, what's the best solution?

 

EDIT: My solution is to modify Equal (==) for float comparison, and to update List equality to use this new float equality. It's extremely simple:

Unprotect[Equal]; (* this lets us edit Equal (==) *)
Equal[a_Real,b_Real]:=Chop[a-b]==0  (* change comparison for reals *)
Equal[a_List?RealQ,b_List?RealQ]:=
  Dimensions@a==Dimensions@b&&AllTrue[MapThread[#1==#2&,{a,b}],TrueQ] (* update comparison for real lists to use the new real comparison *)
Protect[Equal];

(* True iff r is a real or any nested List containing only reals *)
RealQ[r_]:=Developer`MachineRealQ[r]||Developer`RealQ[r]||(MatchQ[r,_List]&&AllTrue[r,RealQ]);

In my opinion this is much more clear than changing $MachinePrecision or anything like that, and you don't need to know what machine epsilon, etc is... see below for more technical answers.

The only reason I would ditch this is if it's drastically slower...

added my solution
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
added my solution
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
edited tags
Link
Michael E2
  • 244.7k
  • 18
  • 351
  • 774
Loading
added my solution
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
added 33 characters in body
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
deleted 37 characters in body
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
added 117 characters in body
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
edited tags
Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading
Source Link
Lucas Mumbo
  • 578
  • 3
  • 12
Loading