Пересечение нуля возвращает высокие значения

У меня есть 2D-массив, содержащий блоки данных, и я создал функцию, которая вычисляет, сколько раз каждое значение пересекает ноль.

Я использую MatLab и пытаюсь преобразовать код, и MatLab возвращает 287 значений для пересечения нуля, а в коде 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;
}

3

Решение

Интенсивное использование цикла for в Matlab традиционно было плохой идеей, так как JIT-компилятор Matlab не очень (или не очень) не очень быстрый (по крайней мере, по сравнению с нативным кодом 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
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]