Эффективная память для замены сетки - PullRequest
1 голос
/ 24 июня 2019

Допустим простой пример, где у меня есть индексы

index_pos = [3,4,5];
index_neg = [1,2];

Я бы хотел иметь матрицу:

result =

     1     3
     2     3
     1     4
     2     4
     1     5
     2     5

Для этого пишу следующий код:

[X,Y] = meshgrid(index_pos,index_neg);
result = [Y(:) X(:)];

Я думаю, что это не очень эффективный способ. Кроме того, это использует слишком много моей памяти, когда я использую большие экземпляры. Я получаю следующую ошибку:

Error using repmat
Out of memory. Type "help memory" for your options.

Error in meshgrid (line 58)
        xx = repmat(xrow,size(ycol));

Error in FME_funct (line 36)
[X,Y] = meshgrid(index_pos,index_neg);

Есть ли какой-нибудь "умный" способ генерирования этой матрицы, используя меньше памяти?

PS: я заметил, что то, что я делаю, также дано здесь . Скорее всего, я нашел эту идею оттуда.

Ответы [ 2 ]

3 голосов
/ 24 июня 2019

Это полностью зависит от того, насколько велики ваши две переменные по отношению к объему памяти на вашем компьютере (плюс типы чисел, которые вы используете). Попробуйте это:

res = zeros(numel(index_neg)*numel(index_pos), 2)

Если это приводит к ошибке нехватки памяти, значит, на вашем компьютере недостаточно памяти для сохранения результата, независимо от эффективности генератора, поэтому, если вышеописанные ошибки, то вы застряли. Если это не ошибка, тогда вы могли бы написать алгоритм зацикливания, который использует меньше временной памяти.

Тем не менее, по умолчанию MATLAB представляет числа с двойной точностью, 8 байтов на число. Если ваши index_ переменные содержат, скажем, только положительные целые числа (все меньше чем 65 536), то вы можете использовать 16-разрядные целые числа без знака. Это всего 2 байта на число, поэтому они занимают в 4 раза меньше места, чем удваиваются. Вы можете проверить это с помощью:

res = zeros(numel(index_neg)*numel(index_pos), 2, 'uint16')

Наконец, вы можете узнать, сколько памяти доступно для MATLAB с помощью команды memory.

0 голосов
/ 24 июня 2019

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

res2 = [ reshape( bsxfun( @times , index_neg.' , ones(size(index_pos)) ) , [] , 1 ) , ...
         reshape( bsxfun( @times , index_pos , ones(size(index_neg)).' ) , [] , 1 ) ] ;

Обратите внимание, что для хранения основного массива требуется одинаковый объем памяти, поэтому не позволит генерировать массивы большего размера.чем с вашим методом (что не на этапе meshgrid).Этот максимальный размер в конечном итоге определяется объемом оперативной памяти, доступной вашей системе.

...