Products & Services Solutions Academia Support User Community Company

Learn more about Symbolic Math Toolbox   

Generating Code from Symbolic Expressions

Generating C or Fortran Code

You can generate C or Fortran code fragments from a symbolic expression, or generate files containing code fragments, using the ccode and fortran functions. These code fragments calculate numerical values as if substituting numbers for variables in the symbolic expression.

To generate code from a symbolic expression g, enter either ccode(g) or fortran(g).

For example:

syms x y
z = 30*x^4/(x*y^2 + 10) - x^3*(y^2 + 1)^2;
fortran(z)
ans =
      t0 = (x**4*30)/(x*y**2+10)-x**3*(y**2+1)**2
ccode(z)
ans =
  t0 = ((x*x*x*x)*3.0E1)/(x*(y*y)+1.0E1)-(x*x*x)*pow(y*y+1.0,2.0);

To generate a file containing code, either enter ccode(g,'file','filename') or fortran(g,'file','filename'). For the example above,

fortran(z, 'file', 'fortrantest')

generates a file named fortrantest in the current directory. fortrantest consists of the following:

      t12 = x**2
      t13 = y**2
      t14 = t13+1
      t0 = (t12**2*30)/(t13*x+10)-t12*t14**2*x

Similarly, the command

ccode(z,'file','ccodetest')

generates a file named ccodetest that consists of the lines

  t16 = x*x;
  t17 = y*y;
  t18 = t17+1.0;
  t0 = ((t16*t16)*3.0E1)/(t17*x+1.0E1)-t16*(t18*t18)*x;

ccode and fortran generate many intermediate variables. This is called optimized code. Intermediate variables can make the resulting code more efficient by reusing intermediate expressions (such as t12 in fortrantest, and t16 in ccodetest). They can also make the code easier to read by keeping expressions short.

Generating MATLAB Function Handles and M-Files

You can use matlabFunction to generate a MATLAB function handle that calculates numerical values as if you were substituting numbers for variables in a symbolic expression. You also can use matlabFunction to generate an M-file for calculating these numerical values. The generated M-file is available for use in any MATLAB calculation, whether or not the computer running the file has a license for Symbolic Math Toolbox functions.

Symbolic Math Toolbox with a Maple™ engine does not support matlabFunction. For details, see Differences in Functionality When Using MuPAD and Maple Engines.

Generating a Function Handle

matlabFunction can generate a function handle from any symbolic expression. For example:

syms x y
r = sqrt(x^2 + y^2);
ht = matlabFunction(tanh(r))
ht = 
    @(x,y)tanh(sqrt(x.^2+y.^2))

You can use this function handle to calculate numerically:

ht(.5,.5)
ans =
    0.6089

You can pass the usual MATLAB double-precision numbers or matrices to the function handle. For example:

cc = [.5,3]; 
dd = [-.5,.5];
ht(cc, dd)
ans =
    0.6089    0.9954

Controlling the Order of Variables

matlabFunction generates input variables in alphabetical order from a symbolic expression. That is why the function handle in Generating a Function Handle has x before y:

ht = @(x,y)tanh((x.^2 + y.^2).^(1./2))

You can specify the order of input variables in the function handle using the vars option. You specify the order by passing a cell array of strings or symbolic arrays, or a vector of symbolic variables. For example:

syms x y z
r = sqrt(x^2 + 3*y^2 + 5*z^2);
ht1 = matlabFunction(tanh(r), 'vars', [y x z])
ht1 = 
    @(y,x,z)tanh(sqrt(x.^2+y.^2.*3.0+z.^2.*5.0))
ht2 = matlabFunction(tanh(r), 'vars', {'x', 'y', 'z'})
ht2 = 
    @(x,y,z)tanh(sqrt(x.^2+y.^2.*3.0+z.^2.*5.0))
ht3 = matlabFunction(tanh(r), 'vars', {'x', [y z]})
ht3 = 
    @(x,in2)tanh(sqrt(x.^2+in2(:,1).^2.*3.0+in2(:,2).^2.*5.0))

Generating an M-File

You can generate an M-file from a symbolic expression, in addition to a function handle. Specify the file name using the file option. Pass a string containing the file name or the path to the file. If you do not specify the path to the file, matlabFunction creates this file in the current directory.

This example generates an M-file that calculates the value of the symbolic matrix F for double-precision inputs t, x, and y:

syms x y t
z = (x^3 - tan(y))/(x^3 + tan(y));
w = z/(1 + t^2);
F = [w,(1 + t^2)*x/y; (1 + t^2)*x/y,3*z - 1];
matlabFunction(F,'file','testMatrix.m')

The file testMatrix.m contains the following code:

function F = testMatrix(t,x,y)
%TESTMATRIX
%    F = TESTMATRIX(T,X,Y)

%    This function was generated
%    by the Symbolic Math Toolbox version 5.2.
%    07-Nov-2008 12:00:32

