To initialize an N-by-M matrix, use the “zeros” function. For example, create a 3-by-5 matrix of zeros: A = zeros(3,5); You can then later assign specific values to the elements of “A”. Answer from Leah on mathworks.com
🌐
MathWorks
mathworks.com › matlab › programming › classes › construct and work with object arrays
empty - Create empty array of specified class - MATLAB
The value you assign to the empty array must be of the same class as the array or convertible to that class. MATLAB fills the other elements of the array with the default value of the array type, which for uint8 is 0. A(3,3) = 5 · A = 3×3 uint8 matrix 0 0 0 0 0 0 0 0 5 ·
🌐
MathWorks
mathworks.com › matlab › language fundamentals › data types › numeric types
Empty Matrices - MATLAB & Simulink
If you construct a matrix using empty matrix elements, the empty matrices are ignored in the resulting matrix: A = [5.36; 7.01; []; 9.44] A = 5.3600 7.0100 9.4400 · You clicked a link that corresponds to this MATLAB command:
🌐
MathWorks
mathworks.com › matlabcentral › answers › 485181-how-to-create-empty-matrix-in-matlab
How to create empty matrix in matlab? - MATLAB Answers - MATLAB Central
October 14, 2019 - I need to create an empty matrix, and I have 100 images . I want to store these images in this matrix by nested loop (i,j) ,So that is matrix(0,0) is the first image ,and the second image is matrix(0,1) ,......, the final image is matrix(10,10) . Sign in to comment. Sign in to answer this question. ... https://www.mathworks.com/matlabcentral/answers/485181-how-to-create-empty-matrix-in-matlab#answer_396245
🌐
MathWorks
mathworks.com › matlab › language fundamentals › matrices and arrays
Empty Arrays - MATLAB & Simulink
In most cases where you need to create an empty array, a 0-by-0 array is sufficient. However, you can create empty arrays of different sizes by using functions like zeros or ones. For example, create a 0-by-5 matrix and a 3-by-0-by-5 array.
🌐
MATLAB
matlab.izmiran.ru › help › techdoc › matlab_prog › ch_dat28.html
The Empty Matrix :: Data Structures (Programming)
To create a 0-by-0 matrix, use the square bracket operators with no value specified: A = []; whos A Name Size Bytes Class A 0x0 0 double array · You can create empty matrices (and arrays) of other sizes using the zeros, ones, rand, or eye functions.
Find elsewhere
🌐
Northwestern University
ece.northwestern.edu › local-apps › matlabhelp › techdoc › matlab_prog › ch10_p44.html
M-File Programming (Programming and Data Types)
The basic model for empty matrices is that any operation that is defined for m-by-n matrices, and that produces a result whose dimension is some function of m and n, should still be allowed when m or n is zero. The size of the result should be that same function, evaluated at zero.
🌐
MathWorks
mathworks.com › matlabcentral › answers › 272301-how-to-write-an-empty-matrix-with-4-number-of-rows-and-3-columns-how-to-write-an-epmty-row-vector
How to write an empty matrix with 4 number of rows and 3 columns. How to write an epmty row vector. - MATLAB Answers - MATLAB Central
March 9, 2016 - Lets read the MATLAB documentation. isempty says: "An empty array has at least one dimension of size zero, for example, 0-by-0 or 0-by-5". The page Empty Matrices, Scalars, and Vectors says "A matrix having at least one dimension equal to zero is ...
🌐
Delft Stack
delftstack.com › home › howto › matlab › create an empty matrix in matlab
How to Create an Empty Matrix in MATLAB | Delft Stack
February 2, 2024 - The smallest empty matrix has dimensions (m-by-n) 0-by-0. We use the square brackets [] without any data or value inserted in it to create our desired 0-by-0 matrix: The ones() function, in MATLAB, is used to create a matrix containing all ones as data.
🌐
Nick Higham
nhigham.com › 2016 › 03 › 15 › empty-matrices-in-matlab
Empty Matrices in MATLAB – Nick Higham
March 15, 2016 - Indeed [ ] is the 0-by-0 empty matrix ... Empty matrices can have dimension n-by-0 or 0-by-n for any nonnegative integer n. One way to construct them is with double.empty (or the empty method of any other MATLAB class):
Top answer
1 of 4
33

