Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

固定小数点の関数近似

固定小数点ライブラリ関数が使用できない場合、固定小数点アプリケーションにはその関数の近似が必要です。多くの場合、内挿されたルックアップ テーブルを使用して指定範囲の関数近似を保存します。

この例では、ルックアップ テーブルを使用して、指定された入力範囲において関数 y = sin(2*pi*x) を近似する方法を示しています。

この例では、入力は符号なしの 16 ビット データ型 fixdt(0,16,16)、出力は符号付きの 16 ビット データ型 fixdt(1,16,14) を使用します。

この例の目的は、2 進小数点の右側 8 ビットまで正確な近似を作成することです。これは、最悪誤差が 2^(-8) 未満になるようにするということを意味します。

この目標を満たすルックアップ テーブルのデータ点集合は多数あります。メモリ使用量や計算速度といった目標に応じて、異なる実装を選択できます。この例では、最小のデータ点数でこの精度目標を満たすソリューションを見つけます。

関数の近似

FunctionApproximation.Options オブジェクトを使用して精度と語長の制約を指定します。

options = FunctionApproximation.Options();
options.AbsTol = 2^-8;
options.RelTol = 0;
options.WordLengths = [8 16 32];
options.MemoryUnits = 'bytes';
options.OnCurveTableValues = true;

近似する関数と入力範囲、データ型を FunctionApproximation.Problem オブジェクトで指定します。

functionToApproximate = @(x) sin(2*pi*x);

problem = FunctionApproximation.Problem(functionToApproximate, 'Options', options);
problem.InputTypes = numerictype(0,16,16);
problem.InputLowerBounds = 0;
problem.InputUpperBounds = 0.25;
problem.OutputType = numerictype(1,16,14);

ルックアップ テーブルの解を作成します。

solution = solve(problem);
Searching for fixed-point solutions.

|  ID | Memory (bytes) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) | 
|   0 |     4.0000e+00 |        0 |          2 |               8 |            8 |             EvenSpacing |     3.906250e-03, 2.105137e-01 |
|   1 |     1.9000e+01 |        0 |         17 |               8 |            8 |             EvenSpacing |     3.906250e-03, 4.257483e-03 |
|   2 |     3.5000e+01 |        1 |         33 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.848536e-03 |
|   3 |     2.8000e+01 |        1 |         26 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.768435e-03 |
|   4 |     2.4000e+01 |        1 |         22 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.596819e-03 |
|   5 |     2.1000e+01 |        1 |         19 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.589720e-03 |
|   6 |     1.5000e+01 |        0 |         13 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.812500e-03 |
|   7 |     1.7000e+01 |        1 |         15 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.824648e-03 |
|   8 |     1.2000e+01 |        0 |         10 |               8 |            8 |             EvenSpacing |     3.906250e-03, 4.677033e-03 |
|   9 |     1.1000e+01 |        0 |          9 |               8 |            8 |             EvenSpacing |     3.906250e-03, 6.957420e-03 |
|  10 |     1.4000e+01 |        1 |         12 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.687388e-03 |
|  11 |     1.3000e+01 |        0 |         11 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.812500e-03 |
|  12 |     9.0000e+00 |        0 |          7 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.818172e-03 |
|  13 |     6.0000e+00 |        0 |          2 |              16 |            8 |             EvenSpacing |     3.906250e-03, 2.105137e-01 |
|  14 |     1.3000e+01 |        0 |          9 |              16 |            8 |             EvenSpacing |     3.906250e-03, 6.957420e-03 |
|  15 |     6.0000e+00 |        0 |          2 |               8 |           16 |             EvenSpacing |     3.906250e-03, 2.105137e-01 |
|  16 |     4.0000e+00 |        0 |          2 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  17 |     1.1000e+01 |        0 |          9 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|  18 |     6.0000e+00 |        0 |          2 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  19 |     1.3000e+01 |        0 |          9 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|  20 |     6.0000e+00 |        0 |          2 |               8 |           16 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  21 |     8.0000e+00 |        0 |          2 |              16 |           16 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  22 |     1.4000e+01 |        1 |          7 |               8 |            8 |          ExplicitValues |     3.906250e-03, 3.830054e-03 |
|  23 |     3.5000e+01 |        1 |         33 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 3.848536e-03 |

Best Solution
|  ID | Memory (bytes) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) |
|  10 |     1.4000e+01 |        1 |         12 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.687388e-03 |

ブレークポイントの仕様を EvenPow2Spacing に変更し、ルックアップ テーブルの解を再作成します。

problem.Options.BreakpointSpecification = 'EvenPow2Spacing';
bestEvenPow2SpacingSolution = solve(problem);
Searching for fixed-point solutions.

