Проблемы со скоростью памяти при разборе графика в Matlab - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть следующая проблема со скоростью памяти в Matlab, и я хотел бы, чтобы ваша помощь поняла, может ли быть решение.

Рассмотрим следующие 4 векторы больших столбцов X1, X2, Y1, Y2.

clear 
rng default
P=10^8;
X1=rand(1,P)*5;
X2=rand(1,P)*5;
Y1=rand(1,P)*5;
Y2=rand(1,P)*5;

То, что я хотел бы сделать, - это график рассеяния, где на оси X у меня есть сумма между любыми двумя возможными элементами X1 и X2, а на оси Y у меня есть сумма между любыми возможными двумя элементы Y1 и Y2.

Я публикую здесь три варианта, которые, как я думал, не работают, главным образом из-за проблем с памятью и скоростью.

Опция 1 (проблемы: слишком медленно при выполнении цикла, не хватает памяти при выполнении vertcat)

Xtemp=cell(P,1);
Ytemp=cell(P,1);
for i=1:P
    tic
    Xtemp{i}=X1(i)+X2(:);
    Ytemp{i}=Y1(i)+Y2(:);
    toc
end
X=vertcat(Xtemp{:}); 
Y=vertcat(Ytemp{:});
scatter(X,Y)

Опция 2 (проблемы: слишком медленно при выполнении цикла, время увеличивается по мере выполнения цикла, Matlab сходит с ума и не может произвести разброс, даже если я останавливаю цикл после 5 итераций)

for i=1:P
    tic
    scatter(X1(i)+X2(:), Y1(i)+Y2(:))
    hold on 
    toc
end

Вариант 3 (что-то вроде отказа) (выдает: при увеличении T разброс становится все ближе и ближе к квадрату, который является правильным; хотя мне интересно, вызвано ли это фактом что я сгенерировал данные с использованием rand, а в варианте 3 я использую randi, возможно, с моими реальными данными разброс не «сходится» к истинному графику при увеличении T, а также, что является «оптимальным» T и R?).

T=20;
R=500;
for t=1:T
    tic
    %select R points at random from X1,X2,Y1,Y2 
    X1sel=(X1(randi(R,R,1)));
    X2sel=(X2(randi(R,R,1)));
    Y1sel=(Y1(randi(R,R,1)));
    Y2sel=(Y2(randi(R,R,1)));
    %do option 1 among those points and plot
    Xtempsel=cell(R,1);
    Ytempsel=cell(R,1);
    for r=1:R
        Xtempsel{r}=X1sel(r)+X2sel(:);
        Ytempsel{r}=Y1sel(r)+Y2sel(:);
    end
    Xsel=vertcat(Xtempsel{:}); 
    Ysel=vertcat(Ytempsel{:});
    scatter(Xsel,Ysel, 'b', 'filled')
    hold on
    toc
end

Есть ли способ сделать то, что я хочу, или просто невозможно?

1 Ответ

0 голосов
/ 08 ноября 2018

Вы пытаетесь построить вектор с P ^ 2 элементами, т.е. 10 ^ 16. Это на порядок больше, чем то, что уместилось бы в памяти стандартного компьютера (10 ГБ - это 10 ^ 10 байт или 1,2 миллиарда операций с двойной точностью).

Для меньших векторов (т.е. P <1e4) попробуйте: </p>

Xsum=bsxfun(@plus,X1,X2.'); %Matrix with the sum of any two elements from X1 and X2
X=X(:);                     %Reshape to vector
Ysum=bsxfun(@plus,Y1,Y2.');
Y=Y(:);
plot(X,Y,'.') %Plot as small dots, likely to take forever if there are too many points

Чтобы построить фигуру с более разумным количеством пар, случайно выбранных из этих больших векторов:

Npick=1e4;
sel1=randi(P,[Npick,1]);
sel2=randi(P,[Npick,1]);
Xsel=X1(sel1)+X2(sel2);
Ysel=Y1(sel1)+Y2(sel2);
plot(Xsel,Ysel,'.');     %Plot as small dots
...