exponenta event banner

Ограничения массива ячеек для создания кода

При использовании массивов ячеек в коде MATLAB ®, предназначенном для создания кода, необходимо соблюдать следующие ограничения:

Назначение элемента массива ячеек

Перед использованием элемента массива ячеек необходимо назначить ему все пути выполнения. Например:

function z = foo(n)
%#codegen
c = cell(1,3);
if n < 1
    c{2} = 1;
    
else
    c{2} = n;
end
z = c{2};
end

Генератор кода рассматривает передачу массива ячеек функции или возврат его из функции как использование всех элементов массива ячеек. Поэтому перед передачей массива ячеек функции или возвращением его из функции необходимо назначить все ее элементы. Например, следующий код не разрешен, так как он не присваивает значение c{2} и c является выводом функции.

function c = foo()
%#codegen
c = cell(1,3);
c{1} = 1;
c{3} = 3;
end

Назначение значений элементам должно быть согласованным для всех путей выполнения. Следующий код не разрешен, так как y{2} является двойным на одном пути выполнения и символом на другом пути выполнения.

function y = foo(n)
y = cell(1,3)
if n > 1;
    y{1} = 1
    y{2} = 2;
    y{3} = 3;
else
    y{1} = 10;
    y{2} = 'a';
    y{3} = 30;
end

Массивы ячеек переменного размера

  • coder.varsize не поддерживается для гетерогенных массивов ячеек.

  • Если вы используете cell для определения массива ячеек фиксированного размера нельзя использовать функцию coder.varsize указывает, что массив ячеек имеет переменный размер. Например, этот код вызывает ошибку генерации кода, поскольку x = cell(1,3) делает x массив ячеек фиксированного размера 1 на 3.

    ...
    x = cell(1,3);           
    coder.varsize('x',[1 5])
    ...

    Вы можете использовать coder.varsize с массивом ячеек, который определяется с помощью фигурных фигурных скобок. Например:

    ...
    x = {1 2 3}; 
    coder.varsize('x',[1 5])
    ...

  • Создание массива ячеек переменного размера с помощью cell используйте этот шаблон кода:

    function mycell(n)
    %#codegen
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    end
    end

    См. раздел Определение массива ячеек переменного размера с помощью ячейки.

    Чтобы задать верхние границы для массива ячеек, используйте coder.varsize.

    function mycell(n)
    %#codegen
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    coder.varsize('x',[1,20]);
    end
    end

Определение массива ячеек переменного размера с помощью cell

Для создания кода перед использованием элемента массива ячеек необходимо присвоить ему значение. При использовании cell для создания массива ячеек переменного размера, например, cell(1,n)MATLAB назначает пустую матрицу каждому элементу. Однако для генерации кода элементы не назначаются. Для создания кода после использования cell для создания массива ячеек переменного размера перед использованием массива ячеек необходимо назначить все элементы массива ячеек. Например:

function z = mycell(n, j)
%#codegen
x = cell(1,n);   
for i = 1:n
    x{i} = i;
end
z = x{j};
end

Генератор кода анализирует код, чтобы определить, назначены ли все элементы до первого использования массива ячеек. Если генератор кода обнаруживает, что некоторые элементы не назначены, создание кода завершается ошибкой с сообщением об ошибке. Например, измените верхнюю границу for-закольцовывание в j.

function z = mycell(n, j)
%#codegen
x = cell(1,n);   
for i = 1:j %<- Modified here
    x{i} = i;
end
z = x{j};
end

С этой модификацией и с входами j меньше, чем n, функция не присваивает значения всем элементам массива ячеек. Создание кода приводит к ошибке:

Unable to determine that every element of 'x{:}' is assigned
before this line.

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

