426 views (last 30 days)

MathWorks Support Team
on 21 Jan 2010

If the matrix size is not defined prior to populating it with data through a FOR loop, memory fragmentation problems may happen since MATLAB is not aware of the final matrix size upon the conclusion of the FOR loop. For example, look at the following FOR loop:

for i=1:10

x(i)=i;

end

When this FOR loop is executed, MATLAB looks at the i=1, requests enough memory from the operating system to create a 1 x 1 matrix, and creates x(1)=1. When i=2, MATLAB requests more memory so a 1 x 2 matrix can be stored. If this additional memory is in the same continuous memory strip as when x(1)=1, MATLAB will simply add the additional number in the same memory strip. If the original memory strip is only big enough for a 1x1 matrix, MATLAB moves the x(1)=1 and places it into a memory spot that is large enough for the 1x2 matrix. Since the matrix is now 1x2, the original memory slot is useless to MATLAB for any matrix larger than 1x1. This memory is now fragmented, and this would cause significant problems with large FOR loops.

In order to work around this issue, you should pre-allocate memory by creating an initial matrix of zeros with the final size of the matrix being populated in the FOR loop. For example, if you create a large matrix by typing a = zeros(1000), MATLAB will reserve enough contiguous space in memory for the matrix 'a' with size 1000x1000. This way, instead of looking for a new block of contiguous free space in memory every time 'a' grows larger than the block that holds it, MATLAB will now only change the values in the pre-allocated memory space for the matrix 'a'. Following is an example on how to pre-allocate memory before entering a FOR loop:

x=zeros(30);

for i=1:30,

for j=1:30

x(i,j)=i+j;

end

end

The above creates x which is a 30x30 matrix. This gives MATLAB a memory block large enough so it doesn't have to keep asking for fragmented memory. This method reduces the chance of receiving "Out of Memory" errors due to fragmentation. It also improves the performance of the program, as shown in the following code:

Running the following code where memory is NOT pre-allocated:

tic;

for i=1:1000,

for j=1:1000,

x(i,j)=i+j;

end

end

toc

returns:

Elapsed time is 12.175349 seconds.

On the other hand, pre-allocating the memory ahead of time

tic;

x=zeros(1000);

for i=1:1000,

for j=1:1000,

x(i,j)=i+j;

end

end

toc

returns:

Elapsed time is 1.761482 seconds.

For pre-allocating memory for a cell array, you may use the following command:

c = cell(m, n, p,...)

It creates an m-by-n-by-p-... cell array of empty matrices. Arguments m, n, p,... must be scalars.

It should be noted that preallocating memory does not make sense if you do not know the eventual size of the matrix you wish to create. This is because one of two cases are likely to occur. Either the preallocated memory will either be too large, resulting in wasted memory; or the allotted memory will be too small for the matrix you are trying to create, resulting in the need to allocate more memory and copy matrix elements to the new space. The latter case will cause you to be just as vulnerable to the memory fragmentation problems you are trying to avoid by preallocating memory.

David Manuel Buitrago Montañez
on 19 May 2016

Edited: David Manuel Buitrago Montañez
on 19 May 2016

Hello, i'm following your advice, but the warning remains

y = zeros(d,2); % preallocating

for i = 1:nargs

y = varargin{i};

if length(y)<d

% llenando los vectores de ceros hasta tf

c = zeros(d-length(y),2); % dos columnas de d ceros

y =[y;c]; % the warning remains

end

Y{i} = y; % guarda las matrices en celdas

end

Can anybody explain why? Thanks

Opps!, I almost forget to mention that there are two warnings in this script. the first one is: "the variable "y" appears to be preallocated, but preallocation is not recommended here" the second one is: "The variable "y" appears to change size on every loop iteration. Consider preallocating for speed" And I'm like: [WHAAAAAT?]

Stephen Cobeldick
on 19 May 2016

This happens because you define the variable y twice: once before the loop (where it should be preallocated) and once inside the loop:

y = zeros(d,2); % preallocating

for i = 1:nargs

y = varargin{i}; % <- oops, the same name!

You probably didn't intend to do this, as each time you define that variable inside the loop it completely replaces the earlier one, thus making your "preallocation" before the loop totally pointless. So this line:

y =[y;c];

should show a warning, because y is then not preallcoated (and the line is doing exactly what proallocation avoids).

Solution: fix your names and think about your algorithm.

Note that you should avoid using i and j for loop variable names, as these are both names of the inbuilt imaginary unit.

seyoum alene
on 4 Sep 2016

................................................

clear all;

a = 0:0.001:3; %Range of values for structural excitation frequency ratio

E = 0.024; %Damping ratio of structure

m = 0:0.001:0.2; %Range of values for mass ratio

B = 0.75:0.001:1.25; %Range of values for tuned frequency ratio

Ed = 0:0.001:0.2;

x = ones(1, 1000);

temp = 1000*ones(length(m),length(Ed));

index_B = -1*ones(length(m),length(Ed));

for l = 1:length(m)

for k = 1:length(Ed)

for i = 1:length(B)

for j = 1:length(a)

%structure mass amplification factor calculation

x(j) = sqrt((B(i)^2-a(j)^2)^2+(2*Ed(k)*a(j)*B(i))^2)/sqrt((-B(i)^2*a(j)^2*m(l)+(1-a(j)^2)*(B(i)^2-a(j)^2)-4*E*Ed(k)*B(i)*a(j)^2)^2+4*(E*a(j)*(B(i)^2-a(j)^2)+Ed(k)*B(i)*a(j)*(1-a(j)^2*(1+m(l))))^2);

end

%determine if min peak for each combination of m and Ed

if max(x(:)) <= temp(l,k)

temp(l,k) = max(x(:));

index_B(l,k) = B(i);

end

end

end

end

end

.....................................

Please help me with this it doesn't give me any answer ...

Walter Roberson
on 27 Sep 2016

The code will give an answer if you wait long enough. However you are asking it to investigate 60742943901 combinations of values, which is over 2^35 combinations, so it will take rather some time.

Your problem is not with pre-allocation, your problem is that you need to vectorize your code.

Ahmed Diab
on 3 Apr 2019

How do I preallocate P and Location

case 1 %Point

N = input('Input number of point loads. ');

for Count = 1:N

P(Count) = input('Input Magitude of force on point of load. ');

Location(Count) = input('Input location of point load. ');

Opportunities for recent engineering grads.

Apply TodaySee Also

## 4 Comments

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_270855

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_270855

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_680480

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_680480

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_680486

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_680486

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_714423

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/99124-how-do-i-pre-allocate-memory-when-using-matlab#comment_714423

Sign in to comment.