Matrixwise subtraction yields vector - how to reshape to original logical matrix?
    3 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
    Michaela Warnecke
 il 15 Mar 2024
  
    
    
    
    
    Commentato: Dyuman Joshi
      
      
 il 20 Mar 2024
            Hi, 
I am working with a large dataset for which I need to do multiple substractions between vectors, then summing across logically indexed values. Currently, I index the vector subtraction in a for loop, but it takes forever as I have to run that loop ~ 1.5M, several times, so I would like to move to matrixwise calculations.
Below is a short version of the crux of my question. If I have a matrix A and a matrix B, and I index the values I am interested in using a logical matrix (cmpMatrix), then I subtract B from A and want to get the mean per column. However, the logical indexing always reshapes into a vector, not a matrix:
A = rand(3);
B = rand(3);
cmpMatrix = A>=0.5 %in my situation, there are always unequal numbers of 0s and 1s per column
cmpMatrix =
  3×3 logical array
   1   0   1
   0   1   1
   1   0   0
%Issue: ans for the following line is a vector.
A(cmpMatrix)
ans =
    0.9612
    0.7870
    0.9437
    0.9813
    0.5702
I'd like to take the mean of all the values that are indexed per column, so I'd need to be able to backtrack where the values in the vector came from. Ideally, I'd be able to do something like:
mean(A(cmpMatrix) - B(cmpMatrix),2)
And receive a 1 x 3 vector where B was subtracted from A at each logical 1, and then the mean was taken across the matrix columns, so as to get a mean per column.
How do I achieve that? 
Thank you for your help.
0 Commenti
Risposta accettata
  Stephen23
      
      
 il 15 Mar 2024
        A = rand(3);
B = rand(3);
X = A>=0.5;
[~,C] = find(X);
M = accumarray(C,A(X)-B(X),[],@mean).'
7 Commenti
  Voss
      
      
 il 18 Mar 2024
				
      Modificato: Voss
      
      
 il 18 Mar 2024
  
			They're equal up to round-off error:
A = rand(104,8193);
B = rand(104,8193);
max(abs(Stephen(A,B)-Voss(A,B)),[],'all')
function M = Stephen(A,B)
X = A>=0.5;
[~,C] = find(X);
M = accumarray(C,A(X)-B(X),[],@mean).';
end
function M = Dyuman(A,B)
[m,n] = size(A);
Y = repmat(1:n,m,1); % modification for non-square A
X = A>=0.5;
M = accumarray(Y(X),A(X)-B(X),[],@mean).';
end
function result = Walter1(A,B)
cmpMatrix = A>=0.5;
result = arrayfun(@(IDX) mean(A(cmpMatrix(:,IDX),IDX)-B(cmpMatrix(:,IDX),IDX)), 1:size(A,2));
end
function result = Walter2(A,B)
cmpMatrix = A>=0.5;
result = cellfun(@mean, mat2cell(A(cmpMatrix) - B(cmpMatrix), sum(cmpMatrix,1), 1)).'; % removing temp variable, and transposing for consistency with other methods
end
function result = Voss(A,B)
A_temp = A;
B_temp = B;
idx = A >= 0.5;
A_temp(~idx) = NaN;
B_temp(~idx) = NaN;
result = mean(A_temp-B_temp,1,'omitnan');
end
  Dyuman Joshi
      
      
 il 20 Mar 2024
				I know and understand that they are round-off error; my point is why does it only occur in a single method and not in others, when all the methods use the same function (essentially the same operation)?
Più risposte (2)
  Voss
      
      
 il 16 Mar 2024
        A_temp = A;
B_temp = B;
idx = A >= 0.5;
A_temp(~idx) = NaN;
B_temp(~idx) = NaN;
result = mean(A_temp-B_temp,1,'omitnan');
0 Commenti
  Walter Roberson
      
      
 il 15 Mar 2024
        One way:
result = arrayfun(@(IDX) mean(A(cmpMatrix(:,IDX),IDX)-B(cmpMatrix(:,IDX),IDX)), 1:size(A,2))
Chances are that this will be slower than looping.
Another way:
temp = A(cmpMatrix) - B(cmpMatrix);
result = cellfun(@mean, mat2cell(temp, sum(cmpMatrix,1), 1));
It would not surprise me if this is slower than looping.
0 Commenti
Vedere anche
Categorie
				Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






