2015-05-30 27 views
2
A = [-1,-1,0,0,4,1,3,0,1,1; 
    -1,1,1,0,2,1,1,0,0,1; 
    0,0,1,0,1,0,1,0,2,0]; 

B = [3,5; 
    2,6; 
    1,7]; 

期望輸出單元陣列(一列):總結爲每行不同範圍的元素和替換

C = [4,4,4,4,4,4,4,4,4,4;   %// sum of elements 3,4,5 is 4 
    5,5,5,5,5,5,5,5,5,5;  %// sum of elements 2,3,4,5,6 is 5 
    3,3,3,3,3,3,3,3,3,3]; %// sum of elements 1,2,3,4,5,6,7 is 3 

矩陣B包括哪些列應被用於執行矩陣A.例如條件,B的第一行是3和5;因此矩陣A的第3列和第5列之間的元素應該用於執行條件。 B的第二行是2和6;所以第2列第6列之間的元素應該用來執行條件。等等......

條件:總結指定的元素,然後用計算的總和替換相關行的所有元素。例如,A包括0,0,4(總和爲0 + 0 + 4 = 4),所以將4寫入矩陣C第一行的所有元素。

沒有for循環,只能使用矩陣運算,怎麼能我做這個任務?

回答

3

隨着bsxfun

n = size(A,2); 
jj = 1:n; 
C = repmat(sum(A .* (bsxfun(@ge, jj, B(:,1)) & bsxfun(@le, jj, B(:,2))), 2), 1, n); 
+0

它的工作原理,謝謝。 – oarar

4

一種方法基於repelem@colon notation & accumarray -

id = repelem(1:size(B,1),diff(B,[],2)+1) 
extents_cell = arrayfun(@colon, B(:,1), B(:,2), 'Uni', 0) 

rowval = accumarray(id(:),A(sub2ind(size(A),id,[extents_cell{:}]))) 
C = repmat(rowval,1,size(A,2)) 

請注意,repelem僅在MATLAB 2015a支持。所以,如果你沒有訪問到它,你可以使用在this answer列出一個自定義計算id或者像這樣 -

id = repelem_custom(1:size(B,1),diff(B,[],2).'+1) 

自定義功能,以取代repelem會是這個樣子 -

function out = repelem_custom(vals,runlens) 
clens = cumsum(runlens); 
idx = zeros(1,(clens(end))); 
idx([1 clens(1:end-1)+1]) = diff([0 vals]); 
out = cumsum(idx); 
return; 
+1

'arrayfun(@colon,...)'對我來說是新聞!大! –

+0

@LuisMendo燁,終於得到了一些用於這個新事物! :) – Divakar

+0

'arrayfun(@colon,...)'很聰明。 +1。 – rayryeng

2

的另一個變種@ Divakar的arrayfun

我不認爲它會比有效率的,因爲這一個使用匿名函數,而不是內置colon(:)個運營商

唯一值得慶幸的是,它的一個內膽爲樣本輸入

out = repmat(arrayfun(@(x,y,r) sum(A(r,x:y)),B(:,1),B(:,2),(1:size(A,1)).'),1,size(A,2)) 

結果:

out = 

4  4  4  4  4  4  4  4  4  4 
5  5  5  5  5  5  5  5  5  5 
3  3  3  3  3  3  3  3  3  3