This is strange, I am seeing f being faster while g being slower than what you are seeing. But both of them are identical for me. Perhaps a different version of MATLAB ?

>> g = @() zeros(1000, 0) * zeros(0, 1000);
>> f = @() zeros(1000)
f =     
    @()zeros(1000)
>> timeit(f)  
ans =    
   8.5019e-04
>> timeit(f)  
ans =    
   8.4627e-04
>> timeit(g)  
ans =    
   8.4627e-04

EDIT can you add + 1 for the end of f and g, and see what times you are getting.

EDIT Jan 6, 2013 7:42 EST

I am using a machine remotely, so sorry about the low quality graphs (had to generate them blind).

Machine config:

i7 920. 2.653 GHz. Linux. 12 GB RAM. 8MB cache.

It looks like even the machine I have access to shows this behavior, except at a larger size (somewhere between 1979 and 2073). There is no reason I can think of right now for the empty matrix multiplication to be faster at larger sizes.

I will be investigating a little bit more before coming back.

EDIT Jan 11, 2013

After @EitanT's post, I wanted to do a little bit more of digging. I wrote some C code to see how matlab may be creating a zeros matrix. Here is the c++ code that I used.

int main(int argc, char **argv)
{
    for (int i = 1975; i <= 2100; i+=25) {
    timer::start();
    double *foo = (double *)malloc(i * i * sizeof(double));
    for (int k = 0; k < i * i; k++) foo[k]  = 0;
    double mftime = timer::stop();
    free(foo);

    timer::start();
    double *bar = (double *)malloc(i * i * sizeof(double));
    memset(bar, 0, i * i * sizeof(double));
    double mmtime = timer::stop();
    free(bar);

    timer::start();
    double *baz = (double *)calloc(i * i, sizeof(double));
    double catime = timer::stop();
    free(baz);

    printf("%d, %lf, %lf, %lf\n", i, mftime, mmtime, catime);
    }
}

Here are the results.

$ ./test
1975, 0.013812, 0.013578, 0.003321
2000, 0.014144, 0.013879, 0.003408
2025, 0.014396, 0.014219, 0.003490
2050, 0.014732, 0.013784, 0.000043
2075, 0.015022, 0.014122, 0.000045
2100, 0.014606, 0.014480, 0.000045

