Реляционные операторы между большими разреженными матрицами в Matlab - PullRequest
0 голосов
/ 04 октября 2018

У меня есть две большие разреженные двойные матрицы в Matlab:

  • P с размером 1048576 x 524288

  • I с размером1048576 x 524288

Я хочу найти количество входов i,j такое, чтобы P(i,j)<=I(i,j)

Наивно я пытался запустить

 n=sum(sum(P<=I));

но это очень медленно (мне пришлось отключить Matlab, потому что он работал вечно, и я не смог его остановить).

Есть ли другой, более эффективный способ продолжить или то, что я хочу сделать, неосуществимо?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Вот решение с использованием индексов ненулевых элементов:

xp = find(P);
xi = find(I);
vp = nonzeros(P);
vi = nonzeros(I);
[s,ia,ib] = intersect(xp,xi);

iia = true(numel(vp),1);
iia(ia)=false;
iib = true(numel(vi),1);
iib(ib) = false;
n = sum(vp(ia) <= vi(ib))+sum(vp(iia)<0)+sum(vi(iib)>0)-(numel(xp)+numel(xi)-numel(s))+numel(P);
0 голосов
/ 04 октября 2018

Из некоторых простых тестов

n = numel(P) - nnz(P>I);

кажется быстрее, чем sum(sum(P<=I)) или даже nnz(P<=I).Причина, вероятно, в том, что разреженная матрица P<=I имеет намного больше ненулевых записей, чем P>I, и, следовательно, требует больше памяти.

Пример:

>> P = sprand(10485, 52420, 1e-3);
>> I = sprand(10485, 52420, 1e-3);
>> tic, disp(sum(sum(P<=I))); toc
   (1,1)      549074582
Elapsed time is 3.529121 seconds.
>> tic, disp(nnz(P<=I)); toc
   549074582
Elapsed time is 3.538129 seconds.
>> tic, disp(nnz(P<=I)); toc
   549074582
Elapsed time is 3.499927 seconds.
>> tic, disp(numel(P) - nnz(P>I)); toc
   549074582
Elapsed time is 0.010624 seconds.

Конечно, это сильно зависит отразмеры матрицы и плотность.

...