Main Content

生成された固定小数点コード

生成された固定小数点ファイルの場所

既定では、固定小数点変換プロセスによってローカル作業フォルダーの 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-cast の最小化によるコードの可読性の向上

変換プロセスでは、浮動小数点コードを解析して fi-cast の数の削減を試みます。算術演算がコンパイル時の定数のみで構成されている場合、変換プロセスではオペランドを固定小数点に個別にキャストしません。代わりに、式全体を固定小数点にキャストします。

たとえば、定数式 x = 1/sqrt(2) 用に生成された次の固定小数点コードがあります。選択された語長は 14 です。

元の MATLAB コード生成された固定小数点コード

x = 1/sqrt(2);

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

fm はローカルな fimath です。

生成された固定小数点コード内でのオーバーフローの回避

変換プロセスでは、以下の方法によってオーバーフローを回避します。

  • 指定しない限り、完全精度の算術を使用。

  • double および fi データ型を含む算術演算を回避。それ以外に、fi データ型の語長が double 定数式の値を表すことができない場合、オーバーフローが発生します。

  • 固定小数点以外の変数と固定小数点の変数の加算と減算を行うときにオーバーフローを回避する。

    固定小数点変換プロセスは 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 は左辺引数の値を上書きしますが、既存のデータ型と配列サイズは保持します。添字による代入を使用すると、固定小数点変数は誤って double に変換されることなく固定小数点として維持されます。固定小数点型が維持されるため、生成済みのコード内で型宣言の数が減少します。また、添字による代入はビット成長の発生を防ぐため。特定の出力データ型を維持する場合に便利です。

範囲または精度の損失の回避

符号なし減算の演算における範囲または精度の損失の回避

減算の結果が負の場合、変換プロセスは左オペランドを符号付きの型にプロモートします。

たとえば、次の MATLAB アルゴリズムを考えます。

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

元のコードでは AB は両方とも符号なしですが、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] については、C が行の中で最大の型であるため、左端の要素 AC の型にキャストされます。

  • [A 5; A B; A C] については次のようになります。

    • 最初の行では C が式全体で最大の型であるため、AC の型にキャストされます。

    • 2 番目の行では B が行の中で最大の型であるため、AB の型にキャストされます。

    • 3 番目の行では C が行の中で最大の型であるため、AC の型にキャストされます。

%#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 の指数の処理

変換する関数にスカラーの入力があり、mpower の指数入力が定数でない場合、変換プロセスは生成されたコードで fimathProductModeSpecifyPrecision に設定します。この設定では、出力のデータ型はコンパイル時に決定できます。

たとえば、次の 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 については指数が定数でないため、ProductModeSpecifyPrecision に設定されます。

%#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