How to pre-allocate for unknown size vector?

159 ビュー (過去 30 日間)
JAI PRAKASH
JAI PRAKASH 2018 年 11 月 24 日
回答済み: Walter Roberson 2020 年 1 月 1 日
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' ?
  1 件のコメント
Raymond MacNeil
Raymond MacNeil 2020 年 1 月 1 日
Good question!

サインインしてコメントする。

採用された回答

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.
JAI PRAKASH
JAI PRAKASH 2018 年 11 月 25 日
OK thank you very much

サインインしてコメントする。


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 Center および File ExchangeLogical についてさらに検索

タグ

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by