|  ID | Memory (bytes) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) | 
|   0 |     4.0000e+00 |        0 |          2 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|   1 |     1.9000e+01 |        0 |         17 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 4.257483e-03 |
|   2 |     3.5000e+01 |        1 |         33 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 3.848536e-03 |
|   3 |     1.1000e+01 |        0 |          9 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|   4 |     6.0000e+00 |        0 |          2 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|   5 |     2.1000e+01 |        0 |         17 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 4.257483e-03 |
|   6 |     1.3000e+01 |        0 |          9 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|   7 |     6.0000e+00 |        0 |          2 |               8 |           16 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|   8 |     2.0000e+01 |        0 |          9 |               8 |           16 |         EvenPow2Spacing |     3.906250e-03, 4.856432e-03 |

Best Solution
|  ID | Memory (bytes) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) |
|   2 |     3.5000e+01 |        1 |         33 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 3.848536e-03 |

ソリューションの確認

ソフトウェアは、FunctionApproximation.Problem および FunctionApproximation.Options オブジェクトで指定された要件を満たすいくつかの実装を返します。これらのさまざまな実装を確認できます。

feasibleSolutions = solution.FeasibleSolutions;
tableDataVec = [feasibleSolutions.TableData];
evenSpacingSolutions = find([tableDataVec.IsEvenSpacing]);
unevenSpacingSolutions = find(~[tableDataVec.IsEvenSpacing]);

evenSolutionsMemoryUsage   = arrayfun(@(x) x.totalMemoryUsage(), feasibleSolutions(evenSpacingSolutions));
unevenSolutionsMemoryUsage = arrayfun(@(x) x.totalMemoryUsage(), feasibleSolutions(unevenSpacingSolutions));

bestEvenSpacingSolution  = feasibleSolutions(evenSpacingSolutions(evenSolutionsMemoryUsage == min(evenSolutionsMemoryUsage)));
bestUnevenSpacingSolution = feasibleSolutions(unevenSpacingSolutions(unevenSolutionsMemoryUsage == min(unevenSolutionsMemoryUsage)));

xeven = bestEvenSpacingSolution.TableData.BreakpointValues{1};
yeven = bestEvenSpacingSolution.TableData.TableValues;

xuneven = bestUnevenSpacingSolution.TableData.BreakpointValues{1};
yuneven = bestUnevenSpacingSolution.TableData.TableValues;

xpow2 = bestEvenPow2SpacingSolution.TableData.BreakpointValues{1};
ypow2 = bestEvenPow2SpacingSolution.TableData.TableValues;

メモリ使用量の比較

ルックアップ テーブルで使用されるメモリを比較します。

memoryValues = [...
    totalMemoryUsage(bestEvenPow2SpacingSolution), ...
    totalMemoryUsage(bestEvenSpacingSolution), ...
    totalMemoryUsage(bestUnevenSpacingSolution)];

figure();
xTickLabels = {'Even pow2 spacing \newline(fastest)','Even spacing \newline(faster)','Uneven spacing \newline(fast)'};
hMemory = bar(memoryValues);
title('Comparison of memory usage obtained by different \newline breakpoint specification options');
hMemory.Parent.XTickLabel = xTickLabels;
hMemory.Parent.XTickLabelRotation = 45;
hMemory.Parent.YLabel.String = 'Memory (bytes)';
hMemory.Parent.Box = 'on';
hMemory.Parent.YGrid = 'on';

Figure contains an axes object. The axes object with title Comparison of memory usage obtained by different Start 2 by 1 matrix 1st Row 1st Column undefined 2nd Row 1st Column undefined EndMatrix breakpoint specification options, ylabel Memory (bytes) contains an object of type bar.

等間隔を使用する場合と不等間隔を使用する場合でテーブルが使用するメモリの量は同じですが、ポイントの数は異なります。これは、等間隔を使用するテーブルのブレークポイントを保存するときには、最初のポイントと間隔のみが保存されるためです。対照的に、不等間隔を使用するテーブルでは、すべてのブレークポイントが保存されます。

EvenPow2Spacing では、等間隔の場合に保存されるポイントの倍を超えるポイントが保存されます。メモリ使用量の観点では、EvenPow2Spacing はこの関数にとっては最も不適当です。ただし、EvenPow2Spacing での計算は乗算ではなく算術シフトを使用して実行され、それによってより速い実行時間につながります。

ソリューションと元の関数との比較

EvenPow2Spacing を使用するソリューションを元の関数と比較します。

[~, hEvenPow2Spacing] = compare(bestEvenPow2SpacingSolution);
hEvenPow2Spacing.Children(4).Title.String = [hEvenPow2Spacing.Children(4).Title.String ' (Even pow2 spacing)'];

