how to preallocate a variables

How do I preallocate variable in this code, when they are inside different functions? Thanks
In general it looks like this:
Script:
A=0:1300;
for i=1:10:length(B)
[]=function1()
end
Function1:
B=0:133;
for i=1:length(B)
[]=function2()
end
Function2:
C= xlsread()
D=1:129
for i=1:length(D)
Variables (c)
[]=function3(Variables (c))
end

3 Comments

Each function has its own workspace, so you should try to preallocate inside each function separately. It is hard to give you specific advice because you removed so much of the context and code.
We're going to need more details. In the little snippets of code you show, nothing can be preallocated. Typical case of preallocation is when you assign to an indexed variable inside a loop:
for i = 1:100
A(i) = somefunction; %preallocation of A advised!
end
that is the catch, output variables in the most inner function come out as the output variables of the most outer function, indexes of the variables in different functions is different inside and outside of the functions, according to the eparchy. Preallocating all variables takes space, because they are not deleted after function runs. I hope this is now more understandable:
A=0:1300;
for i=1:10:length(A)
[m,n,c,D,B]=function1(A)
end
Function1:
B=0:133;
for i=1:length(B)
[m,n,c,D]=function2(A,B)
end
Function2:
C= xlsread()
D=1:129
for i=1:length(D)
Variables (c)
[m,n,c]=function3(Variables (A,B,D,c))
end

Sign in to comment.

 Accepted Answer

Again, with the code you show, there's nothing that can be preallocated. But your loops are also not very useful since the overwrite the output variable on each step. So, perhaps your question is not about preallocation but how to keep all the values returned by the loop (where indeed you would use preallocation to make the code more efficient).
In that case, it's simple you need to index the variables you assign to. Depending on the size/shape of the outputs your indexing is going to look different, so again, more details required.
Assuming the outputs are scalar:
steps = 1:10:1301;
%preallocation advised but not required:
m = zeros(1, numel(steps));
n = zeros(1, numel(steps));
c = zeros(1, numel(steps));
D = zeros(1, numel(steps));
B = zeros(1, numel(steps));
%or they can all be preallocated at once with:
[m, n, c, D, B] = deal(zeros(1, numel(steps)));
%looping
for i = steps
[m(i), n(i), c(i), D(i), B(i)] = function1(something);
end

7 Comments

That's a bit too much code without any comment explaining what it does for me to spend time trying to understand.
I'd recommend that when you write functions the first thing you do is write comments that:
  • explain what the function does
  • explain what each input does, what its type should be, and what sizes and shape are expected (scalar, row vector, column vector, matrix, Nd array)
  • explain what the outputs are, their type, size and shape
It looks like your functions return vector or matrices. Are these always the same size for each iteration. If so, is the size of the output known before you call the function?
thanks, i didn't write much description because its not the final version yet, it's slow, so i am pretty much fighting with this. It is a 4D matrix so far, I will go for 5D if speed problem will be solved. Yes, I am able to indicate the size of outputs before calling the functions. I thought maybe problem is, me putting the codes in separate files, but this is as much as my skills go. Thanks again.
i didn't write much description because its not the final version yet,
I would really recommend that you get into the habit that the first thing you write after writing the function line, before writing any line of code, is the function documentation. In particular, a description of the inputs/outputs. Even if it's code in progress. It not only documents the function but actually helps with writing consistent code.
Your code is going to be slow indeed due for the lack of preallocation (as mlint warns you). Looking at the function Ta_I_yearly, you're growing a lot of variables in the loop. Since you say you know the size of the outputs beforehand, let's call it numcolumns. The code should be:
function [days,time,I,Ta,Ir,Id,Gincl,r]=Ta_I_yearly(angle,azim_angle)
%Ta_I_yearly: calculate yearly something
%Inputs:
% angle: the angle of ???? in radian?degree?. Scalar numeric
% azim_angle: the azimutal angle of ??? in radian?degree?. Scalar numeric
%Outputs:
% days: ???. numeric column? row? vector
% time: ???. numeric matrix with ? columns and same number of rows as days
% I
%...
fits_memoized = memoizefun(@Tfits) ;
[days,Tmax,Tmin]= fits_memoized();
%day=days; What's the point of this line?
lat=41.2995;%Latitude Tashkent
numcolumns = ????;
%preallocation:
time = zeros(numel(days), numcolumns);
Ta = zeros(numel(days), numcolumns);
I = zeros(numel(days), numcolumns);
Ir = zeros(numel(days), numcolumns);
Id = zeros(numel(days), numcolumns);
Gincl = zeros(numel(days), numcolumns);
r = zeros(numel(days), numcolumns);
%all these preallocation lines can also be done with the one liner:
[time, Ta, I, Ir, Id, Gincl, r] = deal(zeros(numel(days), numcolumns));
%the loop:
for j=1:numel(days)
[time(:,j), Ta(:,j), I(:,j),Ir(:,j),Id(:,j),Gincl(:,j),r(:,j)]=environment(lat,day(j),angle,azim_angle,Tmin(j),Tmax(j));
end
end
Great, thanks,
as you have understood, the code is only 'environment', other functions let me have ranges for different variables to solve 'environment', so I can compare the influence of pair of different valuables on variable I,Ir, Id and Gincl. So everything starts with script 'Ta_I_yearly_by_azimangle' so can I preallocate variable there or I have to preallocate in each function? or having them preallocated in 'Ta_I_yearly' is enough?
Each time you have a loop that does:
for i = 1:numiters
somevariable(:, :, i) = something; %may have more or less dimensions, doesn't matter
end
You must preallocate somevariable to avoid slow-downs. so:
somevariable = zeros(dim1, dim2, numiters);
for i = 1:numiters
somevariable(:, :, i) = something;
end
In case you're not aware of the reason for the preallocation, if you don't preallocate on the first iteration of the loop, matlab does:
somevariable(:, :, 1) = something;
somevariable doesn't exist, so matlab allocates enough room to fill somevariable, so allocates a dim1 x dim2 x 1 matrix. On the second iteration,
somevariable(:, :, 2) = something;
matlab sees that somevariable exist, and dim1 and dim2 are the correct size, but dim3 only goes up to 1 and now needs to go up to 2. Matlab need more room, so it allocates a new array of size dim1 x dim2 x 2, copy over the content of the previous array in (:, :, 1) and fill (:, :, 2) with the new result.
Rinse and repeat, each step of the loop, matlab needs to create a new array one size bigger than the previous step, copy over all the data from the previous steps and put the data from the current step.
If you tell matlab beforehand the final size of the array, matlab just have to fill the memory you've allocated. It's a lot faster.
I thank you very much for your assistance, but somehow it did not help much, so I opened another question:

Sign in to comment.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Products

Release

R2016a

Community Treasure Hunt

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

Start Hunting!