How to initialize an array of structs in MATLAB?

前端 未结 6 445
暗喜
暗喜 2020-11-30 23:01

How can I preallocate an array of structs in MATLAB? I want to preallocate \"a\" in this example so that it does not resize several times.

a = []
for i = 1:1         


        
相关标签:
6条回答
  • 2020-11-30 23:19

    According to this answer, there's also another way to do it:

    [a.x] = deal(val);
    

    where val is the value you want to assign to every element of the struct.

    The effect of this command is different from those of the others, as every x field of every structure a will be assigned the val value.

    0 讨论(0)
  • 2020-11-30 23:22

    There's a bunch of ways you can initialize a structure. For example, you can use the struct command:

    a(1:100) = struct('x',[]);
    

    which sets all fields x to empty.

    You can also use deal to create and fill the structure if you know what data should go in there

    xx = num2cell(1:100);
    [a(1:100).x]=deal(xx{:});
    a(99).x
    ans =
        99
    

    Or you can use struct again (note that if a field of the structure should be a cell array, the cell needs to be enclosed in curly brackets!)

    a = struct('x',xx)
    
    0 讨论(0)
  • 2020-11-30 23:24

    Instead of pre-allocating the array of structs it may be easier to reverse the loop. In this way the array is allocated in the first iteration and the rest of the iterations are used to fill the structs.

    a = []
    for i = 100:-1:1
        a(i).x = i;
    end
    
    0 讨论(0)
  • 2020-11-30 23:27

    The way this is supposed to be done, and the simplest is

    a=struct('x',cell(1,N));
    

    If you fix the missing "tic" and add this method to the benchmarking code presented by jerad, the method I propose above is a bit slower than repmat but much simpler to implement, here is the output:

    No preallocation:        0.10137
    Preallocate Indexing:    0.07615
    Preallocate with repmat: 0.01458
    Preallocate with struct: 0.07588
    

    The reason that repmat is faster is because a value to each 'x' field is assigned during the pre-allocation, instead of leaving it empty. If the above pre-allocation technique is changed so we start with all the x fields with a value (one) assigned, like this:

        a=cell(1,N);
        a(:)={1};
        d=struct('x',a);
    

    Then, the benchmarking improves a lot, been very close or some time faster than repmat. The difference is so small that every time I run it it changes which one is faster. Here an output example:

    No preallocation:        0.0962
    Preallocate Indexing:    0.0745
    Preallocate with repmat: 0.0259
    Preallocate with struct: 0.0184
    

    Conversely, if the repmat pre-allocation is changed to set the field empty, like this

    b = repmat( struct( 'x', {} ), N, 1 );
    

    All the speed advantage is lost

    0 讨论(0)
  • 2020-11-30 23:31

    Using repmat is by far the most efficient way to preallocate structs :

    N = 10000;    
    b = repmat(struct('x',1), N, 1 );
    

    This is ~10x faster using Matlab 2011a than preallocating via indexing, as in

    N      = 10000;
    b(N).x = 1
    

    The indexing method is only marginally faster than not preallocating.

    No preallocation:            0.075524    
    Preallocate Using indexing:  0.063774
    Preallocate with repmat:     0.005234
    


    Code below in case you want to verify.

            clear;
            N = 10000;
    
        %1) GROWING A STRUCT
            tic;
            for ii=1:N
                a(ii).x(1)=1;    
            end
            noPreAll = toc;        
    
        %2)PREALLOCATING A STRUCT
            tic;
            b = repmat( struct( 'x', 1 ), N, 1 );
            for ii=1:N
                b(ii).x(1)=1;    
            end;  
            repmatBased=toc;        
    
        %3)Index to preallocate
            tic;
            c(N).x = 1;
            for ii=1:N
                c(ii).x(1)=1;    
            end;  
            preIndex=toc;
    
            disp(['No preallocation:        ' num2str(noPreAll)])            
            disp(['Preallocate Indexing:    ' num2str(preIndex)])
            disp(['Preallocate with repmat: ' num2str(repmatBased)])
    

    Results in command window:

    No preallocation:        0.075524    
    Preallocate Indexing:    0.063774
    Preallocate with repmat: 0.0052338
    >> 
    

    P.S. I'd be interested to know why this is true, if anyone can explain it.

    0 讨论(0)
  • 2020-11-30 23:44

    There's a nice discussion about this in Loren on the Art of MATLAB blog.

    If I understand you correctly, here's a ways to initialize the struct you want:

    a(100).x = 100;
    

    With this method, we can see that elements are filled in with empty arrays.

    0 讨论(0)
提交回复
热议问题