exponenta event banner

Сгенерированный код с фиксированной точкой

Расположение созданных файлов с фиксированной точкой

По умолчанию процесс преобразования с фиксированной точкой создает файлы в папке с именем codegen/fcn_name/fixpt в локальной рабочей папке. fcn_name - имя функции MATLAB ®, преобразуемой в фиксированную точку.

Имя файлаОписание
fcn_name_fixpt.m

Сгенерированный код MATLAB с фиксированной точкой.

Чтобы интегрировать этот код с фиксированной точкой в более крупное приложение, попробуйте создать MEX-функцию для функции и вызвать эту MEX-функцию вместо исходного кода MATLAB.

fcn_name_fixpt_exVal.mat

MAT-файл, содержащий:

  • Структура для входных аргументов.

  • Имя файла с фиксированной точкой.

fcn_name_fixpt_report.html

Ссылка на отчет по предложениям типа, в котором отображается сгенерированный код с фиксированной точкой и информация о предлагаемом типе.

fcn_name_report.html

Ссылка на отчет о предложении типа, в котором отображается исходный код MATLAB и информация о предлагаемом типе.

fcn_name_wrapper_fixpt.m

Файл, преобразующий значения данных с плавающей запятой, предоставленные тестовым файлом, в типы с фиксированной запятой, определенные для входных данных на этапе преобразования. Эти значения с фиксированной точкой подаются в преобразованную функцию с фиксированной точкой. fcn_name_fixpt.

Уменьшение fi-casts для улучшения читаемости кода

Процесс преобразования пытается уменьшить количество fi-casts путем анализа кода с плавающей запятой. Если арифметическая операция состоит только из констант времени компиляции, процесс преобразования не приводит операнды к фиксированной точке по отдельности. Вместо этого оно помещает все выражение в фиксированную точку.

Например, вот код с фиксированной точкой, сгенерированный для константного выражения x = 1/sqrt(2) когда длина выбранного слова равна 14.

Исходный код MATLABСгенерированный код с фиксированной точкой

x = 1/sqrt(2);

x = fi(1/sqrt(2), 0, 14, 14, fm);

fm является локальным fimath.

Предотвращение переполнений в сгенерированном коде с фиксированной точкой

Процесс преобразования позволяет избежать переполнения:

  • Использование арифметики полной точности, если не указано иное.

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

  • Исключение переполнения при добавлении и вычитании переменных без фиксированных точек и переменных с фиксированными точками.

    Процесс преобразования с фиксированной точкой приводит к отсутствиюfi выражения к соответствующему fi тип.

    Например, рассмотрим следующий алгоритм MATLAB.

    % A = 5;
    % B = ones(300, 1)
    function y = fi_plus_non_fi(A, B)
      % '1024' is non-fi, cast it
      y = A + 1024;
      % 'size(B, 1)*length(A)' is a non-fi, cast it
      y = A + size(B, 1)*length(A);
    end

    Генерируемый код с фиксированной точкой:

    %#codegen
    % A = 5;
    % B = ones(300, 1)
    function y = fi_plus_non_fi_fixpt(A, B)
      % '1024' is non-fi, cast it
      fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);
    
      y = fi(A + fi(1024, 0, 11, 0, fm), 0, 11, 0, fm);
      % 'size(B, 1)*length(A)' is a non-fi, cast it
      y(:) = A + fi(size(B, fi(1, 0, 1, 0, fm))*length(A), 0, 9, 0, fm);
    end

Управление ростом битов

Процесс преобразования управляет ростом битов, используя подстрочные назначения, то есть назначения, использующие оператор двоеточия (:), в сгенерированном коде. При использовании назначений с подстрочными индексами MATLAB перезаписывает значение левого аргумента, но сохраняет существующий тип данных и размер массива. Использование подстрочного назначения сохраняет фиксированную точку переменных с фиксированной точкой, а не непреднамеренно превращает их в двойные. Сохранение типа с фиксированной точкой уменьшает количество объявлений типов в сгенерированном коде. Подстрочное назначение также предотвращает рост битов, что полезно, когда требуется сохранить определенный тип данных для вывода.

