Finding corresponding values in double arrays in structure fields
    14 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
    Giovanni Barbarossa
 le 15 Mai 2019
  
    
    
    
    
    Commenté : Giovanni Barbarossa
 le 17 Mai 2019
            I have two structures in a for loop with i = 1:n
A(i).a
B(i).b
For each loop i, the field a of structure A contains a double array with r(i) rows and 1 column, and the field b of structure B contains a double array with r(i) rows and m columns. In other words, the number of rows of the double array in the field of each structure changes with i and it is the same for both structures and equal to r(i). Also, the number of columns in field a of structure A is fixed and equal to 1, and the number of columns in field b of structure B is fixed and equal to m.
For each loop i, I want to find out the column index for each row of the double array contained in field b of structure B of the element which has a value equal to the value of the element on the same row of the double array contained in field a of structure A. For each loop i, the result should be a double array with 1 column and a number of rows  equal to the number of rows of the double array in each field. I want to store the result in a structure R(i).r. 
I tried the following, but it only works when the number of rows of the double arrays is equal to 1. When the number of rows of the double arrays is >1, I get all kind of wrong numbers!
R(i).r = find(B(i).b(:,:) == A(i).a(:));
Thank you very much!
5 commentaires
  Stephen23
      
      
 le 16 Mai 2019
				Jan,
thanks a lot for your assistance. I have attached the two structures A.a and B.b. If I use the code below
clear;
load AB
for n = 1:81;
R(n).r = find(A(n).a == B(n).b);
end
I get the structure R.r attached. You can note that "the code works" when the double array in B(n).b has only one row. For example, for n = 40, or n = 65 or n = 73. When the double array in B(n).b has more than one row, for example for n = 45 or n = 47 or n = 74, I get some meaningless numbers.
To be clear: "the code works" means that the codes correctly finds the column of the value in the row of the double array in B.b that is equal to the corresponding row value of the double array in A.a.
To be even more clear here is an example. For n = 40, the code does find in which column of the single row double array contained in B(40).b the value A(40).a = 16.8967 is. It does find that it is in column 14.
The code does not work for n = 45, in which case the double array A(45).a has 7 rows and R(45).r = [39;48;49;120;122;142;152] which is meaningless considering that the maximum number of columns of the double array contained in B(45).b is 22.
Thank you!
  Stephen23
      
      
 le 16 Mai 2019
				
      Modifié(e) : Stephen23
      
      
 le 16 Mai 2019
  
			" I get some meaningless numbers."
"which is meaningless considering that the maximum number of columns of the double array..."
They are certainly not meaningless. As its documentation clearly states, with only one output argument find returns the linear indices (not column or row indices as you seem to assume).
"...the value A(40).a = 16.8967..."
Checking for equality of such values is very likely to fail due to floating point error issues. You should be using ismembertol or comparing the absolute difference against a tolerance.
As an aside, what is the point in using structure with just one field? Why not use a simpler container (e.g. a cell array)?
Réponse acceptée
  Stephen23
      
      
 le 16 Mai 2019
        
      Modifié(e) : Stephen23
      
      
 le 16 Mai 2019
  
      Note that these methods assume that there is exactly one match per row. If this is not the case, then there is no way to distinguish how many matches each row has (unless you also store the row indices, or use linear indices, or find the closest values (e.g. min) rather than trying to find matching values, etc.).
Method One: difference and find:
for k = 1:81
    % Difference of floating point numbers:
    mat = bsxfun(@minus,A(k).a,B(k).b);
    idx = abs(mat)<1e-5;
    % Translate & get column&row indices:
    [idc,idr] = find(idx.');
    % Store column indices:
    R(k).r = idc;
end
Checking:
>> A(45).a
ans =
       12.021
       12.355
       12.371
       13.352
        2.696
       13.119
       13.743
>> B(45).b
ans =
  Columns 1 through 10
       2.0648     -0.76368      0.11314       2.3052       2.8992       3.5073       3.7053       6.2226       5.7135       4.8649
       1.1811       1.1602         2.54       5.1009       6.8569       8.9056       8.6338       8.6547        9.052       7.9753
        1.525     -0.49692    -0.068542      0.89102       2.1247       3.1357       3.4955       5.0548       4.8492       4.2495
       3.3975       3.7438       9.1755       11.621       11.361       13.352       12.551       15.494       14.953       13.374
       1.5649       1.7044       3.1453       3.7496       4.2454       4.2144       4.5398       4.7567       3.5637       2.4171
       2.7443       1.2311        3.206       5.9502       6.4119       8.3098       13.119       14.773       18.197       17.504
       1.8486       2.5462       2.4416       5.7551       8.0223       10.952       13.743       11.441       10.185       13.115
  Columns 11 through 20
       5.2326       7.0994       8.2874       10.607       11.116       11.215       11.102       12.021       12.742       12.261
       7.3482       7.6304       6.9928       9.2296       8.7175       9.5746       9.2192       9.8882       10.954       10.902
       3.4955       5.8773        6.854       7.6079       6.4599       9.7841       10.761       12.371       13.451       10.572
       12.854       12.681       15.646       18.697         16.1       16.555       17.875       16.187       13.568       11.296
     0.092961    -0.092963       2.0452       2.4636       1.7663       4.6948       1.7818       4.5863       5.6554       4.0905
       18.851       20.518       21.634       21.211       19.441        21.07       22.262       23.634       25.507       23.788
       13.812       11.615       15.068       18.591       19.114       22.707       21.904       25.044       26.822       25.183
  Columns 21 through 22
       13.067       12.374
       12.355        12.93
       11.618       10.966
       10.863       6.5787
       1.9213        2.696
       26.661       24.481
       24.695       20.893
>> R(45).r
ans =
    18
    21
    18
     6
    22
     7
     7
>>
Method Two: ismembertol and ind2sub:
for k = 45
    % Match floating point values:
    idx = ismembertol(B(k).b,A(k).a);
    % Translate & get column&row indices:
    [idc,idr] = ind2sub(size(B(k).b.'),find(idx.'));
    % Store column indices:
    S(k).r = idc;
end
Checking:
>> S(45).r
ans =
    18
    21
    18
     6
    22
     7
     7
Plus de réponses (0)
Voir également
Catégories
				En savoir plus sur Structures dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!