Совместная энтропия аудиофайлов

Итак, попробовав тяжелую циклическую функцию для вычисления совместной энтропии двух источников информации, я нашел эту полезную функцию MATLAB, accumarray, и попробовал следующий код:

function e = jointEntropy(fonte1, fonte2)
    i = double(fonte1(:))+ 1; 
    j = double(fonte2(:)) + 1; 

    subs = [i j];
    f = accumarray(subs, ones(length(fonte1), 1));
    p = f / length(fonte1);
    freq = f ~= 0;
    prob = p(freq);
    e = -sum(prob.*log2(prob));
end

, где fonte1 и fonte2 источники информации, 1xN массивы. Это отлично работало с примерами, в которых оба источника имели только положительные целые значения, но затем я попытался использовать его с аудиофайлами (то есть массивами, значения которых варьировались от -1 до 1), и это продолжало выдавать мне ошибку. Я пробовал добавлять 1 к каждому массиву (в диапазоне от 0 до 2), умножая их на 100 и округляя числа, чтобы получить неотрицательные целые числа, но это все равно не работает.

Любая идея/альтернатива этому коду будет принята с благодарностью.


person M. M. F.    schedule 22.10.2014    source источник
comment
В чем ошибка? Также, пожалуйста, покажите код, который вы упомянули, где вы повторно масштабируете и округляете входные данные. В качестве предложения вы можете сделать e = -sum(sum(p.*full(spfun(@log2,p)))); или e = -sum(sum(p.*(log2(p+(p==0)))));. Посмотрите, что быстрее.   -  person chappjc    schedule 23.10.2014
comment
Хороший первый выстрел, кстати! Кроме того, с accumarray вы можете просто выполнить accumarray(subs,1), и он будет использовать 1 для каждого сабвуфера.   -  person chappjc    schedule 23.10.2014
comment
Хм :) Похоже, вы позаимствовали этот код отсюда: stackoverflow.com/questions/23691398/ :) Было бы неплохо, если бы в следующий раз вы действительно нашли источник кода. Теперь, чтобы ответить на ваш вопрос, вы все еще можете использовать этот код, но вместо этого рассмотрите возможность назначения уникального идентификатора каждому числу с плавающей запятой. Поэтому сделайте это, чтобы заменить subs: [~,~,id1] = unique(fonte1(:)); [~,~,id2] = unique(fonte2(:)); subs = [id1 id2];. Я также должен обновить свой пост, чтобы отразить это. Спасибо за идею!   -  person rayryeng    schedule 02.01.2015
comment
@rayryeng Неудивительно, что это был хороший первый выстрел. :)   -  person chappjc    schedule 02.01.2015
comment
@chappjc - Хе-хе :) Кстати, пасхальное яйцо в этом посте... когда я упомянул accumarray, я поблагодарил вас в скобках. Я бы не научился эффективно его использовать, если бы не ты... так что я действительно должен благодарить тебя!   -  person rayryeng    schedule 02.01.2015
comment
@rayryeng Ну, спасибо за это! Но, читая эту часть вашего поста, я улавливаю предположение, что я, возможно, немного одержим accumarray... виновным в предъявленном обвинении! :D   -  person chappjc    schedule 02.01.2015
comment
@chappjc - хе-хе... ну, в твоем профиле написано, что ты ‹3 accumarray... Я тоже пытаюсь поделиться любовью ;)   -  person rayryeng    schedule 02.01.2015