As you can see calloc (4th column) seems to be the fastest method. It is also getting significantly faster between 2025 and 2050 (I'd assume it would at around 2048 ?).

Now I went back to matlab to check for the same. Here are the results.

>> test
1975, 0.003296, 0.003297
2000, 0.003377, 0.003385
2025, 0.003465, 0.003464
2050, 0.015987, 0.000019
2075, 0.016373, 0.000019
2100, 0.016762, 0.000020

It looks like both f() and g() are using calloc at smaller sizes (<2048 ?). But at larger sizes f() (zeros(m, n)) starts to use malloc + memset, while g() (zeros(m, 0) * zeros(0, n)) keeps using calloc.

So the divergence is explained by the following

  • zeros(..) begins to use a different (slower ?) scheme at larger sizes.
  • calloc also behaves somewhat unexpectedly, leading to an improvement in performance.

This is the behavior on Linux. Can someone do the same experiment on a different machine (and perhaps a different OS) and see if the experiment holds ?

2 of 4
30

The results might be a bit misleading. When you multiply two empty matrices, the resulting matrix is not immediately "allocated" and "initialized", rather this is postponed until you first use it (sort of like a lazy evaluation).

The same applies when indexing out of bounds to grow a variable, which in the case of numeric arrays fills out any missing entries with zeros (I discuss afterwards the non-numeric case). Of course growing the matrix this way does not overwrite existing elements.

So while it may seem faster, you are just delaying the allocation time until you actually first use the matrix. In the end you'll have similar timings as if you did the allocation from the start.

Example to show this behavior, compared to a few other alternatives:

N = 1000;

clear z
tic, z = zeros(N,N); toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
tic, z = zeros(N,0)*zeros(0,N); toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
tic, z(N,N) = 0; toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
tic, z = full(spalloc(N,N,0)); toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
tic, z(1:N,1:N) = 0; toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
val = 0;
tic, z = val(ones(N)); toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

clear z
tic, z = repmat(0, [N N]); toc
tic, z = z + 1; toc
assert(isequal(z,ones(N)))

The result shows that if you sum the elapsed time for both instructions in each case, you end up with similar total timings:

// zeros(N,N)
Elapsed time is 0.004525 seconds.
Elapsed time is 0.000792 seconds.

// zeros(N,0)*zeros(0,N)
Elapsed time is 0.000052 seconds.
Elapsed time is 0.004365 seconds.

// z(N,N) = 0
Elapsed time is 0.000053 seconds.
Elapsed time is 0.004119 seconds.

The other timings were:

// full(spalloc(N,N,0))
Elapsed time is 0.001463 seconds.
Elapsed time is 0.003751 seconds.

// z(1:N,1:N) = 0
Elapsed time is 0.006820 seconds.
Elapsed time is 0.000647 seconds.

// val(ones(N))
Elapsed time is 0.034880 seconds.
Elapsed time is 0.000911 seconds.

// repmat(0, [N N])
Elapsed time is 0.001320 seconds.
Elapsed time is 0.003749 seconds.

These measurements are too small in the milliseconds and might not be very accurate, so you might wanna run these commands in a loop a few thousand times and take the average. Also sometimes running saved M-functions is faster than running scripts or on the command prompt, as certain optimizations only happen that way...

Either way allocation is usually done once, so who cares if it takes an extra 30ms :)


A similar behavior can be seen with cell arrays or arrays of structures. Consider the following example:

N = 1000;

tic, a = cell(N,N); toc
tic, b = repmat({[]}, [N,N]); toc
tic, c{N,N} = []; toc

which gives:

Elapsed time is 0.001245 seconds.
Elapsed time is 0.040698 seconds.
Elapsed time is 0.004846 seconds.

Note that even if they are all equal, they occupy different amount of memory:

>> assert(isequal(a,b,c))
>> whos a b c
  Name         Size                  Bytes  Class    Attributes

  a         1000x1000              8000000  cell               
  b         1000x1000            112000000  cell               
  c         1000x1000              8000104  cell               

In fact the situation is a bit more complicated here, since MATLAB is probably sharing the same empty matrix for all the cells, rather than creating multiple copies.

The cell array a is in fact an array of uninitialized cells (an array of NULL pointers), while b is a cell array where each cell is an empty array [] (internally and because of data sharing, only the first cell b{1} points to [] while all the rest have a reference to the first cell). The final array c is similar to a (uninitialized cells), but with the last one containing an empty numeric matrix [].


I looked around the list of exported C functions from the libmx.dll (using Dependency Walker tool), and I found a few interesting things.

  • there are undocumented functions for creating uninitialized arrays: mxCreateUninitDoubleMatrix, mxCreateUninitNumericArray, and mxCreateUninitNumericMatrix. In fact there is a submission on the File Exchange makes use of these functions to provide a faster alternative to zeros function.

  • there exist an undocumented function called mxFastZeros. Googling online, I can see you cross-posted this question on MATLAB Answers as well, with some excellent answers over there. James Tursa (same author of UNINIT from before) gave an example on how to use this undocumented function.

  • libmx.dll is linked against tbbmalloc.dll shared library. This is Intel TBB scalable memory allocator. This library provides equivalent memory allocation functions (malloc, calloc, free) optimized for parallel applications. Remember that many MATLAB functions are automatically multithreaded, so I wouldn't be surprised if zeros(..) is multithreaded and is using Intel's memory allocator once the matrix size is large enough (here is recent comment by Loren Shure that confirms this fact).

