Этот пример показывает, как использовать сгенерированный код, чтобы ускорить приложение, которое вы развертываете с Компилятором MATLAB®. Пример ускоряет алгоритм при помощи MATLAB® Coder™, чтобы сгенерировать версию MEX алгоритма. Это использует MATLAB Compiler, чтобы развернуть автономное приложение, которое вызывает MEX-функцию. Развертываемое приложение использует MATLAB® Runtime, который включает единожды оплачиваемое развертывание кому-то, у кого нет MATLAB.
Этот рабочий процесс полезен когда:
Вы хотите развернуть приложение на платформе, которую поддерживает MATLAB Runtime.
Приложение включает в вычислительном отношении интенсивный алгоритм, который подходит для генерации кода.
Сгенерированный MEX для алгоритма быстрее, чем исходный алгоритм MATLAB.
Вы не должны развертывать читаемый исходный код C/C++ для приложения.
Пример приложения использует алгоритм ЦОС, который требует DSP System Toolbox™.
Для ускорения это - лучшая практика разделить в вычислительном отношении интенсивный алгоритм от кода, который вызывает его.
В этом примере myRLSFilterSystemIDSim
реализует алгоритм. myRLSFilterSystemIDApp
обеспечивает пользовательский интерфейс, который вызывает myRLSFilterSystemIDSim
.
myRLSFilterSystemIDSim
моделирует систему идентификации при помощи рекурсивных наименьших квадратов (RLS) адаптивная фильтрация. Это использует dsp.VariableBandwidthFIRFilter
, чтобы смоделировать неопознанную систему и dsp.RLSFilter
, чтобы идентифицировать КИХ-фильтр.
myRLSFilterSystemIDApp
обеспечивает пользовательский интерфейс, который вы используете, чтобы динамически настроить параметры симуляции. Это запускает симуляцию для конкретного количества временных шагов или пока вы не останавливаете симуляцию. Это строит результаты на осциллографах.
Для получения дополнительной информации об этом приложении, смотрите, что System Identification Использует Адаптивное Просачивание RLS документации DSP System Toolbox.
В перезаписываемой папке создайте myRLSFilterSystemIDSim
и myRLSFilterSystemIDApp
. Также, чтобы получить доступ к этим файлам, нажмите Open Script.
myRLSFilterSystemIDSim
function [tfe,err,cutoffFreq,ff] = ... myRLSFilterSystemIDSim(tuningUIStruct) % myRLSFilterSystemIDSim implements the algorithm used in % myRLSFilterSystemIDApp. % This function instantiates, initializes, and steps through the System % objects used in the algorithm. % % You can tune the cutoff frequency of the desired system and the % forgetting factor of the RLS filter through the GUI that appears when % myRLSFilterSystemIDApp is executed. % Copyright 2013-2017 The MathWorks, Inc. %#codegen % Instantiate and initialize System objects. The objects are declared % persistent so that they are not recreated every time the function is % called inside the simulation loop. persistent rlsFilt sine unknownSys transferFunctionEstimator if isempty(rlsFilt) % FIR filter models the unidentified system unknownSys = dsp.VariableBandwidthFIRFilter('SampleRate',1e4,... 'FilterOrder',30,... 'CutoffFrequency',.48 * 1e4/2); % RLS filter is used to identify the FIR filter rlsFilt = dsp.RLSFilter('ForgettingFactor',.99,... 'Length',28); % Sine wave used to generate input signal sine = dsp.SineWave('SamplesPerFrame',1024,... 'SampleRate',1e4,... 'Frequency',50); % Transfer function estimator used to estimate frequency responses of % FIR and RLS filters. transferFunctionEstimator = dsp.TransferFunctionEstimator(... 'FrequencyRange','centered',... 'SpectralAverages',10,... 'FFTLengthSource','Property',... 'FFTLength',1024,... 'Window','Kaiser'); end if tuningUIStruct.Reset % reset System objects reset(rlsFilt); reset(unknownSys); reset(transferFunctionEstimator); reset(sine); end % Tune FIR cutoff frequency and RLS forgetting factor if tuningUIStruct.ValuesChanged param = tuningUIStruct.TuningValues; unknownSys.CutoffFrequency = param(1); rlsFilt.ForgettingFactor = param(2); end % Generate input signal - sine wave plus Gaussian noise inputSignal = sine() + .1 * randn(1024,1); % Filter input though FIR filter desiredOutput = unknownSys(inputSignal); % Pass original and desired signals through the RLS Filter [rlsOutput , err] = rlsFilt(inputSignal,desiredOutput); % Prepare system input and output for transfer function estimator inChans = repmat(inputSignal,1,2); outChans = [desiredOutput,rlsOutput]; % Estimate transfer function tfe = transferFunctionEstimator(inChans,outChans); % Save the cutoff frequency and forgetting factor cutoffFreq = unknownSys.CutoffFrequency; ff = rlsFilt.ForgettingFactor; end
myRLSFilterSystemIDApp
function scopeHandles = myRLSFilterSystemIDApp(numTSteps) % myRLSFilterSystemIDApp initialize and execute RLS Filter % system identification example. Then, display results using % scopes. The function returns the handles to the scope and UI objects. % % Input: % numTSteps - number of time steps % Outputs: % scopeHandles - Handle to the visualization scopes % Copyright 2013-2017 The MathWorks, Inc. if nargin == 0 numTSteps = Inf; % Run until user stops simulation. end % Create scopes tfescope = dsp.ArrayPlot('PlotType','Line',... 'Position',[8 696 520 420],... 'YLimits',[-80 30],... 'SampleIncrement',1e4/1024,... 'YLabel','Amplitude (dB)',... 'XLabel','Frequency (Hz)',... 'Title','Desired and Estimated Transfer Functions',... 'ShowLegend',true,... 'XOffset',-5000); msescope = dsp.TimeScope('SampleRate',1e4,'TimeSpan',.01,... 'Position',[8 184 520 420],... 'YLimits',[-300 10],'ShowGrid',true,... 'YLabel','Mean-Square Error (dB)',... 'Title','RLSFilter Learning Curve'); screen = get(0,'ScreenSize'); outerSize = min((screen(4)-40)/2, 512); tfescope.Position = [8, screen(4)-outerSize+8, outerSize+8,... outerSize-92]; msescope.Position = [8, screen(4)-2*outerSize+8, outerSize+8, ... outerSize-92]; % Create UI to tune FIR filter cutoff frequency and RLS filter % forgetting factor Fs = 1e4; param = struct([]); param(1).Name = 'Cutoff Frequency (Hz)'; param(1).InitialValue = 0.48 * Fs/2; param(1).Limits = Fs/2 * [1e-5, .9999]; param(2).Name = 'RLS Forgetting Factor'; param(2).InitialValue = 0.99; param(2).Limits = [.3, 1]; hUI = HelperCreateParamTuningUI(param, 'RLS FIR Demo'); set(hUI,'Position',[outerSize+32, screen(4)-2*outerSize+8, ... outerSize+8, outerSize-92]); % Execute algorithm while(numTSteps>=0) S = HelperUnpackUIData(hUI); drawnow limitrate; % needed to process UI callbacks [tfe,err] = myRLSFilterSystemIDSim(S); if S.Stop % If "Stop Simulation" button is pressed break; end if S.Pause continue; end % Plot transfer functions tfescope(20*log10(abs(tfe))); % Plot learning curve msescope(10*log10(sum(err.^2))); numTSteps = numTSteps - 1; end if ishghandle(hUI) % If parameter tuning UI is open, then close it. delete(hUI); drawnow; clear hUI end scopeHandles.tfescope = tfescope; scopeHandles.msescope = msescope; end
Запустите приложение системы идентификации для 100 временных шагов. Выполнение приложения симуляция для 100 временных шагов или пока вы не нажимаете Stop Simulation. Это строит результаты на осциллографах.
scope1 = myRLSFilterSystemIDApp(100); release(scope1.tfescope); release(scope1.msescope);
Когда вы используете MATLAB Coder, чтобы ускорить алгоритм MATLAB, код должен подойти для генерации кода.
1. Убедитесь, что myRLSFilterSystemIDSim.m
включает директиву %#codegen
после функциональной подписи.
Эта директива указывает, что вы намереваетесь сгенерировать код для функции. В редакторе MATLAB это позволяет анализатору кода обнаружить проблемы генерации кода.
2. Экранируйте алгоритм на неподдерживаемые функции или построения.
coder.screener('myRLSFilterSystemIDSim');
Инструмент готовности генерации кода не находит проблемы генерации кода в этом алгоритме.
Ускорять алгоритм, это использование в качестве примера MATLAB Coder команда codegen
. Также можно использовать приложение MATLAB Coder. Для генерации кода необходимо задать тип, размер и сложность входных параметров. Функциональный myRLSFilterSystemIDSim
берет структуру, которая хранит настраивающуюся информацию. Задайте настраивающую структуру в качестве примера и передайте ее codegen
при помощи опции -args
.
ParamStruct.TuningValues = [2400 0.99]; ParamStruct.ValuesChanged = false; ParamStruct.Reset = false; ParamStruct.Pause = false; ParamStruct.Stop = false; codegen myRLSFilterSystemIDSim -args {ParamStruct};
codegen
создает MEX-функцию myRLSFilterSystemIDSim_mex
в текущей папке.
1. Время 100 выполнения myRLSFilterSystemIDSim
.
clear myRLSFilterSystemIDSim disp('Running the MATLAB function ...') tic nTimeSteps = 100; for ind = 1:nTimeSteps myRLSFilterSystemIDSim(ParamStruct); end tMATLAB = toc;
Running the MATLAB function ...
2. Время 100 выполнения myRLSFilterSystemIDSim_mex
.
clear myRLSFilterSystemIDSim disp('Running the MEX function ...') tic for ind = 1:nTimeSteps myRLSFilterSystemIDSim_mex(ParamStruct); end tMEX = toc; disp('RESULTS:') disp(['Time for original MATLAB function: ', num2str(tMATLAB),... ' seconds']); disp(['Time for MEX function: ', num2str(tMEX), ' seconds']); disp(['The MEX function is ', num2str(tMATLAB/tMEX),... ' times faster than the original MATLAB function.']);
Running the MEX function ... RESULTS: Time for original MATLAB function: 2.6775 seconds Time for MEX function: 0.42718 seconds The MEX function is 6.2679 times faster than the original MATLAB function.
Можно иногда генерировать более быстрый MEX при помощи различного компилятора C/C++ или при помощи определенных опций или оптимизации. Смотрите Ускоряют алгоритмы MATLAB (MATLAB Coder).
В данном примере MEX достаточно быстр без дальнейшей оптимизации.
Измените myRLSFilterSystemIDApp
так, чтобы он вызвал myRLSFilterSystemIDSim_mex
вместо myRLSFilterSystemIDSim
.
Сохраните измененную функцию в myRLSFilterSystemIDApp_acc.m
.
clear myRLSFilterSystemIDSim_mex;
scope2 = myRLSFilterSystemIDApp_acc(100);
release(scope2.tfescope);
release(scope2.msescope);
Поведение приложения, которое вызывает MEX-функцию, совпадает с поведением приложения, которое вызывает исходную функцию MATLAB. Однако графики обновляют более быстро, потому что симуляция быстрее.
1. Чтобы открыть Приложение Application Compiler, на вкладке Apps, при Развертывании приложения, кликают по значку приложения.
2. Укажите, что основным файлом является myRLSFilterSystemIDApp_acc
.
Приложение определяет необходимые файлы для этого приложения. Приложение может найти файлы MATLAB и файлы MEX, которые использует приложение. Необходимо добавить другие типы файлов, такие как MAT-файлы или изображения, как требуется файлы.
3. В разделе Packaging Options панели инструментов убедитесь, что Время выполнения, загруженное с веб-флажка, выбрано.
Эта опция создает установщика приложения, который загружает и устанавливает MATLAB Runtime с развернутым приложением MATLAB.
4. Нажмите Package и сохраните проект.
5. В окне Package убедитесь, что Open папка вывода, когда процесс завершает флажок, выбран.
Когда упаковка завершена, выходная папка открывается.
1. Откройте папку for_redistribution
.
2. Запустите MyAppInstaller_web
.
3. Если вы соединяетесь с Интернетом при помощи прокси-сервера, введите настройки сервера.
4. Совершенствуйтесь через страницы мастера установки.
На странице Installation Options используйте папку стандартной установки.
На странице Required Software используйте папку стандартной установки.
На странице Лицензионного соглашения считайте лицензионное соглашение и примите лицензию.
На странице Confirmation нажмите Install.
Если MATLAB Runtime уже не установлен, инсталлятор устанавливает его.
5. Нажмите Finish.
1. Откройте окно терминала.
2. Перейдите к папке, где приложение установлено.
Для Windows® перейдите к C:\Program Files\myRLSFilterSystemIDApp_acc
.
Для macOS перейдите к /Applications/myRLSFilterSystemIDApp_acc
.
Для Linux перейдите к /usr/myRLSFilterSystemIDApp_acc
.
3. Запустите приложение при помощи соответствующей команды для вашей платформы.
Для Windows используйте application\myRLSFilterSystemIDApp_acc
.
Для macOS используйте myRLSFilterSystemIDApp_acc.app/Contents/MacOS/myRLSFilterSystemIDApp_acc
.
Для Linux используйте /myRLSFilterSystemIDApp_acc
.
Запуск приложения занимает приблизительно то же количество времени как стартовый MATLAB.