2016-09-24 2 views
3

У меня есть разреженная матрица в MATLAB:Изменения ненулевых в некоторых столбцах разреженной матрицы

N=1000; 
P=0.01; 
A=sprand(N,N,P); 

и я хочу, чтобы изменить все не нулевые элементы в определенных столбцах в них.

То есть, что-то вроде этого:

c=randi(N,[1,round(N/10)]); 
A(non zeros at columns c)=1; 

Конечно, это можно сделать в цикле, но это явно не решение, которое я ищу. Я пробовал несколько решений с использованием nnz, nonzeros, spfun - но без каких-либо проблем. Может ли кто-нибудь придумать простой способ сделать это?

Спасибо, ELAD

ответ

1

Вы можете сделать это следующим образом:

A(:,c) = abs(sign(A(:,c))); % take the absolute value of the sign for all entries 
          % in the submatrix defined by the columns in c, and 
          % then assign the result back 

Эквивалентное

A(:,c) = logical(A(:,c); 

или

A(:,c) = A(:,c)~=0; 

Это может быть не так быстро, потому что они обрабатывают все записи в этих столбцах, а не только ненулевые записи. Dohyun's approach, вероятно, быстрее.

+1

решение Луиса решает эту проблему. Я думал, что это можно улучшить, используя spfun, чтобы избежать обработки всех записей в столбцах c, но это оказалось неправильным: * абс был удален, так как мои записи всегда положительные N = 1000000; P = 20/N; A = sprand (N, N, P); c = randi (N, [1, N/10]); tic A (:, c) = знак (A (:, c)); Ток 0,260000 секунд. tic A (:, c) = spfun (знак @, A (:, c)); Ток 0.310704 секунд. Разница во времени может показаться не существенной, но она соответствует испытаниям. Учитывая малую долю нулей в столбцах c (20/1e6), интригует, что spfun не намного быстрее. – user2179331

+0

@ user2179331 Другие возможности: 'A (:, c) = logical (A (:, c))' или 'A (:, c) = A (:, c) ~ = 0' –

1

Вы можете попробовать это

N = 1000; 
P = 0.01; 
A = sprand(N,N,P); 

c = unique(randi(N,[1,round(N/10)]))'; % sorted column index 
[r,cind] = find(A(:,c)); 

A(sub2ind([N,N],r,c(cind)))=1;