2012-11-14 92 views
3

我有一個包含數據塊的二維數組,我創建了一個函數來計算每個數值跨過零的次數。零交叉返回高值

我正在使用MatLab並試圖轉換代碼,並且MatLab返回過零值和C++代碼中的值,這些值非常高,我似乎無法弄清楚原因。

這裏是Matlab代碼:

function f = zerocross(vector) 

% This function simply reports the number of times 
% that the input vector crosses the zero boundary 

len = length(vector); 
currsum = 0; 
prevsign = 0; 

for i = 1:len 
currsign = sign(vector(i)); 
if (currsign * prevsign) == -1 
    currsum = currsum + 1; 
end 
if currsign ~= 0 
    prevsign = currsign; 
end 
end 

f = currsum; 

而我的C++代碼:

vector<iniMatrix> Audio::filter(vector<iniMatrix>&blocks, double sumThres, double ZeroThres) 
{ 
double totalSum = this->width * sumThres; 
double totalZero = this->width * ZeroThres; 

int currZero = 0; 
int currsum = 0; 

int prevsign = 0; 


for(unsigned i=0; (i < 287); i++) 
{ 
    for(int j=0; (j < blocks.size()); j++) 
    { 
     currZero = sign<double>(blocks[j][i]); 

     if(currZero * prevsign == -1) 
     { 
      currsum++; 
     } 

     if(currZero != 0) 
     { 
      prevsign = currZero; 
     } 
    } 
    cout << currsum << endl; 
} 

return blocks; 

登錄功能:

int sign(T n) 
{ 
    if(n < 0) return -1; 
    if(n > 0) return 1; 
    return n; 
} 

,我應該(和MATLAB給予)的值:

6,6,7 9,9,10 ...,11,...,9,...

,我得到的值:

212,337,118,84,....,348。 ..,92

任何人有什麼想法?

編輯:

這是我有我現在的循環:

for(int q=0; (q < 287); q++) 
{ 
    for(unsigned i=0; (i < blocks.size()); i++) 
    { 
     for(unsigned j=0; (j < blocks[0].size()); j++) 
     { 
      currZero = sign<double>(blocks[i][j]); 
      cout << currZero << endl; 
     } 
     cout << endl << endl << endl; 

    } 
    //cout << currZero << endl; 
} 
+0

什麼iniMatrix? –

+0

@RamiJarrar iniMatrix是一個二維矢量typedef ..好吧,所以看起來如果我輸出「currZero」,那麼它只是顯示每個塊相同的值,這是錯誤的 – Phorce

+1

您是否有意爲每個塊執行檢查(「行「),一次一個?如果是這樣,那麼你應該交換內部和外部循環的順序。你的循環以更多的以列爲中心的順序遍歷矩陣 - 你會碰到'blocks [0] [0],blocks [1] [0],...,blocks [n] [0],blocks [1] [0],塊[1] [1]等等。換句話說,您要比較每個塊的第i個元素,而不是比較每個塊內的元素。 – atkretsch

回答

0

在Matlab的循環的傳統,通常是一個壞主意,因爲Matlab的JIT編譯器不重使用(或不是)非常快(至少與本機C代碼相比)。我猜你寫的C++代碼,以加快計算,但也許另一種是寫代碼的Matlab方式「:

vector = rand(1e7,1)-0.1; 
zero_crossings = sum(diff(array<0)~=0); 

雖然我只是在Matlab的2015B測試,在量化代碼只有約快兩倍:

function test() 

    function currsum = zerocross(vector) 

     % This function simply reports the number of times 
     % that the input vector crosses the zero boundary 

     len = length(vector); 
     currsum = 0; 
     prevsign = 0; 

     for i = 1:len 
      currsign = sign(vector(i)); 
      if (currsign * prevsign) == -1 
       currsum = currsum + 1; 
      end 
      if currsign ~= 0 
       prevsign = currsign; 
      end 
     end 
    end 

    function f = zerocross_vectorized(array) 
     f = sum(diff(array<0)~=0); 
    end 

    array = rand(1e5,1e3)-0.1; 

    % test for loop 
    t = tic; 
    crossings = nan(1,size(array,2)); 
    for column = 1:size(array,2) 
     vector = array(:,column); 
     crossings(column) = zerocross(vector); 
    end 
    disp(crossings(1:5)) 
    fprintf(1,'For loop: Calculated in %0.4f seconds\n',toc(t)); 

    % test vectorized 
    t = tic; 
    crossings = zerocross_vectorized(array); 
    disp(crossings(1:5)) 
    fprintf(1,'Vectorized: Calculated in %0.4f seconds\n',toc(t)); 

end 

導致:

>> zerocross 
     18208  17884  17902  17734  17988 

For loop: Calculated in 1.7186 seconds 
     18208  17884  17902  17734  17988 

Vectorized: Calculated in 0.9695 seconds