Чтобы предварительно выделить память в Matlab, я хочу инициализировать свой массив объектов. Как мне это сделать?

#arrays #matlab #object #memory-management

#массивы #matlab #объект #управление памятью

Вопрос:

У меня есть класс объектов, известных как блоки. В настоящее время я создаю массив блоков, используя цикл for, просто добавляя их к пустому массиву

 blockArray=[];
for ii=1:Size   
    blockArray=[blockArray block(....)];      
end
  

Чтобы предварительно выделить память, как мне инициализировать массив объектов из блоков с фиктивными значениями?

Например, если бы вместо использования блочных объектов я использовал числа, я мог бы легко предварительно выделить, используя нули (1, размер). Есть ли что-то подобное, что я мог бы сделать?

Ответ №1:

Документация matlab описывает

Чтобы предварительно выделить массив объектов, сначала назначьте последний элемент массива. MATLAB® заполняет элементы массива с первого по предпоследний объектами DocArrayExample по умолчанию.

Итак, чтобы сделать это, вместо того, чтобы перебирать from 1:size , это проще сделать…

 blockArray = []
blockArray(size) = block(...)
  

Комментарии:

1. Обратите внимание, что для этого конструктор вашего класса должен поддерживать синтаксис с нулевыми входными аргументами, который MATLAB вызовет для заполнения первых n-1 элементов. Поэтому создайте свой конструктор, используя nargin для проверки количества входных данных и указав значения по умолчанию, если они не указаны.

2. Я попробовал это с помощью этого способа, но я получаю сообщение об ошибке: произошла следующая ошибка при преобразовании из блока в double: Ошибка при использовании двойного преобразования в double из блока невозможно.

Ответ №2:

Язык на самом деле не поддерживает это, существует несколько решений (или обходных путей).

Репликация первого экземпляра

Вставляя первый элемент в массив, вы можете заполнить весь массив этим элементом для достижения предварительного выделения. Это может выглядеть очень плохо, но на самом деле это самая быстрая из известных мне возможностей.

 for ii=1:S
    %assumption e is a scalar, otherwise the code is totally screwed
    e=block(....)
    if ii==1
       %to do preallocation, fill it with your first element
       blockArray(1:S)=e
    else
       blockArray(ii)=e
    end      
end
  

Используйте массивы ячеек

Очевидное простое решение, вы можете поместить любой класс в поля

 blockArray=cell(S,1);
for ii=1:S
    %assumption e is a scalar, otherwise the code is totally screwed
    e=block(....)
    blockArray{ii}=e
end
  

Это решение очень простое, но медленнее первого. Вы также теряете некоторые функции, которые недоступны для ячеек arras

Пусть ваш класс реализует функциональность массива

 classdef A
properties
    arg1
    out
end
methods
    function  obj = A(varargin)
        if nargin==0
            %null object constructor
        elseif strcmpi(varargin{1},'createarray')
            sz=varargin(2:end);
            %preallocate
            obj(sz{:})=A;
        else
            %standard constructor
            obj.arg1=varargin{1};
            obj.out=[1 2 3;];
        end
    end

end
end
  

Конструктор без входного аргумента создает «пустой» или «нулевой» объект, он используется для предварительного выделения, поэтому он должен быть пустым.
Конструктор с первым параметром makearray создает массив
В противном случае должен быть вызван ваш конструктор.

Использование:

 %create an empty object
A
%create an array of size 2,3,4
A('createarray',2,3,4)
%use the standard constructor
A(2)
  

Самым большим недостатком является то, что вам нужно изменить свои классы. Никогда не тестировал это решение, но оно должно быть близко к первому по производительности.