%% How MATLAB Allocates Memory
% This topic provides information on how MATLAB® allocates memory when working with variables. This information, like any information on how MATLAB treats data internally, is subject to change in future releases.
%% Memory Allocation for Arrays
% When you assign a numeric or character array to a variable, MATLAB allocates a contiguous block of memory and stores the array data in that block. MATLAB also stores information about the array data, such as its class and dimensions, in a small, separate block of memory called a header. For most arrays, the memory required to store the header is insignificant. However, there could be some advantage to storing large data sets in a small number of large arrays as opposed to a large number of small arrays. This is because fewer arrays require fewer array headers.
% If you add new elements to an existing array, MATLAB expands the array in memory in a way that keeps its storage contiguous. This usually requires finding a new block of memory large enough to hold the expanded array. MATLAB then copies the contents of the array from its original location to this new block in memory, adds the new elements to the array in this block, and frees up the original array location in memory.
% If you remove elements from an existing array, MATLAB keeps the memory storage contiguous by removing the deleted elements, and then compacting its storage in the original memory location.
%% Copying Arrays
% When you assign an array to a second variable (for instance, when you execute B = A), MATLAB does not allocate new memory right away. Instead, it creates a copy of the array reference. As long as you do not modify the contents of the memory block being referenced by A and B, there is no need to store more than one copy of data. However, if you modify any elements of the memory block using either A or B, MATLAB allocates new memory, copies the data into it, and then modifies the created copy.
% On Windows® systems, the memory function enables you to inspect the memory details. To see how copying arrays affects memory usage on your Windows system, create the function memUsed in a file in your current folder. The function calls memory to return the amount of memory used by your MATLAB process in megabytes.
% function y = memUsed
% usr = memory;
% y = usr.MemUsedMATLAB/1e6;
% Call memUsed to display the current memory usage.

format shortG
memUsed

% Create a 2000-by-2000 numeric array and observe the change in memory usage. The array uses about 32 MB of memory.

A = magic(2000);
memUsed

% Make a copy of A in B. Because there is no need to have two copies of the array data, MATLAB only makes a copy of the array reference. This requires no significant additional memory.

B = A;
memUsed

% Now modify B by removing half of its rows. Because A and B no longer point to the same data, MATLAB must allocate a separate memory block to B. As a result, the amount of memory used by the MATLAB process increases by the size of B, which is about 16 MB (one half of the 32 MB required for A).

B(1001:2000,:) = [];
memUsed

%
%% Function Arguments
% MATLAB handles arguments passed in function calls in the same way that it handles arrays being copied. When you pass a variable to a function, you actually pass a reference to the data that the variable represents. As long as the data is not modified by the called function, the variable in the calling function or script and the variable in the called function point to the same location in memory. If the called function modifies the value of the input data, then MATLAB makes a copy of the original variable in a new location in memory, updates that copy with the modified value, and points the input argument in the called function to this new location.
% For example, consider the function myfun, which modifies the value of the array passed to it. MATLAB makes a copy of A in a new location in memory, sets the variable X as a reference to this copy, and then sets one row of X to zero. The array referenced by A remains unchanged.
% A = magic(5);
% myfun(A)
%
% function myfun(X)
% X(4,:) = 0;
% disp(X)
% end
% If the calling function or script needs the modified value of the array it passed to myfun, you need to return the updated array as an output of the called function.
%
%% Data Types and Memory
% Memory requirements differ for MATLAB data types. You might be able to reduce the amount of memory used by your code by learning how MATLAB treats various data types.
%% Numeric Arrays
% MATLAB allocates 1, 2, 4, or 8 bytes to 8-bit, 16-bit, 32-bit, and 64-bit signed and unsigned integers, respectively. It represents floating-point numbers in either double-precision (double) or single-precision (single) format. Because MATLAB stores numbers of type single using 4 bytes, they require less memory than numbers of type double, which use 8 bytes. However, because they are stored with fewer bits, numbers of type single are represented to less precision than numbers of type double. In MATLAB, double is the default numeric data type and provides sufficient precision for most computational tasks. For more information, see Floating-Point Numbers.
%% Structure and Cell Arrays
% While numeric arrays must be stored in a contiguous block of memory, structures and cell arrays can be stored in noncontiguous blocks. For structures and cell arrays, MATLAB creates a header not only for the array, but also for each field of the structure or each cell of the cell array. Therefore, the amount of memory required to store a structure or cell array depends not only on how much data it holds, but also on how it is constructed.
% For example, consider a scalar structure S1 with fields R, G, and B, where each field contains a 100-by-50 array. S1 requires one header to describe the overall structure, one header for each unique field name, and one header for each field. This makes a total of seven headers for the entire structure.

S1.R = zeros(100,50);
S1.G = zeros(100,50);
S1.B = zeros(100,50);

% On the other hand, consider a 100-by-50 structure array S2 in which each element has scalar fields R, G, and B. In this case, S2 needs one header to describe the overall structure, one header for each unique field name, and one header for each field of the 5,000 elements, making a total of 15,004 array headers for the entire structure array.

for i = 1:100
    for j=1:50
        S2(i,j).R = 0;
        S2(i,j).G = 0;
        S2(i,j).B = 0;
    end
end

% Use the whos function to compare the amount of memory allocated to S1 and S2 on a 64-bit system. Even though S1 and S2 hold the same data, S1 uses significantly less memory.

whos S1 S2

%% Complex Arrays
% MATLAB uses an interleaved storage representation of complex numbers, where the real and imaginary parts are stored together in a contiguous block of memory. If you make a copy of a complex array, and then modify only the real or imaginary part of the array, MATLAB creates an array containing both real and imaginary parts. For more information about the representation of complex numbers in memory, see MATLAB Support for Interleaved Complex API in MEX Functions.
%% Sparse Matrices
% It is a good practice to store matrices with few nonzero elements using sparse storage. When a full matrix has a small number of nonzero elements, converting the matrix to sparse storage typically improves memory usage and code execution time. You can convert a full matrix to sparse storage using the sparse function.
% For example, let matrix A be a 1,000-by-1,000 full storage identity matrix. Create B as a sparse copy of A. In sparse storage, the same data uses a significantly smaller amount of memory.

A = eye(1000);
B = sparse(A);
whos A B

%
%% Working with Large Data Sets
% When you work with large data sets, repeatedly resizing arrays might cause your program to run out of memory. If you expand an array beyond the available contiguous memory of its original location, MATLAB must make a copy of the array and move the copy into a memory block with sufficient space. During this process, there are two copies of the original array in memory. This temporarily doubles the amount of memory required for the array and increases the risk of your program running out of memory. You can improve the memory usage and code execution time by preallocating the maximum amount of space required for the array. For more information, see Preallocation.
% Copyright 2020 The MathWorks, Inc.