Когда библиотечная функция фиксированной точки не доступна приложения фиксированной точки требуют приближения функции. Часто, интерполированный ищут, таблица используется, чтобы сохранить приближение функции по заданной области.
В этом примере показано, как аппроксимировать функцию y = sin (2*pi*x) по заданному входному диапазону с помощью интерполяционной таблицы.
Смотрите также: FunctionApproximation.Problem, FunctionApproximation.Options
В этом примере вход использует 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 | 9.0000e+00 | 0 | 7 | 8 | 8 | EvenSpacing | 3.906250e-03, 7.818172e-03 | | 10 | 6.0000e+00 | 0 | 2 | 16 | 8 | EvenSpacing | 3.906250e-03, 2.105137e-01 | | 11 | 1.3000e+01 | 0 | 9 | 16 | 8 | EvenSpacing | 3.906250e-03, 6.957420e-03 | | 12 | 6.0000e+00 | 0 | 2 | 8 | 16 | EvenSpacing | 3.906250e-03, 2.105137e-01 | | 13 | 4.0000e+00 | 0 | 2 | 8 | 8 | EvenPow2Spacing | 3.906250e-03, 2.105137e-01 | | 14 | 1.1000e+01 | 0 | 9 | 8 | 8 | EvenPow2Spacing | 3.906250e-03, 6.957420e-03 | | 15 | 6.0000e+00 | 0 | 2 | 16 | 8 | EvenPow2Spacing | 3.906250e-03, 2.105137e-01 | | 16 | 1.3000e+01 | 0 | 9 | 16 | 8 | EvenPow2Spacing | 3.906250e-03, 6.957420e-03 | | 17 | 6.0000e+00 | 0 | 2 | 8 | 16 | EvenPow2Spacing | 3.906250e-03, 2.105137e-01 | | 18 | 8.0000e+00 | 0 | 2 | 16 | 16 | EvenPow2Spacing | 3.906250e-03, 2.105137e-01 | | 19 | 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® 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);