Предотвращение потери диапазона или точности

Предотвращение потери диапазона или точности при операциях вычитания без знака

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

Например, рассмотрим следующий алгоритм MATLAB.

% A = 1;
% B = 5
function [y,z] = unsigned_subtraction(A,B)
  y = A - B;
  
  C = -20;
  z = C - B;
end

В исходном коде оба A и B не подписаны и результат A-B может быть отрицательным. В сгенерированном коде с фиксированной точкой A повышен до подписанного. В исходном коде C подписан, поэтому не требует повышения в сгенерированном коде.

%#codegen
% A = 1;
% B = 5
function [y,z] = unsigned_subtraction_fixpt(A,B)
 
fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);
y = fi(fi_signed(A) - B, 1, 3, 0, fm);
C = fi(-20, 1, 6, 0, fm);
z = fi(C - B, 1, 6, 0, fm);
end
 
 
function y = fi_signed(a)
coder.inline( 'always' );
if isfi( a ) && ~(issigned( a ))
  nt = numerictype( a );
  new_nt = numerictype( 1, nt.WordLength + 1, nt.FractionLength );
  y = fi( a, new_nt, fimath( a ) );
else
  y = a;
end
end

Предотвращение потери диапазона при конкатенации массивов чисел с фиксированной точкой

При конкатенации матриц с помощью vertcat и horzcat, процесс преобразования использует самый большой числовой тип среди выражений строки и отбрасывает самый левый элемент на этот тип. Этот тип затем используется для конкатенированной матрицы, чтобы избежать потери диапазона.

Например, рассмотрим следующий алгоритм MATLAB.

% A = 1, B = 100, C = 1000
function [y, z] = lb_node(A, B, C)
  %% single rows
  y = [A B C];
  %% multiple rows
  z = [A 5; A B; A C];
end

В сгенерированном коде с фиксированной точкой:

  • Для выражения y = [A B C], самый левый элемент, A, приводится к типу C потому что C имеет самый большой тип в строке.

  • Для выражения [A 5; A B; A C]:

    • В первой строке, A приводится к типу C потому что C имеет наибольший тип целого выражения.

    • Во втором ряду, A приводится к типу B потому что B имеет больший тип в строке.

    • В третьем ряду, A приводится к типу C потому что C имеет больший тип в строке.

%#codegen
% A = 1, B = 100, C = 1000
function [y, z] = lb_node_fixpt(A, B, C)
  %% single rows
  fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);

  y = fi([fi(A, 0, 10, 0, fm) B C], 0, 10, 0, fm);
  
  %% multiple rows
  z = fi([fi(A, 0, 10, 0, fm) 5; fi(A, 0, 7, 0, fm) B; fi(A, 0, 10, 0, fm) C], 0, 10, 0, fm);
end

Обработка непостоянных показателей мощности

Если преобразуемая функция имеет скалярный ввод, и mpower ввод экспоненты не является постоянным, процесс преобразования устанавливает fimath ProductMode кому SpecifyPrecision в созданном коде. С помощью этой настройки можно определить тип выходных данных во время компиляции.

Например, рассмотрим следующий алгоритм MATLAB.

% a = 1
% b = 3
function y = exp_operator(a, b)
  % exponent is a constant so no need to specify precision
  y = a^3;
  % exponent is not a constant, use 'SpecifyPrecision' for 'ProductMode'
  y = b^a;
end

В сгенерированном коде с фиксированной точкой для выражения y = a^3 , экспонента является константой, поэтому нет необходимости задавать точность. Для выражения: y = b^a, экспонента не является постоянной, поэтому ProductMode имеет значение SpecifyPrecision.

%#codegen
% a = 1
% b = 3
function y = exp_operator_fixpt(a, b)
  % exponent is a constant so no need to specify precision
  fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);

  y = fi(a^3, 0, 2, 0, fm);
  % exponent is not a constant, use 'SpecifyPrecision' for 'ProductMode'
  y(:) = fi(b, 'ProductMode', 'SpecifyPrecision', 'ProductWordLength', 2, 'ProductFractionLength', 0 )^a;
end