В этом примере показано, как использовать сгенерированный код для ускорения развертывания приложения с помощью MATLAB ® Compiler. Пример ускоряет алгоритм с помощью Coder™ MATLAB ®, чтобы сгенерировать версию 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
предоставляет пользовательский интерфейс, который используется для динамической настройки параметров симуляции. Он запускает симуляцию для заданного количества временных шагов или пока вы не остановите симуляцию. Он строит графики результатов симуляции на возможностях.
Для получения дополнительной информации об этом приложении смотрите Систему идентификации с использованием адаптивной фильтрации RLS (DSP System Toolbox) в документации 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 = timescope('SampleRate',1e4,... 'Position',[8 184 520 420],... 'TimeSpanSource','property','TimeSpan',0.01,... '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};
Code generation successful.
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: 1.8853 seconds Time for MEX function: 0.29186 seconds The MEX function is 6.4595 times faster than the original MATLAB function.
Иногда можно сгенерировать более быстрый MEX, используя другой компилятор C/C + + или используя определенные опции или оптимизации. См. «Ускорение алгоритмов MATLAB».
В данном примере 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, на вкладке Приложения, в разделе Развертывание приложения, щелкните значок приложения.
2. Укажите, что основной файл myRLSFilterSystemIDApp_acc
.
Приложение определяет необходимые файлы для этого приложения. Приложение может найти файлы MATLAB и файлы MEX, которые использует приложение. Вы должны добавить другие типы файлов, такие как MAT-файлы или изображения, как необходимые файлы.
3. В разделе «Опции упаковки» панели инструментов убедитесь, что установлен флажок Runtime downloaded from web.
Эта опция создаёт программу установки приложения, которая загружает и устанавливает MATLAB Runtime с помощью развернутого приложения MATLAB.
4. Щелкните Пакет и сохраните проект.
5. В окне Пакет убедитесь, что установлен флажок Открыть выходную папку при завершении процесса.
Когда упаковка будет завершена, откроется папка выхода.
1. Откройте for_redistribution
папка.
2. Выполняйте MyAppInstaller_web
.
3. Если вы подключаетесь к Интернету с помощью прокси-сервера, введите настройки сервера.
4. Пройдите по страницам мастера установки.
На странице Опции установки используйте папку установки по умолчанию.
На странице «Необходимое программное обеспечение» используйте папку установки по умолчанию.
На странице Лицензионное соглашение ознакомьтесь с лицензионным соглашением и примите лицензию.
На странице Подтверждение нажмите Установить.
Если MATLAB Runtime еще не установлен, инсталлятор устанавливает его.
5. Нажмите Конец.
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.