**You are now following this question**

- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.

# How to resolve floating point numbers in if condition?

2 views (last 30 days)

Show older comments

I want to find max(cor). And when I do this:

for k = 1 : length(theFiles) % files are alreaady defined in code

p=0;

t=0;

for q=.1:20

if(arr(p)<1)

if(arr(p)>0.85)

cor(t)=arr(p); %cor(t) already defined in code

t=t+1;

end

end

p=p+1;

end %end of q loop

[val1,idx1] = max(cor) ;

idx2 = find(abs(arr-val1)<10^-3) ;

end % end of k loop

Again, it shows idx2 for some of the inputs when printed, but for some it shows blank. such as:

idx2 is

I don't know whether it is relevent information or not, but the file for which the output above is shown(That is blank idx2), has the minimum of all the val1 of other files, such as, the values of val1 for other files are as follows:

9.554158e-01

9.634148e-01

9.750799e-01

9.841079e-01

9.753829e-01

9.764703e-01

Where the value for blank idx2, the val1 is:

9.243360e-01

How do I fix it?

##### 15 Comments

KSSV
on 5 Jul 2021

If you want to find the maximum use max. Why you want to comapre again with

idx2 = find(abs(arr-val1)<10^-3) ;

Walter Roberson
on 5 Jul 2021

for q=.1:20

Why do you use that? The resulting q values would be 0.1 1.1 2.1 up to 19.1 for a total of 20 iterations. But you do not use the value of q so it is just counting, so why confuse the readers?

Also you initialize p to 0 and try to use arr(p) but indexing at 0 is not permitted.

Why not skip using q and instead use for p=1:20 ?

Tawsif Mostafiz
on 5 Jul 2021

Tawsif Mostafiz
on 5 Jul 2021

@kssv correct me if I am mistaken. But isn't the idx different for cor and arr arrays? As, cor only takes the selective values of arr(p). If it weren't a floating point I would have done it in,

[val,idx] = max(cor) ;

idx1=find(arr == maximum, 1);

But how the same is acheivable for floating points?

The problem that I am facing is that, I am printing arr, cor, and val individually using fprintf. For some input, it shows that the printed val is present in cor array, but not in arr array, although cor array is supposed to be a subset of arr array.

dpb
on 5 Jul 2021

" want to find the first instance, that is the index or location of when the value of max(cor) appears in the index arr(p). "

That would be

mx=max(cor) ; % the maximum and first location in cor array

ixa=find(arr==mx,1); % first place that max is, if it exists, in arr array

Ignoring the 0 indexing issue as the above wouldn't run at all with an error when it tries to reference arr(0) the first pass through the loop so I'll presume have fixed that by starting with p=1; t=1; instead of 0.

Several possible problems with your code above is as Walter pointed out that the loop over q only executes 20 times so if the location of the maximum in cor() is past that location as the comment notes that the array cor is defined outside the loop and you're just storing some new values into first portion of it if it has more than 20 elements, then the failure to find that location would be expected.

Alternatively, it's possible there are no values that satisfy the range condition of 0.85 < arr < 1 in which case cor() will not have been set with anything in this loop and would be whatever is left over from the definition outside the loop or empty if not initialized.

We simply don't have enough information with the partial code snippet to know precisely what is happening with any particular data set.

BUT -- if you use max() to find a value in an array, then find will match that value in another array exactly if that value is obtained by direct transfer from the other array--there will be no floating point rounding in that operation, so there's no need for the comparison with tolerance (for which, if were needed, use ismembertol instead).

So, first of all, need to know if it is intended to only be looking at the first 20 elements of the arr array, and if so, then limit all the code to that portion.

There aren't any loops needed at all here other than the outermost one over a set of files; the rest is done simply with logical or linear indexing operations.

Tawsif Mostafiz
on 5 Jul 2021

@dpb thanks for your answer. I ahve fixed the values of p and t. Using your code,

mx=max(cor) ; % the maximum and first location in cor array

