Как инициализировать массив структур в MATLAB?

40

Как я могу предварительно выделить массив структур в MATLAB? Я хочу предварительно выделить "a" в этом примере, чтобы он не изменялся несколько раз.

a = []
for i = 1:100
  a(i).x = i;
end
Теги:

5 ответов

60
Лучший ответ

Использование repmat на сегодняшний день является наиболее эффективным способом предопределения структур:

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

Это ~ 10 раз быстрее, используя Matlab 2011a, чем preallocating путем индексирования, как в

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

Метод индексирования только немного быстрее, чем преалокация.

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


Код ниже, если вы хотите проверить.

        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
        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)])
No preallocation:        0.075524    
Preallocate Indexing:    0.063774
Preallocate with repmat: 0.0052338
>> 

P.S. Мне было бы интересно узнать, почему это правда, если кто-нибудь может это объяснить.

  • 0
    В заданном вопросе значения поля x растут от 1 до 100. В ответе все случаи равны 1. Как бы вы это приспособили? Я спрашиваю, потому что мне это нужно :)
  • 5
    В вашем тесте есть ошибка: перед инициализацией c нет тика (хотя в вашем случае это не имеет большого значения, так как 2 намного быстрее, чем 3). Однако в некоторых версиях Matlab (например, 2010) кажется, что 2) и 3) занимают одно и то же время, не зная, что изменилось в более новых версиях.
Показать ещё 3 комментария
11

Существует несколько способов инициализации структуры. Например, вы можете использовать команду struct:

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

который устанавливает все поля x в пустые.

Вы также можете использовать deal для создания и заполнения структуры, если вы знаете, какие данные должны туда идти

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

Или вы можете снова использовать struct (обратите внимание, что если поле структуры должно быть массивом ячеек, ячейка должна быть заключена в фигурные скобки!)

a = struct('x',xx)
11

Здесь приятно обсудить это в блоге Loren on the Art of MATLAB.

Если вы правильно поняли, вот способы инициализации структуры, которую вы хотите:

a(100).x = 100;

С помощью этого метода мы можем видеть, что элементы заполняются пустыми массивами.

  • 0
    Это, безусловно, самое элегантное решение, которое я видел. Поскольку мое наибольшее беспокойство касалось количества строк кода, я даю этому ответу +1.
-1

В соответствии с этим ответом, есть и другой способ:

[a.x] = deal(val);

где val - это значение, которое вы хотите назначить каждому элементу структуры.

Эффект этой команды отличается от эффекта других, поскольку каждому полю x каждой структуры a присваивается значение val.

-2

Вместо предварительного выделения массива структур может быть проще отменить цикл. Таким образом, массив выделяется в первой итерации, а остальные итерации используются для заполнения структур.

a = []
for i = 100:-1:1
    a(i).x = i;
end

Ещё вопросы

Сообщество Overcoder
Наверх
Меню