Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
relational operator tolerences

Subject: relational operator tolerences

From: Brandon Moore

Date: 21 Jul, 2010 18:30:22

Message: 1 of 12

Wondering if there is some easy way to adjust the tolerances on the relational operators (==, <, etc.) in MATLAB so I don't have things like sum([0.4 0.3 0.2 0.1])==1 come back false. I.e., I don't want to have to include a +tolerance or -tolerance term every time I use a relational operator in order for it to not have these sort of errors (or rather, to error more on the side of logical true instead of logical false).

Subject: relational operator tolerences

From: Andy

Date: 21 Jul, 2010 18:38:04

Message: 2 of 12

"Brandon Moore" <moorebj.nospamplease@umich.edu> wrote in message <i27ebu$mkb$1@fred.mathworks.com>...
> Wondering if there is some easy way to adjust the tolerances on the relational operators (==, <, etc.) in MATLAB so I don't have things like sum([0.4 0.3 0.2 0.1])==1 come back false. I.e., I don't want to have to include a +tolerance or -tolerance term every time I use a relational operator in order for it to not have these sort of errors (or rather, to error more on the side of logical true instead of logical false).

You could overload these with your own function.

Subject: relational operator tolerences

From: Sean

Date: 21 Jul, 2010 18:46:13

Message: 3 of 12

"Brandon Moore" <moorebj.nospamplease@umich.edu> wrote in message <i27ebu$mkb$1@fred.mathworks.com>...
> Wondering if there is some easy way to adjust the tolerances on the relational operators (==, <, etc.) in MATLAB so I don't have things like sum([0.4 0.3 0.2 0.1])==1 come back false. I.e., I don't want to have to include a +tolerance or -tolerance term every time I use a relational operator in order for it to not have these sort of errors (or rather, to error more on the side of logical true instead of logical false).

Subtract the two and see if the absolute difference meets the tolerance.

abs(sum([.4,.3,.2,.1]) - 1) <tol

Subject: relational operator tolerences

From: Brandon Moore

Date: 21 Jul, 2010 18:53:04

Message: 4 of 12

> You could overload these with your own function.

Sure. I guess I could write a local version of eq and use that instead of ==, but where's the fun in that? :) I have a clue how I would overload the actual == operator.
 

Subject: relational operator tolerences

From: John D'Errico

Date: 21 Jul, 2010 19:11:04

Message: 5 of 12

"Brandon Moore" <moorebj.nospamplease@umich.edu> wrote in message <i27ebu$mkb$1@fred.mathworks.com>...
> Wondering if there is some easy way to adjust the tolerances on the relational operators (==, <, etc.) in MATLAB so I don't have things like sum([0.4 0.3 0.2 0.1])==1 come back false. I.e., I don't want to have to include a +tolerance or -tolerance term every time I use a relational operator in order for it to not have these sort of errors (or rather, to error more on the side of logical true instead of logical false).

No, there is no easy way to do this automatically,
beyond overloading the ops themselves. And that
might be a VERY dangerous thing to do.

Note that all of matlab would then be using your
overloaded relops, possibly causing incredibly
difficult to find bugs in the base matlab codes.
In some cases, they may actually be relying on
exact behaviors for those operators. An author
who is careful may choose to take advantage of
such things.

At the very least, this will cause all of matlab to
now run more slowly. So I would strongly
recommend NOT going down this overloading
path. It will come back to bite you in the butt
one day.

You might choose to implement your own
distinct tests, passing in an explicit tolerance,
and use these new functions where you wish
to employ a test with a tolerance. This will be
safe for all concerned. And if there is a bug, it
will be easier for you to track down.

John

Subject: relational operator tolerences

From: Matt J

Date: 21 Jul, 2010 19:15:10

Message: 6 of 12

"Brandon Moore" <moorebj.nospamplease@umich.edu> wrote in message <i27fmg$huj$1@fred.mathworks.com>...
> > You could overload these with your own function.
>
> Sure. I guess I could write a local version of eq and use that instead of ==, but where's the fun in that? :) I have a clue how I would overload the actual == operator.
===============

If it's fun you're looking for, you can do a quick overloading of the == operator using my MatrixObj class

http://www.mathworks.com/matlabcentral/fileexchange/26611-on-the-fly-definition-of-custom-matrix-objects

Depending on how you'll be using this, it could also be useful to you, as well as fun, but to keep the syntax brief, you would have to automate parts of my example below by encapsulating it in a function:

%%%%put this object setup in a function
l=MatrixObj;
l.Params.tol=.01; %tolerance parameter
l.Params.val=1; %Value parameter

l.Ops.eq=@(x,A) abs(A.Params.val-x)<=A.Params.tol;


%%%Example

>> sum([.4 .3 .2 .1001])==l %True within the tolerance of .01

ans =

     1

>> sum([.4 .3 .2 .15])==l %False, even accounting for tolerance

ans =

     0

Subject: relational operator tolerences

From: Andy

Date: 21 Jul, 2010 19:23:05

Message: 7 of 12

