Main Content

Generate C Code from Symbolic Expressions Using the MATLAB Coder App

This example shows how to use the MATLAB® Coder™ app to generate a static C library from symbolic expressions. First, you work with symbolic expressions in Symbolic Math Toolbox™, and convert the symbolic expressions into a deployable MATLAB function using matlabFunction. Next, you generate C code from the MATLAB function. The generated C code accepts inputs that have a fixed, preassigned size, but you can also specify variable-size inputs during code generation.

MATLABCoderImage.png

This example follows the steps described in Generate C Code by Using the MATLAB Coder App (MATLAB Coder), but updates the steps to generate a MATLAB function from a symbolic expression. Alternatively, you can generate C code from a MATLAB function at the MATLAB command line by using the codegen (MATLAB Coder) command. For a tutorial on this workflow, see Generate C Code at the Command Line (MATLAB Coder).

Generate Deployable MATLAB Function from Symbolic Expression

This example solves for the eigenvalues of the model Hamiltonian:

H=(q-12-δ2ΩΩδ2+q+12),

where q, Ω, and δ are the parameters of the Hamiltonian.

Create the symbolic variables q, Omega, and delta to represent the parameters of the Hamiltonian. Create a symbolic matrix for the Hamiltonian.

syms q Omega delta
H = [(q-1)^2 - delta/2, Omega; Omega, (q+1)^2 + delta/2]
H = 

(q-12-δ2ΩΩδ2+q+12)

Find the two eigenvalues of the Hamiltonian.

E = eig(H)
E = 

(q2-4Ω2+δ2+8δq+16q22+1q2+4Ω2+δ2+8δq+16q22+1)

Next, convert the two eigenvalues E(1) and E(2) to a MATLAB function file by using matlabFunction. Write the resulting function, which returns two elements E1 and E2, to the file myEigenvalues.m. Specify the order of input arguments as [q Omega delta].

matlabFunction(E(1),E(2),'File','myEigenvalues', ...
    'Vars',[q Omega delta],'Outputs',{'E1','E2'});

The converted function in the file myEigenvalues.m can be used without Symbolic Math Toolbox. The MATLAB file myEigenvalues.m contains the function myEigenvalues that implements the core algorithm in this example. The function takes q, Omega, and delta as inputs, all of which must be either the same size or a scalar. It then calculates the two eigenvalues as a function of these inputs.

type myEigenvalues
function [E1,E2] = myEigenvalues(q,Omega,delta)
%myEigenvalues
%    [E1,E2] = myEigenvalues(Q,Omega,DELTA)

%    This function was generated by the Symbolic Math Toolbox version 25.1.
%    01-Feb-2025 13:36:16

t2 = Omega.^2;
t3 = delta.^2;
t4 = q.^2;
t6 = delta.*q.*8.0;
t5 = t2.*4.0;
t7 = t4.*1.6e+1;
t8 = t3+t5+t6+t7;
t9 = sqrt(t8);
t10 = t9./2.0;
E1 = t4-t10+1.0;
if nargout > 1
    E2 = t4+t10+1.0;
end
end

Run MATLAB Test Script

To calculate the eigenvalues for a set of inputs, create and run the test script myTest.m in MATLAB. The test script specifies the inputs with the following sizes:

  • qGrid is a 128-by-256 matrix that represents points in the two-dimensional (q,Ω) space.

  • OmegaGrid is a 128-by-256 matrix that represents points in the two-dimensional (q,Ω) space.

  • delta is a scalar.

The script then calls the function myEigenvalues.m to compute the eigenvalues. The output displays a plot of the eigenvalues for these input values. Below is the content of the script myTest.m.

q = linspace(-2,2,256);
Omega = linspace(0,2,128);
delta = 1;

[qGrid,OmegaGrid] = meshgrid(q,Omega);
[E1,E2] = myEigenvalues(qGrid,OmegaGrid,delta);

surf(q,Omega,E1)
hold on;
surf(q,Omega,E2)
shading interp

Figure contains an axes object. The axes object contains 2 objects of type surface.

Generate C Code from MATLAB Function

Make MATLAB Code Suitable for Code Generation

The Code Analyzer in the MATLAB Editor continuously checks your code as you enter it. It reports issues and recommends modifications to maximize performance and maintainability.

  • Open myEigenvalues.m in the MATLAB Editor. After the function declaration, add the %#codegen directive:

  • The Code Analyzer message indicator in the top right corner of the MATLAB Editor is green. The analyzer did not detect errors, warnings, or opportunities for improvement in the code. For more information about using the Code Analyzer, see Check Code for Errors and Warnings Using the Code Analyzer.

  • Save the file. You are now ready to compile your code by using the MATLAB Coder app. Here, compilation refers to the generation of C/C++ code from your MATLAB code.