Regarding the last point about the memory allocator, you could write a similar benchmark in C/C++ similar to what @PavanYalamanchili did, and compare the various allocators available. Something like this. Remember that MEX-files have a slightly higher memory management overhead, since MATLAB automatically frees any memory that was allocated in MEX-files using the mxCalloc, mxMalloc, or mxRealloc functions. For what it's worth, it used to be possible to change the internal memory manager in older versions.


EDIT:

Here is a more thorough benchmark to compare the discussed alternatives. It specifically shows that once you stress the use of the entire allocated matrix, all three methods are on equal footing, and the difference is negligible.

function compare_zeros_init()
    iter = 100;
    for N = 512.*(1:8)
        % ZEROS(N,N)
        t = zeros(iter,3);
        for i=1:iter
            clear z
            tic, z = zeros(N,N); t(i,1) = toc;
            tic, z(:) = 9; t(i,2) = toc;
            tic, z = z + 1; t(i,3) = toc;
        end
        fprintf('N = %4d, ZEROS = %.9f\n', N, mean(sum(t,2)))

        % z(N,N)=0
        t = zeros(iter,3);
        for i=1:iter
            clear z
            tic, z(N,N) = 0; t(i,1) = toc;
            tic, z(:) = 9; t(i,2) = toc;
            tic, z = z + 1; t(i,3) = toc;
        end
        fprintf('N = %4d, GROW  = %.9f\n', N, mean(sum(t,2)))

        % ZEROS(N,0)*ZEROS(0,N)
        t = zeros(iter,3);
        for i=1:iter
            clear z
            tic, z = zeros(N,0)*zeros(0,N); t(i,1) = toc;
            tic, z(:) = 9; t(i,2) = toc;
            tic, z = z + 1; t(i,3) = toc;
        end
        fprintf('N = %4d, MULT  = %.9f\n\n', N, mean(sum(t,2)))
    end
end

Below are the timings averaged over 100 iterations in terms of increasing matrix size. I performed the tests in R2013a.

>> compare_zeros_init
N =  512, ZEROS = 0.001560168
N =  512, GROW  = 0.001479991
N =  512, MULT  = 0.001457031

N = 1024, ZEROS = 0.005744873
N = 1024, GROW  = 0.005352638
N = 1024, MULT  = 0.005359236

N = 1536, ZEROS = 0.011950846
N = 1536, GROW  = 0.009051589
N = 1536, MULT  = 0.008418878

N = 2048, ZEROS = 0.012154002
N = 2048, GROW  = 0.010996315
N = 2048, MULT  = 0.011002169

N = 2560, ZEROS = 0.017940950
N = 2560, GROW  = 0.017641046
N = 2560, MULT  = 0.017640323

N = 3072, ZEROS = 0.025657999
N = 3072, GROW  = 0.025836506
N = 3072, MULT  = 0.051533432

N = 3584, ZEROS = 0.074739924
N = 3584, GROW  = 0.070486857
N = 3584, MULT  = 0.072822335

