2013-07-08 5 views
2

У меня очень большая разреженная матрица в Octave, и я хочу получить дисперсию каждой строки. Если я использую std(A,1); , он падает, потому что память исчерпана. Почему это? Отклонение должно быть очень легко вычислить для разреженной матрицы, не так ли? Как я могу сделать эту работу?Октава: std на разреженной матрице, слишком интенсивной памяти

+0

Да, алгоритм вычисления дисперсий на разреженной матрице может быть довольно простым (в зависимости от в формате), но он должен быть реализован. –

+0

Как это можно эффективно реализовать? Есть ли способ циклически перебирать записи разреженной матрицы? –

ответ

2

Если вы хотите, стандартное отклонение только ненулевых элементов в каждом столбце, то вы можете сделать:

[nrows, ncols] = size(A); 

counts = sum(spones(A),1); 

means = sum(A,1) ./ max(counts, 1); 
[i,j,v] = find(A); 
v = means(j); 
placedmeans = sparse(i,j,v,nrows,ncols); 

vars = sum((A - placedmeans).^2, 1) ./ max(counts, 1); 

stds = sqrt(vars); 

Я не могу представить себе ситуацию, в которой вы хотели бы принять стандартные отклонения всех члены в каждой колонке разреженной матрицы (включая нули), но если да, то вам нужно только подсчитать количество нулей в каждом столбце и включить их в расчетах:

[nrows,ncols] = size(A); 

zerocounts = nrows - sum(spones(A),1); 

means = sum(A,1) ./ nrows; 
[i,j,v] = find(A); 
v = means(j); 
placedmeans = sparse(i,j,v,nrows,ncols); 

vars = (sum((A - placedmeans).^2, 1) + zerocounts .* means.^2) ./ nrows; 

stds = sqrt(vars); 

Кроме того, я не знаю, если вы хотите вычесть один из знаменателя vars (counts и nrows respe ctively).

EDIT: исправлена ​​ошибка, которая восстанавливает помещенную матрицу неправильного размера, когда A заканчивается в строке или столбце всех нулей. Кроме того, первый случай теперь возвращает среднее значение/var/std нуля всякий раз, когда столбец имеет все нули (тогда как раньше он был бы NaN)

+0

Это почти работает, но, похоже, есть ошибка. Мне нужна вторая версия, которая также учитывает нули. К сожалению, он не работает, если в матрице содержится целая строка с нулями в конце. Это дает исключение из измерений в этом случае. Вы знаете, почему это так? –

+0

Хорошо, это был глупый комментарий. Вы не можете принять дисперсию строки, полной нулей. Знаете ли вы, как я мог бы изменить вышеуказанный код, чтобы те, у кого нет записей, получили 0 как дисперсию? –

+0

Вы можете абсолютно принять дисперсию строки, полной нулей. Он равен нулю. (Однако вы не можете принять дисперсию пустого списка, поэтому я изменил первую версию, чтобы дать 0 в этом случае). Однако предоставленный код принимает стандартное отклонение каждого столбца (как и std (A, 1)), а не каждой строки. Кроме того, я сделал редактирование, чтобы исправить ошибку, о которой вы говорили. Теперь он должен работать с любой (непустой) матрицей. – dspyz