2015-03-08 197 views
0

我有一個矩陣,其行代表音樂筆記。 [A,A#,B,C,C#,D,D#,E,F,F#,G,G#] 因此,索引1表示A,2表示A#等。在矩陣中,該索引中最大的元素越有可能出現在音頻中。Matlab矩陣和向量排序索引

我要計算其中3項指標是最頻繁出現的可能12

之間這是怎麼推斷出來。首先我使用[B,I] = sort()對每列進行排序。 B現在包含排序的列 現在,我包含按升序方式排序的索引。

因此,I [10],I [11]和I [12]現在包含該列中的3個最大索引。

現在我創建一個名爲notes的新矢量。如果一個特定的音符排序後,發現它是我最大的3個索引之一,那麼相應的音符應該增加。

我試圖爲第3列,這是這些:

0.0690 0.0530 0.0656 
0.2453 0.2277 0.2306 
0.0647 0.0315 0.0494 
1.2037 1.1612 1.1613 
0.0772 0.0346 0.0367 
0.1628 0.1429 0.1648 
0.0572 0.0370 0.0493 
0.4119 0.3577 0.3635 
0.0392 0.0430 0.0466 
0.1182 0.0921 0.0935 
0.7473 0.6680 0.7088 
0.0794 0.0527 0.0566 

因此,在B中第一循環迭代我應該得到的,

0.0392 
0.0572 
0.0674 
0.0690 
0.0772 
0.0794 
0.1182 
0.1628 
0.2453 
0.4119 
0.7473 
1.2037 

這我得到(所以到現在一切都好)。 I(其中包含已排序的索引)也正確地返回,其中3個最大索引是8,11,4(即包含最大元素的原始索引,其中8,11,4以升序排列)

問題在if條件之內。在第一次迭代中,在if條件之後,'筆記'列向量應該在第8位,第11位,第4位即增量。

0 
0 
0 
1 
0 
0 
0 
1 
0 
0 
1 
0 

然而,if條件後,只有向量中的第四位正在遞增。在第一次迭代後的事實,顯示「註釋」矢量時,我得到

0 
0 
0 
1 
0 
0 
0 
0 
0 
0 
0 
0 

這是代碼:

for col = 1:3   
    [B,I] = sort(C(:,col), 'ascend'); %B is the sorted column. I is the sorted indexes 
    fprintf('Col No:'); 
    disp(col); 
    fprintf('Sorted Column: '); 
    disp(B); 
    fprintf('Sorted Indexes: '); 
    disp(I); 

    if (I(10) == 1 || I(11) == 1 || I(12) == 1) 
     notes(1,:) = notes(1,:) + 1; 
    elseif (I(10) == 2 || I(11) == 2 || I(12) == 2) 
     notes(2,:) = notes(2,:) + 1; 
    elseif (I(10) == 3 || I(11) == 3 || I(12) == 3) 
     notes(3,:) = notes(3,:) + 1; 
    elseif (I(10) == 4 || I(11) == 4 || I(12) == 4) 
     notes(4,:) = notes(4,:) + 1; 
    elseif (I(10) == 5 || I(11) == 5 || I(12) == 5) 
     notes(5,:) = notes(5,:) + 1; 
    elseif (I(10) == 6 || I(11) == 6 || I(12) == 6) 
     notes(6,:) = notes(6,:) + 1; 
    elseif (I(10) == 7 || I(11) == 7 || I(12) == 7) 
     notes(7,:) = notes(7,:) + 1; 
    elseif (I(10) == 8 || I(11) == 8 || I(12) == 8) 
     notes(8,:) = notes(8,:) + 1; 
    elseif (I(10) == 9 || I(11) == 9 || I(12) == 9) 
     notes(9,:) = notes(9,:) + 1; 
    elseif (I(10) == 10 || I(11) == 10 || I(12) == 10) 
     notes(10,:) = notes(10,:) + 1; 
    elseif (I(10) == 11 || I(11) == 11 || I(12) == 11) 
     notes(11,:) = notes(11,:) + 1; 
    elseif (I(10) == 12 || I(11) == 12 || I(12) == 12) 
     notes(12,:) = notes(12,:) + 1; 

    end 

    disp(notes); 

我在做什麼錯?代碼可能是錯誤的(或者可能會更好)。我不擅長Matlab。這是第一次使用它。

希望你的想法,意見,更正。

感謝您提前預約

回答

2

您似乎在過份譴責這個問題。你可以做的是使用sort並單獨將排序應用到每列。 sort函數使用第二個參數來告訴你要應用排序的維度。由於您想對列進行排序,因此需要將第二個參數設置爲1,這意味着您要對每列的行進行排序。

因此,定義你的 「筆記」 C矩陣:

C = [0.0690 0.0530 0.0656 
0.2453 0.2277 0.2306 
0.0647 0.0315 0.0494 
1.2037 1.1612 1.1613 
0.0772 0.0346 0.0367 
0.1628 0.1429 0.1648 
0.0572 0.0370 0.0493 
0.4119 0.3577 0.3635 
0.0392 0.0430 0.0466 
0.1182 0.0921 0.0935 
0.7473 0.6680 0.7088 
0.0794 0.0527 0.0566]; 

你可以簡單地這樣做:

[~,I] = sort(C, 1, 'descend') 

'descend'標誌排序在值下降秩序。因此,I將是一個矩陣其中每列告訴你每個排序值的位置將出現在每列的位置。因此,您只需獲得I的前三行。

這樣,如果我們顯示I前三行,我們得到:

>> disp(I(1:3,:)) 

4  4  4 
11 11 11 
8  8  8 

這是有意義的,因爲對於每一列,我們發現在位置4,分別爲11和8中的最高值。

現在,如果您想統計在上述矩陣中看到的那些頭寸,您可以非常簡單地使用histcaccumarray

因此:

ind = I(1:3,:); %// Get the first three rows of the sorted indices 
notes = histc(ind(:), 1:12); %// or 
%notes = accumarray(ind(:), 1, [12 1]); 

因此,對於notes我們得到:

notes = 

    0 
    0 
    0 
    3 
    0 
    0 
    0 
    3 
    0 
    0 
    3 
    0 

因此,我們看到指數4,8和11爲每一列,所以我們應該增加這些職位每次1。 histc會計算出現事件的頻率,因此我們可以自然使用它並計算出我們看到4,8和11的次數,或者我們在前三行I中看到的任何數量。 accumarray也做同樣的事情,但accumarray是一個更一般的功能,不僅僅是把相同的箱子裏的東西加在一起。 histc是更好的方式去處理你的情況 - 尤其是因爲垃圾箱數量不變。


作爲本文的一個編輯,在您的評論中的下方,您表示您希望能夠將這個應用於18個分欄。最好的事情可能是在某種循環中做到這一點。首先找出我們有18列的多少部分,然後將其放入循環中多次並更新結果。在循環的每次迭代中,我們需要在矩陣中取出右邊的18列,並保持18的塊,直到達到數組的末尾。

我們希望把我們的研究結果在另一矩陣,其中每列是每18柱段三個最頻繁出現的音符的結果。

事情是這樣的:

numColumns = size(C, 2); %// Get total number of columns for matrix 
numSegments = ceil(numColumns/18); %// Get total number of segments 

finalMatrix = zeros(12, numSegments); 
for idx = 1 : numSegments 

    %// Make sure that when we get 18 chunks, we don't out of bounds 
    if 18*idx > numColumns 
     seg = C(:,(idx-1)*18 + 1 : end); 
    else 
     seg = C(:,(idx-1)*18 + 1 : 18*idx); 
    end 

    [~,I] = sort(seg, 1, 'descend'); 
    ind = I(1:3,:); %// Get the first three rows of the sorted indices 
    notes = histc(ind(:), 1:12); 

    %// Your code 
    [~,y] = sort(notes, 'descend'); 
    finalvec = zeros(12,1); 
    finalvec(y(1)) = 1; finalvec(y(2)) = 1; finalvec(y(3)) = 1; 

    %// Place in final matrix 
    finalMatrix(:, idx) = finalvec; 
end 

finalMatrix將每18片段的結果存儲到一個列,其中每列是你在你的評論中寫道邏輯。

+0

哇,謝謝!很好解釋。現在要創建一個具有3個最高發生音符的矢量我做了這樣的事情: finalvec = zeros(12,1); [x,y] = sort(notes,'descend'); finalvec(y(1))= 1; finalvec(y(2))= 1; finalvec(y(3))= 1; disp(finalvec); 這是足夠的嗎? – 2015-03-09 00:06:47

+0

是的,我看起來很好! – rayryeng 2015-03-09 00:08:32

+0

順便說一句,如果我幫忙,考慮接受我的答案。祝你好運! – rayryeng 2015-03-09 00:08:53