N = 4096, ZEROS = 0.098791732
N = 4096, GROW  = 0.095849788
N = 4096, MULT  = 0.102148452
🌐
MathWorks
mathworks.com › matlabcentral › answers › 1716590-how-to-create-and-empty-matrix-of-a-given-size-in-a-way-that-is-compatible-with-codegen
How to create and empty matrix of a given size in a way that is compatible with codegen - MATLAB Answers - MATLAB Central
May 11, 2022 - I have a function that is writing to an output matrix (y). ... x is a variable size large array and using zeros() is inefficient because it initializes the array with zeros that are then going to be overwritten. I was wondering if there is a way to do this more efficiently? I've tried a lot of the options I can find so far but none are compatible with codegen. ... https://www.mathworks.com/matlabcentral/answers/1716590-how-to-create-and-empty-matrix-of-a-given-size-in-a-way-that-is-compatible-with-codegen#comment_2152365
🌐
MathWorks
mathworks.com › matlab › language fundamentals › matrices and arrays
isempty - Determine whether array is empty - MATLAB
Create a 0-by-3 string array and test if it is empty. ... Input array or table, specified as a scalar, vector, matrix, multidimensional array, table, or timetable.
Top answer
1 of 1
1

The difference is that one function returns a cell array of arrays, and the other function just returns an array. A cell array is a container which can hold different objects in each cell, and critically a cell can be an array.

In this case, the outputs z1 and z2 are NOT the same. The output z1 is a cell array whose first element is an array of doubles. The output z2 is an array of doubles.

Of note is that any array that has at least one dimension of size 0 is considered an empty array (see isempty).

Behavior Examples

The following examples may be helpful in understanding the types of these variables.

>> a = zeros(0, 1)

a =

  0×1 empty double column vector

>> whos("a")
  Name      Size            Bytes  Class     Attributes

  a         0x1                 0  double   

This is to be expected, an empty array should have no data. Now, this is a bit of lie from MATLAB, since the size and type data is stored somewhere to display it to us, but we will ignore that for now.

>> b = {a}

b =

  1×1 cell array

    {0×1 double}

>> whos("b")
  Name      Size            Bytes  Class    Attributes

  b         1x1               104  cell      

Notice even though we are just storing an empty array, we are using 104 (!) bytes. All of this data is that size and type data of the array we are storing, along with a pointer to the actual data.

Note: since an empty array stores no data, the pointer is most likely a null pointer.

We can extract the array from a cell with curly brace indexing:

>> c = b{1}

c =

  0×1 empty double column vector

>> whos("c")
  Name      Size            Bytes  Class     Attributes

  c         0x1                 0  double  

Again, we have an empty array of size "zero".

>> b{2} = zeros(0, 1)

b =

  1×2 cell array

    {0×1 double}    {0×1 double}

>> whos("b")
  Name      Size            Bytes  Class    Attributes

  b         1x2               208  cell  

With two elements, we now have to store information about two different arrays. Each cell requires 104 bytes, so two cells requires 208 bytes.

Now, let's store some actual data, and also use the fact that a cell array can store different types.

>> b{2} = ["Hello", ", ", "World!"]

b =

  1×2 cell array

    {0×1 double}    {1×3 string}

>> whos("b")
  Name      Size            Bytes  Class    Attributes

  b         1x2               476  cell    

>> d = ["Hello", ", ", "World!"]

d = 

  1×3 string array

    "Hello"    ", "    "World!"

>> whos("d")
  Name      Size            Bytes  Class     Attributes

  d         1x3               268  string   

Note the size of b is precisely the size of two cells + the size of each array or 2 * 104 + 0 + 268 = 476

Implementation Example

It may help to consider a simple example what is happening under the hood here. Consider the following pseudocode for how you might store an array:

class Array:
    type: double
    data_pointer: double*
    rows: unsigned int
    cols: unsigned int

Each array object has a field that has a pointer to a location on the heap, where the actual data is stored. It also has a size, which for this simple case we will assume to only support 2D arrays.

So the object z2 might look something like

>> z2
Array:
    type: double
    data_pointer: NULL
    rows: 0
    cols: 1

A cell array can be constructed by making an array of pointers

class CellArray:
    type: Array
    data_pointer: Array*
    rows: unsigned int
    cols: unsigned int

Then the object z1 might look like

>> z1
CellArray:
    type: Array
    data_pointer: 0xDEADBEEF
    rows: 1 // Not an empty cell array
    cols: 1

Clearly, these objects are not the same.