"John D'Errico" <woodchips@rochester.rr.com> wrote in message <i27go8$q2s$1@fred.mathworks.com>...
> "Brandon Moore" <moorebj.nospamplease@umich.edu> wrote in message <i27ebu$mkb$1@fred.mathworks.com>...
> > Wondering if there is some easy way to adjust the tolerances on the relational operators (==, <, etc.) in MATLAB so I don't have things like sum([0.4 0.3 0.2 0.1])==1 come back false. I.e., I don't want to have to include a +tolerance or -tolerance term every time I use a relational operator in order for it to not have these sort of errors (or rather, to error more on the side of logical true instead of logical false).
>
> No, there is no easy way to do this automatically,
> beyond overloading the ops themselves. And that
> might be a VERY dangerous thing to do.
>
> Note that all of matlab would then be using your
> overloaded relops, possibly causing incredibly
> difficult to find bugs in the base matlab codes.
> In some cases, they may actually be relying on
> exact behaviors for those operators. An author
> who is careful may choose to take advantage of
> such things.
>
> At the very least, this will cause all of matlab to
> now run more slowly. So I would strongly
> recommend NOT going down this overloading
> path. It will come back to bite you in the butt
> one day.
>
> You might choose to implement your own
> distinct tests, passing in an explicit tolerance,
> and use these new functions where you wish
> to employ a test with a tolerance. This will be
> safe for all concerned. And if there is a bug, it
> will be easier for you to track down.
>
> John

I don't think it would be dangerous to overload eq with a new function call syntax, e.g. eq(A,B,'tol',tolerance). Without the additional arguments, other calls to eq would function as normal.

That said, if you don't want to worry, you can just create your own wrapper function:

function tf = isClose(A,B,tolerance)
  tf = (A-B) <= tolerance;
end

This would at least save some typing in the long run, while making your code easy to read (not risking any confusion that might occur with an overloaded eq).

Subject: relational operator tolerences

From: Walter Roberson

Date: 21 Jul, 2010 19:21:47

Message: 8 of 12

John D'Errico wrote:

> No, there is no easy way to do this automatically,
> beyond overloading the ops themselves. And that
> might be a VERY dangerous thing to do.
>
> Note that all of matlab would then be using your
> overloaded relops, possibly causing incredibly
> difficult to find bugs in the base matlab codes.
> In some cases, they may actually be relying on
> exact behaviors for those operators. An author
> who is careful may choose to take advantage of
> such things.

As an example of what John describes:

histc() reserves the final output bin to count values that are exact equal to
the last provided edge. If comparisons suddenly became slightly fuzzy in the
manner described ("erring on the side of logical true"), then

x < x

and

x == x

would both be true and it would then be ambiguous as to whether the values
exactly matching the last edge should be counted towards the second-last bin
or toward the final bin or both.

Subject: relational operator tolerences

From: Walter Roberson

Date: 21 Jul, 2010 19:24:49

Message: 9 of 12

Andy wrote:

> That said, if you don't want to worry, you can just create your own
> wrapper function:
>
> function tf = isClose(A,B,tolerance)
> tf = (A-B) <= tolerance;
> end

You probably meant to type

   tf = abs(A-B) <= tolerance;

Subject: relational operator tolerences

From: someone

Date: 21 Jul, 2010 19:31:36

Message: 10 of 12

"Andy " <myfakeemailaddress@gmail.com> wrote in message
snip ...
>
> That said, if you don't want to worry, you can just create your own wrapper function:
>
> function tf = isClose(A,B,tolerance)
> tf = (A-B) <= tolerance;
> end
>
> This would at least save some typing in the long run, while making your code easy to read (not risking any confusion that might occur with an overloaded eq).

I think you want to change the above to:

> tf = abs(A-B) <= tolerance;

Subject: relational operator tolerences

From: Matt J

Date: 21 Jul, 2010 19:56:04

Message: 11 of 12

Here's a bit more embellished version of my last example that uses the
oneWithTol() function down at the bottom of the post to create the object in a single line. The object returned by oneWithTol allows you to do a series of tolerance-qualified comparisons with arbitrary numbers, all without function call syntax.

 l=oneWithTol(.01); %Represents the number 1 with a tolerance of .01

%%Comparison operations

>> sum([.4 .3 .2 .1001])==l %Equal to one within tolerance of .01

ans =

     1

>> sum([.4 .3 .2 .1001 9])==l %Not equal to one within tolerance of .01

ans =

     0

>> sum([.4 .3 .2 .1001 9])==10*l %But it is equal to 10 within the tolerance

ans =

     1

>> sum([.4 .3 .2 .15 9])==10*l %Not equal to 10 within the tolerance

ans =

     0





function FuzzyOne=oneWithTol(tol,val)
%FuzzyOne=oneWithTol(tol) - Returns an object FuzzyOne representing the
%scalar 1, but with the property that operations expression==FuzzyOne will
%be evaluated with the input tolerance, tol
%
%Also, FuzzyOne can be scaled arbitrarily c*FuzzyOne to permit comparisons
%with numbers other than one.

if nargin<2, val=1; end %for now extra argout only used internally

FuzzyOne=MatrixObj;
FuzzyOne.Params.tol=tol;
FuzzyOne.Params.val=val;
FuzzyOne.Ops.eq=@(x,A) abs(A.Params.val-x)<=A.Params.tol;
FuzzyOne.Ops.mtimes=@(c,A) oneWithTol(A.Params.tol,c*A.Params.val);

Subject: relational operator tolerences

From: Brandon Moore

Date: 21 Jul, 2010 20:30:39

Message: 12 of 12

Walter Roberson <roberson@hushmail.com> wrote in message
> histc() reserves the final output bin to count values that are exact equal to
> the last provided edge. If comparisons suddenly became slightly fuzzy in the
> manner described ("erring on the side of logical true"), then
>
> x < x
>
> and
>
> x == x
>
> would both be true and it would then be ambiguous as to whether the values
> exactly matching the last edge should be counted towards the second-last bin
> or toward the final bin or both.

Good point. Probably better to leave this alone and deal with approximation problems explicitly. At least until someone invents a computer that works with real numbers.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us