ixa=find(arr==mx,1); % first place that max is, if it exists, in arr array

Shows result or all the inputs except one. I am using the following code to print mx, cor and arr.

for s=1:length(arr)

fprintf("arr is %d\n",arr(s));

end

for v=1:length(cor)

fprintf("cor is %d\n",cor(v));

end

fprintf("maximum is %d ixa is %d\n",mx,ixa);

For giving 8 inputs at once, for 7 inputs, it shows normal output. Let me give you one example.

arr is 1.248978e-01

arr is 1.018090e-01

arr is 1.424247e-01

arr is 1.875205e-01

arr is 1.537038e-01

arr is 2.112862e-01

arr is 1

arr is 9.753829e-01 %first appears in 8th instance.

arr is 9.473528e-01

arr is 9.314605e-01

arr is 9.183571e-01

arr is 8.629645e-01

arr is 8.465781e-01

arr is 7.996246e-01

arr is 7.673663e-01

arr is 7.345215e-01

arr is 3.135270e-01

arr is 3.062124e-01

arr is 2.940971e-01

arr is 1.804656e-01

arr is 1.315477e-01

arr is 1.185888e-01

arr is 1.098524e-01

arr is 8.431171e-02

arr is 8.431171e-02

arr is 8.134353e-02

arr is 8.009365e-02

arr is 7.919035e-02

arr is 7.623680e-02

arr is 7.356673e-02

arr is 7.298326e-02

arr is 7.239559e-02

arr is 6.939037e-02

arr is 6.939037e-02

arr is 6.939037e-02

arr is 6.898077e-02

arr is 6.898077e-02

arr is 6.877514e-02

arr is 6.877514e-02

arr is 6.877514e-02

arr is 6.877514e-02

arr is 6.877514e-02

arr is 6.877514e-02

cor is 9.753829e-01 %max(cor)

cor is 9.473528e-01

cor is 9.314605e-01

cor is 9.183571e-01

cor is 8.629645e-01

maximum is 9.753829e-01 ixa is 8

As you can see, it correctly predicts, maximum, that is max(cor) is the 8th value in arr(p).

All the other bears the same type of output, except input 5.

For input 5, The output is like this:

arr is 8.373341e-02

arr is 2.281927e-01

arr is 2.093401e-02

arr is 1.745628e-02

arr is 2.229341e-01

arr is 6.130643e-02

arr is 6.021532e-02

arr is 2.177850e-02

arr is 5.057797e-02

arr is 3.505052e-02

arr is 5.986454e-02

arr is 1.033150e-01

arr is 1.041290e-01

arr is 7.494588e-02

arr is 1.034880e-01

arr is 1.123892e-01

arr is 9.874080e-02

arr is 1.370517e-01

arr is 1.007373e-01

arr is 1.296451e-01

arr is 1.350760e-01

arr is 1

arr is 1.446095e-01

arr is 8.941384e-01

arr is 8.583505e-01

arr is 9.835071e-02

arr is 3.114828e-01

arr is 3.001147e-01

arr is 2.861069e-01

arr is 2.760516e-01

arr is 2.515372e-01

arr is 1.287723e-01

arr is 1.260997e-01

arr is 1.232662e-01

arr is 1.195805e-01

arr is 1.182329e-01

arr is 1.038775e-01

arr is 1.001578e-01

arr is 9.176201e-02

arr is 8.787075e-02

arr is 6.458028e-02

arr is 6.441344e-02

arr is 6.006245e-02

cor is 8.941384e-01

cor is 8.583505e-01

cor is 9.243360e-01 %this is max(cor)

cor is 9.167294e-01

maximum is 9.243360e-01 ixa is

As you can see ixa shows no values. It is because, maximum or max(cor) is present in cor(the 3rd value of cor), but not in arr(p). Which I don't understand, as cor is the sub set of arr(from the original code), That is:

if(arr(p)<1)

if(arr(p)>0.85)

cor(t)=arr(p);

t=t+1;

