2010-07-09 3 views
18

Я пытаюсь найти какой-то способ выставить вектор размером 3 из каждого столбца матрицы 3 * (большого числа) в Matlab. Конечно, я мог бы использовать цикл, но я пытаюсь найти более эффективное решение, немного похожее на широковещательное вещание. О, и я не могу использовать repmat, потому что у меня просто недостаточно памяти для его использования (поскольку он создает еще одну матрицу 3 * (большое число)) ...Атрибут Matlab для вещания Numpy?

Возможно ли это?

+1

Как видно из одного из последних ответов, Matlab R2016b, как представляется, добавил вещание в качестве стандартной функции. (https://nickhigham.wordpress.com/2016/09/20/implicit-expansion-matlab-r2016b/) –

ответ

18

Петли не плохо в MATLAB больше благодаря оптимизации компилятора, например just-in-time acceleration (JITA). и т. д. В большинстве случаев я заметил, что решение с петлями в текущих версиях MATLAB: много быстрее, чем сложные (хотя и крутые: D) однострочные.

bsxfun может сделать трюк но в моем опыте, как правило, имеют проблемы с памятью, а также, но в меньшей степени, чем repmat.

Так синтаксис будет:

AA = bsxfun(@minus,A,b) где b вектор и A ваша большая матрица

Но я призываю вас профилировать хитрый вариант, а затем решить! Скорее всего, из-за ограничений памяти у вас может не быть выбора :)

+0

Возможно, вы можете быть прав насчет BSXFUN. У него все еще будут проблемы с памятью, но я считаю, что это обычно * слегка * лучше, чем использование REPMAT. – gnovice

+3

То, что мне нравится в 'bsxfun', - это то, что в версиях 2010a и 2010b он будет многопоточным для вашего кода для повышения производительности без чрезмерного вмешательства с вашей стороны. – JudoWill

+0

@JudoWill: Это здорово! Я искал четкий аргумент против «repmat». У вас есть какая-то документация по этому поводу? – Jacob

4

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

Так может быть

matout = matin; 
for j = 1:size(matin, 1) %3 in this case 
    matout(j,:) = matin(j,:) - vec_to_subtract(j); 
end 

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

+0

Фактически, цикл for находится в большой размерности (поскольку я вычитаю вектор размером-3 из каждого столбец массива размера-3 * (много)), поэтому я боялся цикла for. – antony

+0

Подумайте об этом так: разделите свой массив на 3 вектора размером 1xN. затем вычесть соответствующий скаляр из каждого вектора. Таким образом, цикл for находится вдоль короткого измерения. – Marc

+0

ОК, я вижу это сейчас. Благодарю. – antony

10

Другие ответы немного устарели - Matlab R2016b имеет added broadcasting as a standard feature. Пример из этого сообщения в блоге, который соответствует вопросу:

>> A = ones(2) + [1 5]' 
A = 
    2  2 
    6  6 
+2

Есть и другие * удивительные * новые функции в 2016b, также как и первоклассные строки (https://www.mathworks.com/help/matlab/matlab_prog/create-string-arrays.html), которые вы можете объединить с "+ ». О, я просто саркастически :-) – antony

 Смежные вопросы

  • Нет связанных вопросов^_^