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

Когда вы используете массивы ячеек в коде 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} является двойным на одном пути к выполнению и char на другом пути к выполнению.

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

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

  • Вы не можете индексировать массивы ячеек при помощи сглаженного parentheses(). Рассмотрите массивы ячеек индексации при помощи изогнутого braces{} получить доступ к содержимому ячейки.

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

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

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

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

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

    x = {1, 'mytext'};
    for i = A:B
    	 disp(x{i});
    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, задайте переменную как массив или структуру вместо как массив ячеек.

Похожие темы