The "hacky" way is the only way to do it. However, you do not need to check i <= numel(x). The array will be expanded automatically (but without array doubling):
x = zeros(1000,1);
for i = 1:10000
x(i) = rand;
end
x(i+1:end) = [];
EDIT: To keep it simple while still retaining the array doubling, you can write a class, or simply a few helper functions (below).
EDIT2: The usage of helper functions will slow things down compared to the manual hack. In MATLAB 2010 it is still much faster than naive growth. In MATLAB 2011 the naive approach is actually faster, suggesting that this version has smarter allocation. Perhaps it is fast enough so that no hack is needed at all. Thanks to Andrew Janke for pointing this out.
function listtest()
n = 10000;
l = new_list();
for i=1:n
l = list_append(l, i);
end
a = list_to_array(l);
end
function l = new_list()
l = [0 0];
end
function l = list_append(l, e)
if l(1)+1 == length(l)
l(length(l)*2) = 0;
end
l(1) = l(1)+1;
l(l(1)+1) = e;
end
function a = list_to_array(l)
a = l(2:1+l(1));
end
EDIT (from AndrewJanke)
Here's code to compare the speed of the implementations.
function manual_reserve_example(n)
x = zeros(1000,1);
for i = 1:n
if i > numel(x)
x = [x;zeros(size(x))];
end
x(i) = i;
end
x(i+1:end) = [];
end
function naive_growth(n)
x = 0;
for i = 1:n
x(i) = i;
end
end
function compare_them(n)
fprintf('Doing %d elements in Matlab R%s\n', n, version('-release'));
tic;
naive_growth(n);
fprintf('%30s %.6f sec\n', 'naive_growth', toc);
tic;
manual_reserve_example(n);
fprintf('%30s %.6f sec\n', 'manual_reserve', toc);
tic;
listtest(n);
fprintf('%30s %.6f sec\n', 'listtest', toc);
end