end

end

p=p+1;

which means all the elements in cor must be present in arr. Shouldn't it?

dpb
on 5 Jul 2021

Attach the data as a .mat file; it's too cumbersome and hard to read such a large amount of text...

for s=1:length(arr)

fprintf("arr is %d\n",arr(s));

end

you don't need loops in MATLAB; to look at an array at command line just use

>> disp(arr)

0.1249

0.1018

0.1424

0.1875

0.1537

0.2113

>>

or just the variable name itself--

> arr

arr =

0.1249

0.1018

0.1424

0.1875

0.1537

0.2113

>>

The only difference there is whether the variable name is echo'ed first or not.

Only you want a particular formatting other than the default format currently in place in the command window do you need fprintf() or the like and even then there's no need for a loop--

>> fprintf('%0.6f\n',arr)

0.124898

0.101809

0.142425

0.187521

0.153704

0.211286

>>

As for the thing about number of elements, you haven't answered the question of what the length of the input vector arr is that you are wanting to iterate over; your original code had a loop over 20 iterations but that doesn't say anything about what arr size actually is other than it must have had at least 20 elements -- but, as noted, the way your code was written if it were larger, then you would have a potential problem.

Also, the way your initial code was written, the indexing variables p and t were indexed after the conditional was satisfied and so, if you just changed the initial condition on those to be 1 instead of 0 and kept the same code otherwise, then those will end up being one larger than the actual size of the number of elements found. This could be the cause of not finding an element.

Without the actual data and all for a precise case that you think doesn't work, we still don't have sufficient to (easily) debug what's going on.

Easiest would be for you to put together one small test case that is complete in and by itself that illustrates the input and the precise code that you ran and the results that you get and then what you think you should have gotten.

Tawsif Mostafiz
on 5 Jul 2021

@dpb there are 43 arr values, so I changed q=1:43. Sorry for not mentioning that. I am trying to generate a .mat file, but it shows,

Unable to write file data: permission denied.

Instead I am entering a large portion of the code:

clc;

clear all;

% Specify the folder where the files live.

myFolder = 'Given Folder';

% Get a list of all files in the folder with the desired file name pattern.

filePattern = fullfile(myFolder, '*.bmp'); % Change to whatever pattern you need.

theFiles = dir(filePattern);

for k = 1 : length(theFiles)

baseFileName = theFiles(k).name;

fullFileName = fullfile(theFiles(k).folder, baseFileName);

fprintf(1, 'Now reading %s\n', fullFileName);

imageArray = imread(fullFileName);

p=1;

t=1;

for q=1:43

arr(p)=abs(c); %c is derived in original code, thre are 43 values of c.

if(arr(p)<1)

if(arr(p)>0.85)

array(t)=white1;

cor(t)=arr(p);

t=t+1;

end

end

p=p+1;

end %end of q loop

mx=max(cor);

ixa=find(arr==mx,1);

end %end of k loop

Now, for 5th input, or when k=5, if cor and mx is printed, it should look like this:

cor is 8.941384e-01

cor is 8.583505e-01

mx is 8.941384e-01 ixa is 24

As there are only 2 values in arr that is >0.85 and <1.

However, it looks like this:

cor is 8.941384e-01

cor is 8.583505e-01

cor is 9.243360e-01 %this is max(cor)

cor is 9.167294e-01

mx is 9.243360e-01 ixa is

The problem is the last two values of cor aren't even in arr. The mx it derives from the value cor=9.243360e-01 is absent in arr.

Walter Roberson
on 5 Jul 2021

dpb
on 5 Jul 2021

AGAIN, UNLESS WE HAVE THE ACTUAL ARRAY arr DATA, WE CAN'T DEBUG WHAT WE DON'T HAVE ACCESS TO!!!

Attach a .mat file that contains the arr array.

But, the above CANNOT have run as is to produce the given output --

clc;

clear all;

...

for q=1:43

arr(p)=abs(c); %c is derived in original code, thre are 43 values of c.

