Fold expressions into constants in generated code
evaluates out
= coder.const(expression
)expression
and
replaces out
with the result of the evaluation
in generated code.
[
evaluates
the multi-output function having handle out1,...,outN
] = coder.const(handle
,arg1,...,argN
)handle
.
It then replaces out1,...,outN
with the results
of the evaluation in the generated code.
This example shows how to specify constants
in generated code using coder.const
.
Write a function AddShift
that takes
an input Shift
and adds it to the elements of a
vector. The vector consists of the square of the first 10 natural
numbers. AddShift
generates this vector.
function y = AddShift(Shift) %#codegen y = (1:10).^2+Shift;
Generate code for AddShift
using the codegen
command.
Open the Code Generation Report.
codegen -config:lib -launchreport AddShift -args 0
The code generator produces code for creating the vector. It
adds Shift
to each element of the vector during
vector creation. The definition of AddShift
in
generated code looks as follows:
void AddShift(double Shift, double y[10]) { int k; for (k = 0; k < 10; k++) { y[k] = (double)((1 + k) * (1 + k)) + Shift; } }
Replace the statement
y = (1:10).^2+Shift;
with
y = coder.const((1:10).^2)+Shift;
Generate code for AddShift
using the codegen
command.
Open the Code Generation Report.
codegen -config:lib -launchreport AddShift -args 0
The code generator creates the vector containing the squares
of the first 10 natural numbers. In the generated code, it adds Shift
to
each element of this vector. The definition of AddShift
in
generated code looks as follows:
void AddShift(double Shift, double y[10]) { int i0; static const signed char iv0[10] = { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 }; for (i0 = 0; i0 < 10; i0++) { y[i0] = (double)iv0[i0] + Shift; } }
This example shows how to fold a user-written function into a constant in generated code.
Write a function getsine
that takes
an input index
and returns the element referred
to by index
from a lookup table of sines. The function getsine
creates
the lookup table using another function gettable
.
function y = getsine(index) %#codegen assert(isa(index, 'int32')); persistent tbl; if isempty(tbl) tbl = gettable(1024); end y = tbl(index); function y = gettable(n) y = zeros(1,n); for i = 1:n y(i) = sin((i-1)/(2*pi*n)); end
Generate code for getsine
using an
argument of type int32
. Open the Code Generation
Report.
codegen -config:lib -launchreport getsine -args int32(0)
The generated code contains instructions for creating the lookup table.
Replace the statement:
tbl = gettable(1024);
with:
tbl = coder.const(gettable(1024));
Generate code for getsine
using an
argument of type int32
. Open the Code Generation
Report.
The generated code contains the lookup table itself. coder.const
forces
the expression gettable(1024)
to be evaluated during
code generation. The generated code does not contain instructions
for the evaluation. The generated code contains the result of the
evaluation itself.
This example shows how to specify constants
in generated code using a multi-output function in a coder.const
statement.
Write a function MultiplyConst
that
takes an input factor
and multiplies every element
of two vectors vec1
and vec2
with factor
.
The function generates vec1
and vec2
using
another function EvalConsts
.
function [y1,y2] = MultiplyConst(factor) %#codegen [vec1,vec2]=EvalConsts(pi.*(1./2.^(1:10)),2); y1=vec1.*factor; y2=vec2.*factor; function [f1,f2]=EvalConsts(z,n) f1=z.^(2*n)/factorial(2*n); f2=z.^(2*n+1)/factorial(2*n+1);
Generate code for MultiplyConst
using
the codegen
command. Open the Code Generation
Report.
codegen -config:lib -launchreport MultiplyConst -args 0
The code generator produces code for creating the vectors.
Replace the statement
[vec1,vec2]=EvalConsts(pi.*(1./2.^(1:10)),2);
with
[vec1,vec2]=coder.const(@EvalConsts,pi.*(1./2.^(1:10)),2);
Generate code for MultiplyConst
using
the codegen
command. Open the Code Generation
Report.
codegen -config:lib -launchreport MultiplyConst -args 0
This example shows how to call an extrinsic
function using coder.const
.
Write an XML file MyParams.xml
containing
the following statements:
<params> <param name="hello" value="17"/> <param name="world" value="42"/> </params>
Save MyParams.xml
in the current folder.
Write a MATLAB® function xml2struct
that
reads an XML file. The function identifies the XML tag param
inside
another tag params
.
After identifying param
, the function assigns
the value of its attribute name
to the field name
of a structure s
. The function also assigns the
value of attribute value
to the value of the field.
function s = xml2struct(file) s = struct(); doc = xmlread(file); els = doc.getElementsByTagName('params'); for i = 0:els.getLength-1 it = els.item(i); ps = it.getElementsByTagName('param'); for j = 0:ps.getLength-1 param = ps.item(j); paramName = char(param.getAttribute('name')); paramValue = char(param.getAttribute('value')); paramValue = evalin('base', paramValue); s.(paramName) = paramValue; end end
Save xml2struct
in the current folder.
Write a MATLAB function MyFunc
that
reads the XML file MyParams.xml
into a structure s
using
the function xml2struct
. Declare xml2struct
as
extrinsic using coder.extrinsic
and call it in
a coder.const
statement.
function y = MyFunc(u) %#codegen assert(isa(u, 'double')); coder.extrinsic('xml2struct'); s = coder.const(xml2struct('MyParams.xml')); y = s.hello + s.world + u;
Generate code for MyFunc
using the codegen
command.
Open the Code Generation Report.
codegen -config:dll -launchreport MyFunc -args 0
The code generator executes the call to xml2struct
during
code generation. It replaces the structure fields s.hello
and s.world
with
the values 17 and 42 in generated code.
expression
— MATLAB expression or user-written functionMATLAB expression or user-defined single-output function.
The expression must have compile-time constants only. The function
must take constant arguments only. For instance, the following code
leads to a code generation error, because x
is
not a compile-time constant.
function y=func(x)
y=coder.const(log10(x));
To fix the error, assign x
to a constant
in the MATLAB code. Alternatively, during code generation, you
can use coder.Constant
to define input type as
follows:
codegen -config:lib func -args coder.Constant(10)
Example: 2*pi
, factorial(10)
handle
— Function handleHandle to built-in or user-written function.
Example: @log
, @sin
Data Types: function_handle
arg1,...,argN
— Arguments to the function with handle handle
Arguments to the function with handle handle
.
The arguments must be compile-time constants. For instance,
the following code leads to a code generation error, because x
and y
are
not compile-time constants.
function y=func(x,y)
y=coder.const(@nchoosek,x,y);
To fix the error, assign x
and y
to
constants in the MATLAB code. Alternatively, during code generation,
you can use coder.Constant
to define input type
as follows:
codegen -config:lib func -args {coder.Constant(10),coder.Constant(2)}
out
— Value of expression
Value of expression
. In the generated code, MATLAB Coder™ replaces
occurrences of out
with the value of expression
.
out1,...,outN
— Outputs of the function with handle handle
handle
Outputs of the function with handle handle
.MATLAB Coder evaluates
the function and replaces occurrences of out1,...,outN
with
constants in the generated code.
The code generator constant-folds expressions automatically
when possible. Typically, automatic constant-folding occurs for expressions
with scalars only. Use coder.const
when the code
generator does not constant-fold expressions on its own.