Заданный сегодня вопрос дал неожиданный результат в отношении неявного создания массива:
array1 = 5*rand(496736,1);
array2 = 25*rand(9286,1);
output = zeros(numel(array1), numel(array2)); % Requires 34GB RAM
output = zeros(numel(array1), numel(array2),'logical'); % Requires 4.3GB RAM
output = abs(bsxfun(@minus, array1.', array2)) <= 2; % Requires 34GB RAM
output = pdist2(array1(:), array2(:)) <= 2; % Requires 34GB RAM
Все идет нормально. Массив, содержащий 496736*9286 двойных значений, должен занимать 34 ГБ, а логический массив, содержащий такое же количество элементов, требует всего 4,3 ГБ (в 8 раз меньше). Это происходит для последних двух, потому что они используют промежуточную матрицу, содержащую все пары расстояний с двойной точностью, что требует полных 34 ГБ, тогда как логическая матрица предварительно выделяется напрямую как просто логические и требует 4,3 ГБ.
Удивительная часть начинается здесь:
output = abs(array1.' - array2); % Requires 34GB RAM
output = abs(array1.' - array2) <= 2; % Requires 4.3GB RAM ?!?
Какая?!? Почему неявное расширение не требует тех же 34 Гб оперативной памяти за счет создания промежуточной двойной матрицы output = abs(array1.' - array2)
?
Это особенно странно, поскольку неявное расширение — это, как я понял, короткий способ написания старых bsxfun
решений. Так почему же bsxfun
создает полную 34-гигабайтную матрицу, а неявное расширение — нет?
MATLAB каким-то образом распознает, что результат операции должен быть логической матрицей?
Все тесты проводились на MATLAB R2018b, Ubuntu 18.04, 16 ГБ ОЗУ (т.е. ошибка массивов 34 ГБ)
bsxfun
doc< /a>: По сравнению с использованиемbsxfun
, неявное расширение обеспечивает более высокую скорость выполнения, лучшее использование памяти и улучшенную читабельность кода. Думаю, MathWorks применил волшебство прямо здесь, и, конечно, нет никакой документации. на что. Может быть, теперь нужно предсказывать правильный тип вывода на основе анализа аргументов от внешнего к внутреннему !? Будем надеяться, что некоторые люди, не работающие в MathWorks, могут предоставить дополнительную информацию. - person HansHirse   schedule 16.09.2019d=a+b+c
вычисляется не какtmp=a+b; d=tmp+c
, а какd(i)=a(i)+b(i)+c(i)
? Кто-нибудь может проверить это (например, максимальное использование памяти)? - person Cris Luengo   schedule 16.09.2019output = bsxfun(@(x,y)(abs(x-y)<2),array1.',array2)
. Если вы поместите оператор сравнения внутри анонимной функции, bsxfun должен потреблять меньше памяти. - person obchardon   schedule 16.09.2019x = ones(1e200, 1e300); clear x
работает в кратчайшие сроки? - person Luis Mendo   schedule 16.09.2019