Чтобы избежать этой ошибки, следуйте следующим инструкциям:

  • При использовании cell чтобы определить массив ячеек переменного размера, напишите код, следующий за этим шаблоном:

    function z = mycell(n, j)
    %#codegen
    x = cell(1,n);   
    for i = 1:n
        x{i} = i;
    end
    z = x{j};
    end
    

    Вот шаблон для многомерного массива ячеек:

    function z = mycell(m,n,p)
    %#codegen
    x = cell(m,n,p);
    for i = 1:m
        for j =1:n
            for k = 1:p
                x{i,j,k} = i+j+k;
            end
        end
    end
    z = x{m,n,p};
    end

  • Приращение или уменьшение счетчика цикла на 1.

  • Определите массив ячеек в пределах одного цикла или одного набора вложенных циклов. Например, этот код не разрешен:

    function z = mycell(n, j)
    x = cell(1,n);
    for i = 1:5
        x{i} = 5;
    end
    for i = 6:n
        x{i} = 5;
    end
    z = x{j};
    end            

  • Используйте одни и те же переменные для размеров ячейки и начальных и конечных значений цикла. Например, не удалось создать код для следующего кода, поскольку при создании ячейки используется n и значение конца цикла использует m:

    function z = mycell(n, j)
    x = cell(1,n);
    m = n;
    for i = 1:m
        x{i} = 2;
    end
    z = x{j};
    end               

    Переписать код для использования n для создания ячейки и конечного значения цикла:

    function z = mycell(n, j)
    x = cell(1,n);
    for i = 1:n
        x{i} = 2;
    end
    z = x{j};
    end

  • Создайте массив ячеек с помощью этого шаблона:

    x = cell(1,n)

    Не присваивайте массив ячеек полю структуры или свойству объекта. Например, этот код не разрешен:

    myobj.prop = cell(1,n)
    for i = 1:n
    ...
    end
    

    Не используйте cell функция внутри конструктора массива ячеек {}. Например, этот код не разрешен:

    x = {cell(1,n)};

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

    function z = mycell(n)
    if n > 3
        c = cell(1,n);
    else
        c = cell(n,1);
    end
    for i = 1:n
        c{i} = i;
    end
    z = c{n};
    end

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

    function z = cellerr(n)
    if n > 3
        c = cell( 1,n);
        for i = 1:n
            c{i} = i;
        end
    else
        c = cell(n,1);
        for i = 1:n
            c{i} = i;
        end
    end
    z = c{n};
    end

Индексирование массива ячеек

  • Нельзя индексировать массивы ячеек с помощью гладких скобок(). Рассмотрите возможность индексирования массивов ячеек с помощью фигурных фигурных скобок{} для доступа к содержимому ячейки.

  • Необходимо индексировать в гетерогенные массивы ячеек с помощью константных индексов или с помощью for- контуры с постоянными границами.

    Например, следующий код не разрешен.

    x = {1, 'mytext'};
    disp(x{randi});

    Можно индексировать в гетерогенный массив ячеек в for-закольцовывание с постоянными границами, поскольку генератор кода разворачивает цикл. При разворачивании создается отдельная копия тела цикла для каждой итерации цикла, что делает индекс в каждой итерации цикла постоянным. Однако, если for-loop имеет большое тело или имеет много итераций, разворачивание может увеличить время компиляции и создать неэффективный код.

    Если A и B константы, следующий код показывает индексирование в гетерогенный массив ячеек в for-контур с постоянными границами.

    x = {1, 'mytext'};
    for i = A:B
    	 disp(x{i});
    end

Наращивание массива ячеек с помощью {end + 1}

Для наращивания массива ячеек X, вы можете использовать X{end + 1}. Например:

...
X = {1 2};
X{end + 1} = 'a';
...

При использовании {end + 1} Чтобы создать клеточный массив, выполните следующие ограничения:

  • Использовать только {end + 1}. Не использовать {end + 2}, {end + 3}и так далее.

  • Использовать {end + 1} только с векторами. Например, следующий код не разрешен, так как X является матрицей, а не вектором:

    ...
    X = {1 2; 3 4};
    X{end + 1} = 5;
    
    ...

  • Использовать {end + 1} только с переменной. В следующем коде: {end + 1} не вызывает {1 2 3} расти. В этом случае генератор кода обрабатывает {end + 1} как внеплановый индекс в X{2}.

    ...
    X = {'a' { 1 2 3 }};
    X{2}{end + 1} = 4;
    ...

  • Когда {end + 1} растет массив ячеек в цикле, массив ячеек должен иметь переменный размер. Поэтому массив ячеек должен быть однородным.

    Этот код разрешен, так как X является однородным.

    ...
    X = {1  2};
    for i=1:n
        X{end + 1} = 3;
    end
    ...

    Этот код не разрешен, так как X является неоднородным.

    ...
    X = {1 'a' 2 'b'};
    for i=1:n
        X{end + 1} = 3;
    end
    ...

Содержимое массива ячеек

Массивы ячеек не могут содержать mxarrays. В массиве ячеек нельзя сохранить значение, возвращаемое внешней функцией.

Передача массивов ячеек внешним функциям C/C + +

Невозможно передать массив ячеек в coder.ceval. Если переменная является входным аргументом для coder.cevalопределите переменную как массив или структуру, а не как массив ячеек.

Связанные темы