Диагностируйте и зафиксируйте ошибки данных Переменного Размера

Диагностирование и фиксация ошибок несоответствия размера

Проблема: присвоение матриц Переменного Размера к матрицам фиксированного размера

Вы не можете присвоить матрицы переменного размера матрицам фиксированного размера в сгенерированном коде. Рассмотрите этот пример:

function Y = example_mismatch1(n) %#codegen
assert(n < 10);
B = ones(n,n);
A = magic(3);
A(1) = mean(A(:));
if (n == 3)
    A = B;
end
Y = A;

Компиляция этой функции производит эту ошибку:

??? Dimension 1 is fixed on the left-hand side 
but varies on the right ...

Существует несколько способов зафиксировать эту ошибку:

  • Позвольте матричный A вырасти путем добавления coder.varsize построение:

    function Y = example_mismatch1_fix1(n) %#codegen
    coder.varsize('A');
    assert(n < 10);
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B;
    end
    Y = A;

  • Явным образом ограничьте размер матричного B к 3х3 путем изменения assert оператор:

    function Y = example_mismatch1_fix2(n) %#codegen
    coder.varsize('A');
    assert(n == 3)
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B;
    end
    Y = A;
  • Используйте явную индексацию, чтобы сделать B тот же размер как A:

    function Y = example_mismatch1_fix3(n) %#codegen
    assert(n < 10);
    B = ones(n,n);
    A = magic(3);
    A(1) = mean(A(:));
    if (n == 3)
        A = B(1:3, 1:3);
    end
    Y = A;

Проблема: пустая матрица, измененная форму, чтобы совпадать со спецификацией Переменного Размера

Если вы присваиваете пустой матричный [] к данным переменного размера, MATLAB® может тихо изменить данные в сгенерированном коде, чтобы совпадать с a coder.varsize спецификация. Например:

function Y = test(u) %#codegen
Y = [];
coder.varsize('Y', [1 10]);
if u < 0
    Y = [Y u];
end

В этом примере, coder.varsize задает Y как вектор-столбец до 10 элементов, таким образом, его первая размерность фиксируется в размере 1. Оператор Y = [] определяет первую размерность Y как 0, создавая несоответствие. Правая сторона присвоения является пустой матрицей, и левая сторона является вектором переменного размера. В этом случае MATLAB изменяет пустой матричный Y = [] в сгенерированном коде к Y = zeros(1,0) таким образом, это совпадает с coder.varsize спецификация.

Проблема: присвоение неявно расширенных Выходных параметров к переменной фиксированного размера

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

function out = test(n) %#codegen
x = ones(n,1);
if mod(n,2) == 1
	y = ones(n,n);
	x = y + x;
end 
out = out + x(2);
end

В этом примере, x неограниченный вектор. Из-за неявного расширения, плюс операция на x и y результаты в неограниченной матрице (Inf-by-Inf). Присвоение неограниченной матрицы к x, то, которое является неограниченным вектором, приводит к ошибке.

Если вы хотите использовать неявно расширенный выход, присвойте выход новой переменной с тем же размером как выход.

Если вы хотите, чтобы x сохранил свой размер и не применил неявное расширение в сгенерированном коде, использовать coder.sameSizeBinaryOp (MATLAB Coder), чтобы применить операцию. Можно также вызвать coder.noImplicitExpansionInFunction (MATLAB Coder) в вашем теле функции, чтобы отключить неявное расширение в коде, сгенерированном для этой функции.

Неявное расширение автоматически расширяет операнды, чтобы применить бинарные операции на массивы совместимых размеров. Смотрите Генерируют Код С Неявным расширением, Enabled (MATLAB Coder), Оптимизируют Неявное расширение в Сгенерированном коде (MATLAB Coder) и Совместимые Размеры Массивов для Основных Операций.

Диагностирование и фиксация ошибок в обнаружении верхних границ

Проблема: Используя непостоянные размерности в матричном конструкторе

Можно задать данные переменного размера путем присвоения переменной матрице с непостоянными размерностями. Например:

function y = dims_vary(u) %#codegen
if (u > 0)
    y = ones(3,u);
else
    y = zeros(3,1);
end

Однако компиляция этой функции генерирует ошибку, потому что вы не задавали верхнюю границу для u.

Существует несколько способов решить проблему:

  • Включите динамическое выделение памяти и перекомпилируйте. Во время генерации кода MATLAB не проверяет на верхние границы, когда это использует динамическое выделение памяти для данных переменного размера.

  • Если вы не хотите использовать динамическое выделение памяти, добавьте assert оператор перед первым использованием u:

    function y = dims_vary_fix(u) %#codegen
    assert (u < 20);
    if (u > 0)
        y = ones(3,u);
    else
        y = zeros(3,1);
    end