0

I need to compare two vectors of different dimensions via a for loop. One is named energy_a and the other one xminpeaks.

I use Octave 5.2.0 because of university wanting me to use this version.

My goal is to create two vectors names indexmin and indexmax of a length of 28. My problem, my code can't find multiple values and return me two vectors of a length of 20.

One thing important, the code fail to find two identical values on the same values he's looking for when trying to find values for indexmin and indexmax. Another important thing, energy_a is extracted from a csv file with the fopen method.

Here is the code I am running:

% Load data file

fid = fopen("Fluo_spectre_aragonite.csv",'r');
indata = textscan (fid , '%f %f %f %f %f %f %f %f %f %f %f %f %f',
'Delimiter', ';',
'HeaderLines' ,1);
fclose (fid);

energy_a = indata{1, 1};

%define the vectors
xminpeaks=[1.4400, 1.8600, 2.8050, 3.1050, 3.5100, 3.9000, 4.4400, 4.6650, 5.1150, 5.6850, 6.0300, 6.7350, 7.1700, 7.6500, 8.2050, 9.1800, 9.9150, 12.5400, 13.7850, 15.4800, 16.2900, 17.0550, 17.7150, 18.9600, 21.3450, 22.4950, 24.1650, 25.2600];

xmaxpeaks=[1.5750, 2.0400, 3.1050, 3.4050, 3.9000, 4.1100, 4.6650, 5.1150, 5.6850, 6.0300, 6.7350, 7.1700, 7.6500, 8.2050, 9.1800, 9.9150, 10.6800, 12.8400, 14.4600, 16.2900, 17.0550, 17.7150, 18.9600, 21.3450, 22.4950, 24.1650, 25.2600, 25.7400];


indexmin=[];
indexmax=[];

%finding the values
for i = 1:length(xminpeaks)
  index=1;
  for j = 1:length(energy_a) 
    if energy_a(j)== xminpeaks(i)
      indexmin = [indexmin index];
    endif
    if energy_a(j) == xmaxpeaks(i)
      indexmax = [indexmax index];
    endif 
    index+=1;
  endfor
endfor

This should work just fine, it's simple loop but it failed finding values as 2.8050 in each vectors. (I made sure each of the values were with 4 zeros after the comma by the way.)

First thing I thought was "I know computer work specially with float numbers, so I'll try to put them into integers."

So I did this:

xminpeaks=[1.4400, 1.8600, 2.8050, 3.1050, 3.5100, 3.9000, 4.4400, 4.6650, 5.1150, 5.6850, 6.0300, 6.7350, 7.1700, 7.6500, 8.2050, 9.1800, 9.9150, 12.5400, 13.7850, 15.4800, 16.2900, 17.0550, 17.7150, 18.9600, 21.3450, 22.4950, 24.1650, 25.2600];

xmaxpeaks=[1.5750, 2.0400, 3.1050, 3.4050, 3.9000, 4.1100, 4.6650, 5.1150, 5.6850, 6.0300, 6.7350, 7.1700, 7.6500, 8.2050, 9.1800, 9.9150, 10.6800, 12.8400, 14.4600, 16.2900, 17.0550, 17.7150, 18.9600, 21.3450, 22.4950, 24.1650, 25.2600, 25.7400];

xminpeaks10000=[xminpeaks*10000];
xmaxpeaks10000=[xmaxpeaks*10000];
energy_a10000=[energy_a*10000];

indexmin=[];
indexmax=[];

%on cherche les index de chaque intervalles de valeurs englobant les pics
for i = 1:length(xminpeaks)
  index=1;
  for j = 1:length(energy_a)
    if energy_a10000(j)== xminpeaks1000(i)
      indexmin = [indexmin index];
    endif
    if energy_a10000(j) == xmaxpeaks1000(i)
      indexmax = [indexmax index];
    endif 
    index+=1;
  endfor
endfor

So now all my values are integers. But when running it, again it failed and gave me two vectors of length of 21 this time, struggling again on the same values, now integer. For example it failed again on 28050 (=2.8050×10000) but this time it found another value that is 512 (=0.0512×10000).

The thing I can't wrap my head around is the fact that when 512 wasn't found, other values as 549, 614, 838, or 921 could be found, so it shouldn't be a problem linked with the length of the number too.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
Brclsbtn
  • 11
  • 3
  • Multiplying with `10000` doesn't make the numbers integers. See `output_precision(16); xminpeaks10000(7)`. If you really want integers use `round([xminpeaks*10000])` i.e., `round(xminpeaks*10000)` – kikon Nov 27 '22 at 14:41
  • Instead of testing for exact equality, have you tried testing for closeness to within a suitable tolerance, i.e. by writing `abs(energy_a(j) - xminpeaks(i)) < tol` instead of `energy_a(j)== xminpeaks(i)`, where `tol` could be some suitably small number such as, say, `1e-15`? – Howard Rudd Nov 27 '22 at 15:10
  • @kikon Thank you! It perfectly worked, I didn't think about round (octave doesn't show any comma and zeros after the number even if it's still float) – Brclsbtn Nov 28 '22 at 09:59
  • @HowardRudd Thank you for your proposal, I didn't try it because I need to find perfectly equal values, but I'll try it to understand how this works ! – Brclsbtn Nov 28 '22 at 10:01
  • 1
    Please do not add answers to the question body itself. Instead, you should add it as an answer. [Answering your own question is allowed and even encouraged](https://stackoverflow.com/help/self-answer). – Adriaan Nov 28 '22 at 10:10
  • "I didn't try it because I need to find perfectly equal values" -- You need perfectly equal values within the first 4 digits after the comma. Set you tolerance to `0.00001` if you like. This is the correct way to compare floats. Rounding the value x1000 is exactly the same thing. – Cris Luengo Nov 28 '22 at 17:00
  • Does this answer your question? [Why is 24.0000 not equal to 24.0000 in MATLAB?](https://stackoverflow.com/questions/686439/why-is-24-0000-not-equal-to-24-0000-in-matlab) -- this is on MATLAB, but the conclusions are identical. – Cris Luengo Nov 28 '22 at 17:00

0 Answers0