Open MATLAB Coder App and Create Project File

To generate code using the MATLAB Coder app, you must first create a MATLAB Coder project file (that has the extension .coderprj). This file contains the information that you provide to the code generator, including paths of MATLAB Coder entry-point functions, their input types, global variables, and the code generation configuration parameters.

  • On the MATLAB toolstrip Apps tab, under Code Generation, click the MATLAB Coder app icon. The app opens the Create MATLAB Coder Project dialog box.

  • Provide the name of the project file and the folder in which you want to place the file. For this example, create a file named myEigenvalues.coderprj in your current working folder.

A MATLAB Coder toolstrip opens that contains sections that correspond to the primary actions you perform when generating code, including preparing your MATLAB code for C/C++ code generation, generating code, performing verification on generated code, viewing the code generation report, and exporting the generated code.

A code generation panel also opens that contains a Next Steps section which displays messages to guide you thorough the code generation steps, an Input section, and an Output section.

Specify MATLAB Entry-Point Functions

An entry-point function is a top-level MATLAB function from which you generate code. For this example, your entry-point function is myEigenvalues.

In this state of the MATLAB Coder app, the Next Steps section of the code generation panel indicates that you must add an entry-point to the empty project you just created.

To add an entry-point function:

  • Either click the Add Entry Points button in the Inputs section of the code generation panel or the Entry Points button in the toolstrip.

  • The Entry Points pane opens. Enter the name of your entry-point function myEigenvalues.

The app runs the Code Generation Readiness Tool on the entry-point function. This tool screens the MATLAB code for features and functions that are not supported for code generation. If the app identifies issues with an entry-point function or one of its dependencies, the Entry Points pane shows a warning message. Click the link next to the message to open the Code Generation Readiness Tool in a separate window where you can review and fix the issues. In this example, the app does not detect code generation readiness issues. For more information, see Code Generation Readiness Tool (MATLAB Coder).

Note that the Code Analyzer and the Code Generation Readiness Tool might not detect all code generation issues. After eliminating the errors or warnings that these two tools detect, generate code with MATLAB Coder to determine if your MATLAB code has other compliance issues.

Certain MATLAB functions and objects that are supported for C/C++ code generation have specific code generation limitations. These limitations and related usage notes are listed in the Extended Capabilities sections of their corresponding reference pages. For more information, see Functions and Objects Supported for C/C++ Code Generation (MATLAB Coder).

Define Input Types

Because C/C++ uses static typing, the code generator must determine the class, size, and other properties (such as complexity) of all variables in the MATLAB files at code generation time, also known as compile time. Therefore, you must specify the properties of all entry-point function inputs. To specify input properties, you can:

  • Instruct the app to automatically determine input properties by providing a script that calls the entry-point functions with sample inputs.

  • Specify properties directly.

In this example, to define the properties of the inputs q, Omega, and Delta, specify the test file myTest.m that the code generator can use to define types automatically:

  • In the Entry Points pane, set the Automatically Define Input Types parameter to Using Script.

  • Enter or select the test file myTest.m and click the run button.

The test file, myTest.m, calls the entry-point function, myEigenvalues, with the expected input types. The app determines that the input q is a double 128-by-256 array, the input Omega is a double 128-by-256 array, and the input delta is a double 1-by-1 scalar.

Generate C Source Code

  • In the Prepare section of the MATLAB Coder toolstrip, make sure that Output is set to C and Build type is set to Static Library (.lib) (these are the default settings). Use the default values for the other code configuration settings as well.

  • Click the Generate Code button either in the toolstrip or in the Output section of the code generation panel. MATLAB Coder generates C source files for your project in the work\codegen\lib\myEigenvalues folder, where work is the folder that contains your tutorial files. The Output section of the code generation panel indicates that code generation succeeded. This section also contains links to the generated output folder and the code generation report.

  • Click the Code Generation Report link to view the report in the Report Viewer. If the code generator detects errors or warnings during code generation, the report describes the issues and provides links to the problematic MATLAB code. For more information, see Code Generation Reports (MATLAB Coder).

Clicking the Generate Code button generates source code only and does not build the source code to create binaries. To both generate source code and build binaries in a single step, open the Generate Code drop-down menu and select the Generate Code and Build option. Also, instead of generating a C static library, you can choose to generate a MEX function or other C/C++ build types. Different code configuration settings are available for the MEX and C/C++ build types. When you switch between MEX and C/C++ code generation, verify the settings that you choose.

