Приближение функций фиксированной точки

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

В этом примере показано, как аппроксимировать функцию y = sin (2*pi*x) по заданному входному диапазону с помощью интерполяционной таблицы.

Смотрите также: Функциональная аппроксимация., FunctionApproximation. Опции

В этом примере вход использует 16-битный тип данных без знака, fixdt(0,16,16), и выход использует 16-битный тип данных со знаком, fixdt(1,16,14).

Цель этого примера состоит в том, чтобы создать приближение, которое является с точностью до 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);

% Create a LUT solution
solution = solve(problem);

% Change breakpoint specification to EvenPow2Spacing and create a LUT
% solution again
problem.Options.BreakpointSpecification = 'EvenPow2Spacing';
bestEvenPow2SpacingSolution = solve(problem);
|  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 |     2.1000e+01 |        1 |         19 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.589720e-03 |
|   2 |     1.9000e+01 |        0 |         17 |               8 |            8 |             EvenSpacing |     3.906250e-03, 4.257483e-03 |
|   3 |     1.7000e+01 |        1 |         15 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.824648e-03 |
|   4 |     1.5000e+01 |        0 |         13 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.812500e-03 |
|   5 |     1.2000e+01 |        0 |         10 |               8 |            8 |             EvenSpacing |     3.906250e-03, 4.677033e-03 |
|   6 |     1.1000e+01 |        0 |          9 |               8 |            8 |             EvenSpacing |     3.906250e-03, 6.957420e-03 |
|   7 |     1.4000e+01 |        1 |         12 |               8 |            8 |             EvenSpacing |     3.906250e-03, 3.687388e-03 |
|   8 |     1.3000e+01 |        0 |         11 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.812500e-03 |
|   9 |     6.0000e+00 |        0 |          2 |              16 |            8 |             EvenSpacing |     3.906250e-03, 2.127109e-01 |
|  10 |     4.0000e+00 |        0 |          2 |               8 |            8 |             EvenSpacing |     3.906250e-03, 2.127109e-01 |
|  11 |     1.3000e+01 |        0 |          9 |              16 |            8 |             EvenSpacing |     3.906250e-03, 7.097083e-03 |
|  12 |     1.1000e+01 |        0 |          9 |               8 |            8 |             EvenSpacing |     3.906250e-03, 7.097083e-03 |
|  13 |     6.0000e+00 |        0 |          2 |               8 |           16 |             EvenSpacing |     3.906250e-03, 2.105137e-01 |
|  14 |     4.0000e+00 |        0 |          2 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  15 |     1.1000e+01 |        0 |          9 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|  16 |     6.0000e+00 |        0 |          2 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  17 |     1.3000e+01 |        0 |          9 |              16 |            8 |         EvenPow2Spacing |     3.906250e-03, 6.957420e-03 |
|  18 |     6.0000e+00 |        0 |          2 |               8 |           16 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  19 |     8.0000e+00 |        0 |          2 |              16 |           16 |         EvenPow2Spacing |     3.906250e-03, 2.105137e-01 |
|  20 |     1.4000e+01 |        1 |          7 |               8 |            8 |          ExplicitValues |     3.906250e-03, 3.830054e-03 |

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

|  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 |     3.5000e+01 |        1 |         33 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 3.848536e-03 |
|   2 |     1.9000e+01 |        0 |         17 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 4.257483e-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) |
|   1 |     3.5000e+01 |        1 |         33 |               8 |            8 |         EvenPow2Spacing |     3.906250e-03, 3.848536e-03 |

Исследуйте решения

%The software returns several implementations that meet the requirements
%specified in the |FunctionApproximation.Problem| and
%|FunctionApproximation.Options| objects. You can explore these different
%implementations.

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';

Объем памяти, используемый таблицами, использующими даже интервал и неравномерный интервал, является тем же самым, но число точек отличается. Это вызвано тем, что при хранении точек останова для таблиц, использующих даже интервал, только, первая точка и интервал хранятся. В отличие от этого все точки останова хранятся для таблиц с помощью неравномерного интервала.

Даже хранилища разрядки pow2 более чем удваивают точки, сохраненные для того, чтобы даже расположить с интервалами. С точки зрения использования памяти, даже pow2 интервал наименее оптимально для этой функции. Однако расчеты для даже pow2 интервал выполняются с помощью арифметических сдвигов вместо умножения, которое может привести к более быстрым временам выполнения.

Сравните решения исходной функции

Сравните решение, использующее даже pow2 располагающий с интервалами к исходной функции.

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

Сравните решение, использующее даже располагающий с интервалами к исходной функции.

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

Сравните решение с помощью неравномерного интервала для исходной функции.

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

Используйте приближение в модели Simulink®

Можно использовать это приближение непосредственно в Simulink® Lookup Table (n-D) блок.

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. Если вам установили Simulink® Coder™, можно сгенерировать код для модели. Если встроенные параметры будут включены, сгенерированный код покажет большие различия в КПД в реализации неравномерно расположенного с интервалами, равномерно распределенного, и степень 2 интервалов.

sim(modelName)

Очистка

close_system(modelName, 0);
Для просмотра документации необходимо авторизоваться на сайте