Octave/Matlab: добавление новых элементов в вектор

Имея вектор x, и я должен добавить элемент (newElem).

Есть ли разница между -

x(end+1) = newElem; 

и

x = [x newElem];

?

Ответ 1

x(end+1) = newElem является более надежным.

x = [x newElem] будет работать, только если x является вектором строки, если он является вектором столбца x = [x; newElem]. x(end+1) = newElem, однако, работает как для векторов строк, так и для столбцов.

В целом, однако, следует избегать роста векторов. Если вы сделаете это много, это может привести к тому, что ваш код будет сканироваться. Подумайте об этом: наращивание массива предполагает выделение нового пространства, копирование всего, добавление нового элемента и очистку старого беспорядка... Довольно пустая трата времени, если вы заранее знали правильный размер.

Ответ 2

Чтобы добавить к ответу @ThijsW, для первого метода по методу конкатенации существует значительное преимущество в скорости:

big = 1e5;
tic;
x = rand(big,1);
toc

x = zeros(big,1);
tic;
for ii = 1:big
    x(ii) = rand;
end
toc

x = []; 
tic; 
for ii = 1:big
    x(end+1) = rand; 
end; 
toc 

x = []; 
tic; 
for ii = 1:big
    x = [x rand]; 
end; 
toc

   Elapsed time is 0.004611 seconds.
   Elapsed time is 0.016448 seconds.
   Elapsed time is 0.034107 seconds.
   Elapsed time is 12.341434 seconds.

Я получил эти времена в 2012 году, но когда я запустил тот же код на том же компьютере в matlab 2010a, я получил

Elapsed time is 0.003044 seconds.
Elapsed time is 0.009947 seconds.
Elapsed time is 12.013875 seconds.
Elapsed time is 12.165593 seconds.

Итак, я думаю, что преимущество в скорости распространяется только на более поздние версии Matlab

Ответ 3

Как упоминалось ранее, использование x(end+1) = newElem имеет то преимущество, что позволяет конкатенировать вектор с помощью скаляра, независимо от того, транспонирован ли ваш вектор или нет. Поэтому он более надежный для добавления скаляров.

Однако не следует забывать, что x = [x newElem] также будет работать, когда вы попытаетесь добавить сразу несколько элементов. Более того, это более естественно объясняет случай, когда вы хотите объединить матрицы. M = [M M1 M2 M3]


В общем, если вам нужно решение, которое позволит вам конкатенировать существующий вектор x с newElem, который может быть или не быть скаляром, это должно сделать трюк:

 x(end+(1:numel(newElem)))=newElem