Figure contains 2 axes objects. Axes object 1 with title Comparison of Original Function and Approximation (Even pow2 spacing), xlabel Input, ylabel Function Value contains 2 objects of type line. These objects represent Original, Approximation. Axes object 2 with title Feasibility of Solution: Feasible AbsTol = 0.00390625 RelTol = 0, xlabel Input, ylabel Error contains 3 objects of type area, line. These objects represent Feasible Region : Absolute Error <= Max Error Allowed, Max Error Allowed : max(abs(Original) * RelTol, AbsTol), Absolute Error : abs(Original - Approximation).

等間隔を使用するソリューションを元の関数と比較します。

[~, hEvenSpacing] = compare(bestEvenSpacingSolution);
hEvenSpacing.Children(4).Title.String = [hEvenSpacing.Children(4).Title.String ' (Even spacing)'];

Figure contains 2 axes objects. Axes object 1 with title Comparison of Original Function and Approximation (Even spacing), xlabel Input, ylabel Function Value contains 2 objects of type line. These objects represent Original, Approximation. Axes object 2 with title Feasibility of Solution: Feasible AbsTol = 0.00390625 RelTol = 0, xlabel Input, ylabel Error contains 3 objects of type area, line. These objects represent Feasible Region : Absolute Error <= Max Error Allowed, Max Error Allowed : max(abs(Original) * RelTol, AbsTol), Absolute Error : abs(Original - Approximation).

不等間隔を使用するソリューションを元の関数と比較します。

[~, hUnevenSpacing] = compare(bestUnevenSpacingSolution);
hUnevenSpacing.Children(4).Title.String = [hUnevenSpacing.Children(4).Title.String ' (Uneven spacing)'];

Figure contains 2 axes objects. Axes object 1 with title Comparison of Original Function and Approximation (Uneven spacing), xlabel Input, ylabel Function Value contains 2 objects of type line. These objects represent Original, Approximation. Axes object 2 with title Feasibility of Solution: Feasible AbsTol = 0.00390625 RelTol = 0, xlabel Input, ylabel Error contains 3 objects of type area, line. These objects represent Feasible Region : Absolute Error <= Max Error Allowed, Max Error Allowed : max(abs(Original) * RelTol, AbsTol), Absolute Error : abs(Original - Approximation).

Simulink モデルでの近似の使用

この近似を Simulink Lookup Table (n-D) ブロックで直接使用できます。fxpdemo_approx モデルは、異なるブレークポイント間隔仕様を使用してルックアップ テーブルを比較します。LUT は関数 sin(2*pi*x) を近似します。

modelName = 'fxpdemo_approx';
open_system(modelName)

modelWorkspace = get_param(modelName, 'ModelWorkspace');

modelWorkspace.assignin('xevenFirstPoint'     , xeven(1)  );
modelWorkspace.assignin('xevenSpacing'        , diff(xeven(1:2))  );
modelWorkspace.assignin('yeven'               , yeven  );
modelWorkspace.assignin('TableDTeven'         , bestEvenSpacingSolution.TableData.TableDataType      );
modelWorkspace.assignin('BreakpointDTeven'    , bestEvenSpacingSolution.TableData.BreakpointDataTypes);

modelWorkspace.assignin('xuneven'             , xuneven);
modelWorkspace.assignin('yuneven'             , yuneven);
modelWorkspace.assignin('TableDTuneven'       , bestUnevenSpacingSolution.TableData.TableDataType      );
modelWorkspace.assignin('BreakpointDTuneven'  , bestUnevenSpacingSolution.TableData.BreakpointDataTypes);

modelWorkspace.assignin('xpow2FirstPoint'     , xpow2(1)  );
modelWorkspace.assignin('xpow2Spacing'        , diff(xpow2(1:2))  );
modelWorkspace.assignin('ypow2'               , ypow2  );
modelWorkspace.assignin('TableDTpow2'         , bestEvenPow2SpacingSolution.TableData.TableDataType      );
modelWorkspace.assignin('BreakpointDTpow2'    , bestEvenPow2SpacingSolution.TableData.BreakpointDataTypes);

set_param(modelName, 'Dirty', 'off');

概要

モデル fxpdemo_approx では、理想関数と 3 つの近似が使用されます。モデルをシミュレートします。

sim(modelName)

コードの生成

Simulink® Coder™ がインストールされている場合、モデルのコードを生成できます。インライン パラメーターが ON の場合、不均等な間隔、等間隔、および 2 のべき乗の間隔の実装において効率に大きな違いがあることが、生成されるコードに示されます。