To convert MATLAB code to efficient C/C++ code, the code generator introduces optimizations that, in certain situations, cause the generated code to behave differently than the original MATLAB code. See Differences Between Generated Code and MATLAB Code (MATLAB Coder).

Verify Using MEX

The Verify Using MEX toolstrip button generates a MEX function from your entry-point functions, runs the MEX function, and reports issues. A MEX function is generated code that can be called from inside MATLAB. It is a best practice to perform this step because you can detect and fix run-time errors that are harder to diagnose in the generated standalone C/C++ code. By default, the MEX function includes memory integrity checks. These checks perform array bounds and dimension checking. The checks detect violations of memory integrity in code generated for MATLAB functions. For more information, see Control Run-Time Checks (MATLAB Coder).

  • In the MATLAB Coder toolstrip, open the Verify Using MEX drop-down menu.

  • Specify a test file that calls the entry-point function with example inputs. For this example, use the test file myTest.m that you used to define the input types.

The app generates a MEX function. It runs the test script myTest replacing calls to myEigenvalues with calls to the generated MEX. If the app detects issues during the MEX function generation or execution, it provides warning and error messages in the Command Window. Click these messages to navigate to the problematic code and fix the issue. In this example, the app does not detect issues and shows this message in the Output section of the code generation panel.

Note that before generating standalone C/C++ code from your MATLAB code, generate a MEX function. Run the generated MEX function and make sure it has the same run-time behavior as your MATLAB function. If the generated MEX function produces answers that are different from MATLAB, or produces an error, you must fix these issues before proceeding to standalone code generation. Otherwise, the standalone code that you generate might be unreliable and have undefined behavior.

Compare Generated C Code to Original MATLAB Code

To compare your generated C code to the original MATLAB code, open the C file, myEigenvalues.c, and the myEigenvalues.m file in the MATLAB Editor.

Important information about the generated C code:

  • The function signature is:

void myEigenvalues(const double q[32768], const double Omega[32768],
                   double delta, double E1[32768], double E2[32768])
  • const double q[32768] and const double Omega[32768] corresponds to the input q and Omega in your MATLAB code. The size of q is 32768, which corresponds to the total size (128 x 256) of the example input that you used when you generated C/C++ code from your MATLAB code. The same applies to the input Omega. In this case, the generated code uses one-dimensional arrays to represent two-dimensional arrays in the MATLAB code.

  • The code generator preserves your function name and comments. When possible, the code generator preserves your variable names. Note that if a variable in your MATLAB code is set to a constant value, it does not appear as a variable in the generated C code. Instead, the generated C code contains the value of the variable.

Generate C Code for Variable-Size Inputs

The C function that you generated for myEigenvalues.m can accept only inputs that have the same size as the sample inputs that you specified during code generation. However, the input arrays to the corresponding MATLAB function can be of any size. In this part of the example, you generate C code from myEigenvalues.m that accepts variable-size inputs.

Suppose that you want the dimensions of q, Omega, and delta in the generated C code to have these properties:

  • The first dimension of both q and delta can vary in size up to 100.

  • The second dimension of q and delta can vary in size up to 400.

  • Omega is a scalar of size 1-by-1.

To specify these input properties:

  1. In the Entry Points pane, enter the test file myTest.m and click Automatically Define Input Types as before. The test file calls the entry-point function, myEigenvalues, with the expected input types. The app determines that the input q is a double 128-by-256 array, the input Omega is a double 128-by-256 array, and the input delta is a double 1-by-1 scalar. These types specify fixed-size inputs.

  2. Click the input type specifications to edit them. You can specify variable size, up to a specified limit, by using the : prefix. For example, :100 specifies that the corresponding dimension can vary in size up to 100. Change the type for q to double(:100 x :400), for Omega to double(1 x 1), and for delta to double(:100 x :400).

You can now generate code by following the same steps as before. The function signature for the generated C code in myEigenvalues.c now reads:

void myEigenvalues(const emxArray_real_T *q, double Omega,
                   const emxArray_real_T *delta, emxArray_real_T *E1,
                   emxArray_real_T *E2)

The arguments in the generated code correspond to these arguments in the original MATLAB function:

  • emxArray_real_T*q — the q input argument

  • Omega — the Omega input argument

  • emxArray_real_T*delta — the delta input argument

  • emxArray_real_T*E1 — the E1 output argument

  • emxArray_real_T*E2 — the E2 output argument