if(arr(p)<1)

if(arr(p)>0.85)

array(t)=white1;

cor(t)=arr(p);

t=t+1;

end

end

p=p+1;

end %end of q loop

because c is undefined. And, even if it were, then arr(p)=abs(c) would fail on an addressing error if c were a vector of 43 elements because it would try to put the whole array on the RHS into one array element on the LHS and you would get an error about number of elements must match.

Unless and until you produce a working code and the data that goes with it, there's nothing else to be done.

BUT, as I pointed out before, if the point is to just select the elements of arr that are between the two limits then all you need is the code I gave before in place of the double loop construct.

Also, the above does have the problem I outlined above that the t and p variables are incremented after the loop condition is satisfied and so end up as one greater than the number of elements that actually satisfy the condition. This doesn't matter for p but leaves t one too large for cor that contains values from the past loop -- and it is not reinitialized inside the outer loop over the number of files so it does still contain the previous data and will be as large as the largest number of elements found in any file but only have the number found in the current file that match; the rest will be from some previous file.

for q=1:43

arr(p)=abs(c); %c is derived in original code, thre are 43 values of c.

if(arr(p)<1)

if(arr(p)>0.85)

array(t)=white1;

cor(t)=arr(p);

t=t+1;

end

end

p=p+1;

end %end of q loop

should be replaced with

arr=abs(c); % presuming _c_ really is defined somewhere and abs() operation is really wanted

MN=0.85; MX=1; % define the bounds as variables

ix=iswithin(arr,MN,MX); % logical addressing vector of those satisfy conditional

cor=arr(ix); % keep only those wanted

array=repmat(white1,size(cor)); % secondary array of same size of constant???

Then you can find() the max value and location in the reduced array.

The above will eliminate the issue of not reinitializing the array and the counter and is much simpler than the double-loop. logical addressing and vector operations are "the MATLAB way".

iswithin is a utility function

function flg=iswithin(x,lo,hi)

% returns T for values within range of input

% SYNTAX:

% [log] = iswithin(x,lo,hi)

% returns T for x between lo and hi values, exclusive

flg= (x>lo) & (x<hi);

>>

Tawsif Mostafiz
on 6 Jul 2021

@dpb With your suggestion on the previous comment, I have manged to solve the original Problem (maximum of cor not being in arr). Thanks. But a new problem emerged. When run, the following error shows:

Error using ==

Arrays have incompatible sizes for this operation.

Error in Untitled12 (line 263)

ixa=find(arr=

=mx,1);

I have attached the .mat file of the workspace for your consideration. How can I fix it?

dpb
on 6 Jul 2021

What's mx?

It should be the single maximum value you're looking for--if it's a vector, then something is wrong before here.

Tawsif Mostafiz
on 6 Jul 2021

dpb
on 6 Jul 2021

>> load work mx arr

>> whos arr mx

Name Size Bytes Class Attributes

arr 1x41 328 double

mx 0x0 0 double

>> ixa=find(arr==mx,1)

Error using ==

Matrix dimensions must agree.

>>

mx is empty so you haven't solved all the problems of including the case where there may not be any values within the bounds selected.

>> MN=0.85;MX=1;

>> cor=arr((arr>MN) & (arr<(MX)));

>> whos cor

Name Size Bytes Class Attributes

cor 1x0 0 double

>> isempty(cor)

ans =

logical

1

>> ixa=find(arr==mx,1)

Error using ==

Matrix dimensions must agree.

>>

So, == also fails if both are empty.

With the data for this particular sample, there are no values that satisfy the condition; you need to code for that possibility.

That's where a try...catch...end block could be useful

try

ixa=find(arr==mx,1);

catch ME

ixa=0;

end

You'll have to then also ensure you don't try to use the zero-valued index later on, of course....or have some other way of handling the case.

ADDENDUM:

But, at least with the data we can prove what happened...see how easy that was??? :)

### Answers (0)

### See Also

### Categories

### Tags

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.