How to pre-allocate for unknown size vector?

141 次查看(过去 30 天)
vector = [];
for i = 1:1000000
r = randi([1 4],1,1); % a random integer generator between 1 and 4
vector = [vector 1:r];
end
% 1. How to preallocate 'vector' ?
% 2. And get rid of unassigned variables ?
% 3. Preallocation considering Matlab coder compatability perspective !!
% 4. Can i use 'coder.nullcopy' ?

采纳的回答

Image Analyst
Image Analyst 2018-11-24
Here is one way:
numIterations = 4;
maxLength = 4;
vector = zeros(1, numIterations * maxLength);
lastIndex = 0;
for k = 1: numIterations
r = randi([1 maxLength],1,1); % a random integer generator between 1 and 4
vector(lastIndex+1 : lastIndex + r) = 1 : r;
lastIndex = lastIndex + r;
end
% Crop off unused elements
vector = vector(1:lastIndex)

更多回答(2 个)

John D'Errico
John D'Errico 2018-11-24
编辑:John D'Errico 2018-11-24
There are several simple ways to do this.
  1. Over-allocate the array. r will never be larger than 4. Therefore, the array will never be larger than 4e6 in length. So preallocate r to be of size 1x4e6. Now just index into the array, keeping a running count of where you stuffed the last elements into the array. At the end, just delete the unused elements. I would pre-allocate with NaNs, so you know what was unused.
  2. Preallocate a cell array instead. You know how many passes through the loop. So create a cell array of size 1x1e6. Then stuff one cell at each iteration of the loop. At the end, just collapse the cell array into a flat array using cell2mat.
There are other ways to do this, but those are the easy ways. #2 is by far the better, and simpler, so use it. It will be fairly efficient, and very easy to read and debug. For example...
C = cell(1,1e6);
for i = 1:1000000
r = randi([1 4],1,1); % a random integer generator between 1 and 4
C{i} = 1:r;
end
vector = cell2mat(C);
whos vector
Name Size Bytes Class Attributes
vector 1x2501228 20009824 double
  3 个评论
John D'Errico
John D'Errico 2018-11-25
Then better will be #1 I guess. It requires only that you keep acounter of where you are stuffing new elements into your array, then delete the unused portion of the array at the end. Extra bookkeeping that the cell array solution allows you to avoid.
I would point out that #1 is the solution that Image Analyst posed.

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2020-1-1
Start with an empty vector. Keep track of the number of positions used so far (which will start at 0)
At any point when you need to insert a 1:r, check to see if there are at least r positions remaining in the vector. If there are not at least r positions remaining in the vector, extend the vector by max() of r and (number of iterations remaining times average length of extension (that is, (4+1)/2)) . End if. Now insert the 1:r and increment the count of used values.
At end, trim out any unused locations.
vector = [];
vused = 0;
mrand = 4;
avgrand = (mrand+1)/2;
numIterations = 100000;
for i = 1 : numIterations
Lvec = length(vector);
r = randi(4);
if Lvec-vused < r
extend_to = Lvec + max(r, ceil((numIterations - i)*avgrand));
fprintf('extending to length %d on iteration %d\n', extend_to, i);
vector(extend_to) = 0; %zero fills between current end and here
end
vector(vused+1:vused+r) = 1:r;
vused = vused + r;
end
fprintf('trimming %d entries\n', length(vector)-vused);
vector(vused+1:end) = [];
If you test this, you will see that the number of extensions is quite low, often being only 2 or 3 times.

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

标签

产品


版本

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by