Code Generation Examples

Apply Window to Input Signal

In this example, apply a Hamming window to an input data vector of size 512x1.

Create a file called window_data.m by typing

>>edit window_data

at the MATLAB® command prompt.

Copy and paste the code provided into the editor and save the file.

function output_data=window_data(input_data,N) %#codegen
Win=hamming(N);
output_data=input_data.*Win;

Use codegen to generate a MEX–file window_data.m.

codegen window_data -args {zeros(512,1),coder.newtype('constant',512)} -o window_data 

The -args option defines the input specifications for the MEX –file. input_data is a 512x1 real valued vector. Because the input to hamming must be a constant, coder.newtype is used to specify the window length. In a conventional MATLAB program, you can read the input data length at runtime and construct a Hamming window of the corresponding length.

Alternatively, edit the code for window_data.m as follows:

function output_data=window_data(input_data) %#codegen
Win=hamming(512);
output_data=input_data.*Win;

The preceding code specifies the length of the Hamming window in the source code as opposed to using coder.newtype. Use codegen to generate a MEX–file and C code:

codegen window_data -args {zeros(512,1)} -o window_data -report 

The -report flag generates a compilation report. If the codegen operation is successful, you obtain: Code generation successful: View report.

Click on View report to view the Code Generation Report.

Select the C-code tab and select window_data.c as the Target Source File.

Note from the location bar that the C source code is in the codegen/mex/<FUNCTION_NAME> folder. Running codegen creates this folder and places the C source code, C header files, and MEX files in the folder. Each function that you create produces a codegen/mex/<FUNCTION_NAME> folder.

Scroll through the C code to see that the values of the Hamming window are included directly in the C source code.

Run the MEX-file on a white noise input:

% Window white noise input
output_data=window_data(randn(512,1));

Apply Lowpass Filter to Input Signal

Assuming a sampling frequency of 20 kHz, create a 4–th order Butterworth filter with a 3–dB frequency of 2.5 kHz. Use the Butterworth filter to lowpass filter a 10000x1 input data vector.

Create a file called ButterFilt.m. Copy and paste the following code into the file.

function output_data=ButterFilt(input_data) %#codegen
[b,a]=butter(4,0.25);
output_data=filter(b,a,input_data);

Run the codegen command to obtain the C source code ButterFilt.c and MEX file:

codegen ButterFilt -args {zeros(10000,1)} -o ButterFilt -report

The C source code includes the five numerator and denominator coefficients of the 4–th order Butterworth filter as constants.

static real_T dv0[5] = { 0.010209480791203124, 0.040837923164812495, 0.061256884747218743, 0.040837923164812495, 0.010209480791203124 };
static real_T dv1[5] = { 1.0, -1.9684277869385174, 1.7358607092088851, -0.72447082950736208, 0.1203895998962444 };

Apply the filter using the MEX-file:

Fs=20000;
%Create 10000x1 input signal
t=0:(1/Fs):0.5-(1/Fs); 
input_data=(cos(2*pi*1000*t)+sin(2*pi*500*t)+0.2*randn(size(t)))';
%Filter data
output_data=ButterFilt(input_data);

Cross Correlate or Autocorrelate Input Data

Estimate the cross correlation or autocorrelation of two real-valued input vectors to lag 50. Output the estimate at the nonnegative lags.

Create a file called myxcorr.m. Copy and paste the following code into the file:

function [C,Lags]=myxcorr(x,y) %#codegen
[c,lags]=xcorr(x,y,50,'coeff');
C=c(51:end);
Lags=lags(51:end);

Run the codegen command at the MATLAB command prompt:

codegen myxcorr -args {zeros(512,1), zeros(512,1)} -o myxcorr -report

Use the MEX-file to compute and plot the autocorrelation of a white noise input:

rng(0,'twister')
%White noise input
input_data=randn(512,1);
%Compute autocorrelation with MEX-file
[C,Lags]=myxcorr(input_data,input_data);
% Plot the result
stem(Lags,C); axis([-0.5 51 -1.1 1.1])
xlabel('Lags'); ylabel('Autocorrelation Function');

freqz With No Output Arguments

In Code Generation from MATLAB, freqz with no output arguments behaves differently than in the standard MATLAB language. In standard MATLAB, freqz with no output arguments produces a plot of the magnitude and phase response of the input filter. The plot is produced regardless of whether the call to freqz terminates in a semicolon or not. No frequency response or phase vectors are returned.

freqz with no output arguments and no terminating semicolon:

B = [0.05 0.9 0.05]; %Numerator coefficients
freqz(B,1) %no semicolon. Plot is produced

freqz with no output arguments and terminating in a semicolon:

B = [0.05 0.9 0.05]; %Numerator coefficients
freqz(B,1); %semicolon. Plot is produced

The behavior shown in the preceding examples differs from the expected behavior of a MEX-file using freqz with code generation support. To illustrate this difference create a program called myfreqz.m.

Copy and paste the following code into the file:

function myfreqz(B,A) %#codegen
freqz(B,A)

Run the following command at the MATLAB command prompt:

codegen myfreqz -args {zeros(1,3), zeros(1,1)} -o myfreqz 

Calling the MEX-file writes a 512x1 complex-valued vector to the workspace and displays the output. The vector is the frequency response. No plot is produced.

myfreqz([0.05 0.9 0.05],1);

Change the code in myfreqz.m by adding a terminating semicolon:

function myfreqz(B,A) %#codegen
freqz(B,A);

Run the following command at the MATLAB command prompt:

codegen myfreqz -args {zeros(1,3), zeros(1,1)} -o myfreqz 

Calling the MEX-file produces a plot of the magnitude and phase response of the filter. The output of the complex-valued frequency response is suppressed.

myfreqz([0.05 0.9 0.05],1);

Zero Phase Filtering

Design a lowpass Butterworth filter with a 1 kHz 3–dB frequency to implement zero phase filtering on data with a sampling frequency of 20 kHz.

[B,A] = butter(20,0.314,'low');

Create the program myZerophaseFilt.m.

function output  = myZerophaseFilt(input) %#codegen
B=1e-3 *[
    0.0000
    0.0001
    0.0010
    0.0060
    0.0254
    0.0814
    0.2035
    0.4071
    0.6615
    0.8820
    0.9702
    0.8820
    0.6615
    0.4071
    0.2035
    0.0814
    0.0254
    0.0060
    0.0010
    0.0001
    0.0000];
A=[1.0000
   -7.4340
   28.2476
  -71.6333
  134.6222
 -197.9575
  235.1628
 -230.2286
  188.0901
 -129.1746
   74.8284
  -36.5623
   15.0197
   -5.1525
    1.4599
   -0.3361
    0.0613
   -0.0085
    0.0009
   -0.0001
    0.0000];
output = filtfilt(B,A,input);

Run the following command at the MATLAB command prompt:

codegen myZerophaseFilt -args {zeros(1,20001)} -o myZerophaseFilt 

Filter input data with myZerophaseFilt:

Fs = 20000;
t = 0:(1/Fs):1;
Comp500Hz = cos(2*pi*500*t);
Signal = Comp500Hz+sin(2*pi*4000*t)+0.2*randn(size(t));
FilteredData = myZerophaseFilt(Signal);
plot(t(1:500).*1000,Comp500Hz(1:500)); 
xlabel('msec'); ylabel('Amplitude');
axis([0 25 -1.8 1.8]); hold on;
plot(t(1:500).*1000,FilteredData(1:500),'r','linewidth',2);
legend('500 Hz component','Zero phase lowpass filtered data',...
'Location','NorthWest');

Was this topic helpful?