3 views (last 30 days)

I calculated a matrix (attached). In the 11th row, matlab considers the 3rd column, i.e., entry (11, 3) as the maximum entry of the that row, although, the entries in columns 1, 2, ..., 7, and 15 have the exact same value, i.e.,

find(matrix(11, :) == max(matrix(11, :)))

only gives 3.

Does anyone know why it happens?

Thanks

Star Strider
on 6 Dec 2019

You are not seeing the entire picture.

If you test ‘matrix(11,:)’:

Check = matrix(11, :) - max(matrix(11,:))

the result is:

Check =

-0.000000000000006 -0.000000000000002 0.000000000000000 -0.000000000000007 -0.000000000000003 -0.000000000000004 -0.000000000000002 -0.500000000000002 -0.999999999999997 -1.499999999999993 -1.999999999999991 -1.499999999999994 -1.000000000000000 -0.500000000000006 -0.000000000000003

and you have encountered ‘floating-point approximation error’.

Walter Roberson
on 9 Dec 2019

You should be considering using ismembertol() instead of comparisons.

ismembertol() works with relative values by default. You can use an absolute tolerance instead if you pass in the option 'Datascale', 1 such as

ismembertol(matrix(11, :), max(matrix(11, :)), 1e-4, 'Datascale', 1)

Star Strider
on 9 Dec 2019

@Walter —

Thr original Question was about floating-point approximation error. I considered ismembertol for the comaprisions, however this Comment introduces some ambiguity with respect to the what Mohammad wants. Apparently, Mohammad wants 4-digit precision everywhere. That may not be possible because certain operations would inevitably result in extended precision results that would again need to be truncated.

Walter Roberson
on 10 Dec 2019

Sign in to comment.

Adam Danz
on 9 Dec 2019

Edited: Adam Danz
on 10 Dec 2019

You could limit the values in your matrix to the first 4 decimal places but this is usually not a good idea unles there's a reasonable justification to do so. Take a look at the values you mentioned.

format long % so you can see more decimal places

Trace_Wc([1,2,7],3)

ans =

1.249999999999995

1.250000000000014

1.249999999999999

As you can see, limiting those values to the first 4 dp will not give you matching values.

Those same values in "short" format are

format short

Trace_Wc([1,2,7],3)

ans =

1.2500

1.2500

1.2500

But the key point is that the format just affects what you see, not the actual values.

If you have principled reason to truncate the precision to 4 decimal places (ie, the instrument used to get the data is only precise to 3 dp), you could do so like this:

Trace_WcNew = round(Trace_Wc, 4);

% Trace_WcNew = round(Trace_Wc * 1E4)/1E4 % for <r2014b (see comments below)

Instead, if you're trying to find values in a row that are approximately equal to the max value of that row, use a threshold like this:

idx = abs(Trace_Wc(11,:) - max(Trace_Wc(11,:))) < 0.0001

This locates all values in row 11 that are within 0.0001 of the max. Here's what it's returns:

format long

Trace_Wc(11,idx)

ans =

Columns 1 through 6

2.249999999999984 2.249999999999988 2.249999999999990 2.249999999999983 2.249999999999988 2.249999999999987

Columns 7 through 8

2.249999999999988 2.249999999999988

In that case, 0.0001 is somewhat arbitrarily chosen after looking at the data. Instead, you could use a threshold that is 1/10 of 1% of the range of your data such as

threshold = range(Trace_Wc(11,:))*.001

Walter Roberson
on 9 Dec 2019

Trace_WcNew = round(Trace_Wc * 1E4)/1E4

These days,

Trace_WcNew = round(Trace_Wc, 4);

Adam Danz
on 9 Dec 2019

Jeez... that's been out since r2014b and I keep forgetting to use it.... thx Walter.

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.