t2 = x.^2;
t3 = tan(y);
t4 = t2.*x;
t5 = t.^2;
t6 = t5 + 1;
t7 = 1./y;
t8 = t6.*t7.*x;
t9 = t3 + t4;
t10 = 1./t9;
F = [-(t10.*(t3 - t4))./t6,t8; t8,- t10.*(3.*t3 - 3.*t2.*x) - 1];

matlabFunction generates many intermediate variables. This is called optimized code. Intermediate variables can make the resulting code more efficient by reusing intermediate expressions (such as t4, t6, t8, t9, and t10 in the calculation of F). Using intermediate variables can make the code easier to read by keeping expressions short.

If you don't want the default alphabetical order of input variables, use the vars option to control the order. Continuing the example,

matlabFunction(F,'file','testMatrix.m','vars',[x y t])

generates a file equivalent to the previous one, with a different order of inputs:

function F = testMatrix(x,y,t)
...

Naming Output Variables

By default, the names of the output variables coincide with the names you use calling matlabFunction. For example, if you call matlabFunction with the variable F

syms x y t
z = (x^3 - tan(y))/(x^3 + tan(y));
w = z/(1 + t^2);
F = [w, (1 + t^2)*x/y; (1 + t^2)*x/y,3*z - 1];
matlabFunction(F,'file','testMatrix.m','vars',[x y t])

the generated name of an output variable is also F:

function F = testMatrix(x,y,t)
...

If you call matlabFunction using an expression instead of individual variables

syms x y t
z = (x^3 - tan(y))/(x^3 + tan(y));
w = z/(1 + t^2);
F = [w,(1 + t^2)*x/y; (1 + t^2)*x/y,3*z - 1];
matlabFunction(w + z + F,'file','testMatrix.m',...
'vars',[x y t])

the default names of output variables consist of the word out followed by the number, for example:

function out1 = testMatrix(x,y,t)
...

To customize the names of output variables, use the output option:

syms x y z
r = x^2 + y^2 + z^2;
q = x^2 - y^2 - z^2;
f = matlabFunction(r, q, 'file', 'new_function',...
'outputs', {'name1','name2'})

The generated function returns name1 and name2 as results:

function [name1,name2] = new_function(x,y,z)
...

Converting MuPAD Expressions

You can convert a MuPAD expression or function to a MATLAB function:

syms x y;
f = evalin(symengine, 'arcsin(x) + arccos(y)');
matlabFunction(f, 'file', 'new_function');

The created file contains the same expressions written in the MATLAB language:

function f = new_function(x,y)
%NEW_FUNCTION
%    F = NEW_FUNCTION(X,Y)

%    This function was generated by
%    the Symbolic Math Toolbox version 5.2.
%    31-Oct-2008 17:41:12

f = asin(x) + acos(y);

Generating Embedded MATLAB Function Blocks

Using emlBlock, you can generate an Embedded MATLAB™ Function block. The generated block is available for use in Simulink® models, whether or not the computer running the simulations has a license for Symbolic Math Toolbox functions.

Symbolic Math Toolbox with a Maple engine does not support emlBlock. For details, see Differences in Functionality When Using MuPAD and Maple Engines.

Generating and Editing a Block

Suppose, you want to create a model involving the van der Pol equation. Before you can convert a symbolic expression to an Embedded MATLAB Function block, create an empty model or open an existing one:

new_system('my_system');
open_system('my_system');

Create a symbolic expression and pass it to the emlBlock command. Also specify the block name:

syms x y;
mu = sym('mu');
dydt = -x - mu*y*(x^2 - 1);
emlBlock('my_system/vdp', dydt);

If you use the name of an existing block, the emlBlock command replaces the definition of an existing block with the converted symbolic expression.

The model my_system contains the generated block.

Add other Simulink blocks and wiring to properly define the system.

You can open and edit the generated block. To open a block, select Edit>Open Block or use the context menu.

Controlling the Order of Input Ports

emlBlock generates input variables and the corresponding input ports in alphabetical order from a symbolic expression. To change the order of input variables, use the vars option:

syms x y;
mu = sym('mu');
dydt = -x - mu*y*(x^2 - 1);
emlBlock('my_system/vdp', dydt,...
'vars', [y mu x]);

Naming the Output Ports

By default, emlBlock generates the names of the output ports as the word out followed by the output port number, for example, out3. The output option allows you to use the custom names of the output ports:

syms x y;
mu = sym('mu');
dydt = -x - mu*y*(x^2 - 1);
emlBlock('my_system/vdp', dydt,...
'outputs',{'name1'});

Converting MuPAD Expressions

You can convert a MuPAD expression or function to an Embedded MATLAB Function block:

syms x y;
f = evalin(symengine, 'arcsin(x) + arccos(y)');
emlBlock('my_system/my_block', f);

The resulting block contains the same expressions written in the MATLAB language:

function f = my_block(x,y)
%MY_BLOCK
%    F = MY_BLOCK(X,Y)

%    This function was generated by
%    the Symbolic Math Toolbox version 5.2.
%    31-Oct-2008 11:48:48

f = asin(x) + acos(y);

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS