2013-09-13 2 views
1

В MATLAB имеют большую матрицу с вероятностями перехода transition_probs и матрицу смежности adj_mat. Я хочу, чтобы вычислить кумулятивную сумму переходной матрицы по столбцам, а затем поэлементно умножить его на матрицу смежности, которая действует в качестве маски таким образом:Для больших разреженных матриц в MATLAB вычислите суммарную сумму по столбцам для ненулевых записей?

cumsumTransitionMat = cumsum(transition_probs,2) .* adj_mat; 

я получаю ошибку памяти, потому что с cumsum все элементы матрицы тогда отличны от нуля.

Я хотел бы избежать этой проблемы, только имея совокупные записи сумм, в которых вначале есть ненулевые записи. Как это можно сделать без использования цикла for?

ответ

2

, когда CUMSUM применяется к строкам, для каждой строки он будет идти и заполняться значениями, начиная с первого отличного от нуля столбца, который он обнаруживает до последнего столбца, который он выполняет по определению.

Худший случай с точки зрения хранения - когда разреженная матрица содержит значения в первом столбце, лучший случай - когда все ненулевые значения появляются в последнем столбце. Пример:

% worst case 
>> M = sparse([ones(5,1) zeros(5,4)]); 
>> MM = cumsum(M,2);  % completely dense matrix 
>> nnz(MM) 
ans = 
    25 

% best case 
>> MM = cumsum(fliplr(M),2); 

Если полученная матрица не помещается в памяти, я не вижу, что еще можно сделать, кроме, возможно, использовать для цикла по строкам, и обрабатывать матрицы меньшего размера партии ...

Обратите внимание, что вы не можете применить операцию маскировки до вычисления суммарной суммы, так как это изменит результаты. Поэтому вы не можете сказать cumsum(transition_probs .* adj_mat, 2).

+0

так что это невозможно? вы знаете, что я пытаюсь сделать? Я хочу сделать марковскую матрицу перехода. Таким образом, в строке (состоянии) имеется только определенный набор ненулевых записей, т. Е. Возможные переходы состояний, обозначаемые матрицей смежности 1/0. У меня есть набор вероятностей для этих состояний. Я бросаю случайное число для следующего состояния кандидата и хочу видеть, какие значения столбцов столбца находятся между ними в суммарной сумме. Как еще я могу это сделать? – Vass

+0

ну, похоже, я выполняю операцию подряд за строкой, вычисляя ее каждый раз, когда происходит переход – Vass

+0

да, я думаю, я понял, что должен делать код (в основном вы хотите выбрать следующее состояние в соответствии с вектором весов, соответствующим вероятности перехода текущего состояния, но ограничиваются только соседними состояниями). Вы как бы реализуете ['randsample'] (http://stackoverflow.com/q/2977497/97160). Проблема в том, что когда результат вычисляется по всей матрице за один раз, он слишком плотный, чтобы соответствовать памяти. Вот почему я предложил зацикливать строки по одному вместо векторизованного вызова. Извините, я не мог больше помочь :) – Amro

2

Вы можете применить cumsum только к ненулевым элементам. Вот код:

A = sparse(round(rand(100,1)));  %some sparse data 
A_cum = A;        %instantiate A_cum by copy A 

idx_A = find(A);      %find non-zeros 
A_cum(idx_A) = cumsum(A(idx_A)); %cumsum on non-zeros elements only 

Вы можете проверить вывод с

B = cumsum(A); 


    A_cum B 
    1  1 
    0  1 
    0  1 
    2  2 
    3  3 
    4  4 
    5  5 
    0  5 
    0  5 
    6  6 

и isequal(A_cum(find(A_cum)), B(find(A_cum))) дает 1.

+0

Я не уверен, что это работает. Результаты разные, используя A_cum – Vass

+1

См. Редактирование - результаты идентичны мне: non-zeros Элементы A и их соответствующие B идентичны. Если я не правильно понял ваш комментарий или вопрос. Не могли бы вы уточнить? – marsei

Смежные вопросы