Documentation

coder.const

Fold expressions into constants in generated code

Description

example

out = coder.const(expression) evaluates expression and replaces out with the result of the evaluation in generated code.

example

[out1,...,outN] = coder.const(handle,arg1,...,argN) evaluates the multi-output function having handle handle. It then replaces out1,...,outN with the results of the evaluation in the generated code.

Examples

collapse all

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.

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)
{
int k;
for (k = 0; k < 10; k++) {
y[k] = (double)((1 + k) * (1 + k)) + Shift;
}
}

Replace the expression (1:10).^2 with coder.const((1:10).^2), and then generate code for AddShift again using the codegen command. Open the Code Generation Report.

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)
{
int i;
static const signed char iv = { 1, 4, 9, 16, 25, 36,
49, 64, 81, 100 };

for (i = 0; i < 10; i++) {
y[i] = (double)iv[i] + 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
The code generator does not generate code for creating the vectors. Instead, it calculates the vectors and specifies the calculated vectors in generated code.

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();
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.

Input Arguments

collapse all

MATLAB 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 to built-in or user-written function.

Example: @log, @sin

Data Types: function_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)}

Output Arguments

collapse all

Value of expression. In the generated code, MATLAB Coder™ replaces occurrences of out with the value of expression.

Outputs of the function with handle handle.MATLAB Coder evaluates the function and replaces occurrences of out1,...,outN with constants in the generated code.

Tips

• When possible, the code generator constant-folds expressions automatically. 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.

• When constant-folding computationally intensive function calls, to reduce code generation time, make the function call extrinsic. The extrinsic function call causes evaluation of the function call by MATLAB instead of by the code generator. For example:

function j = fcn(z)
zTable = coder.const(0:0.01:100);
jTable = coder.const(feval('besselj',3,zTable));
j = interp1(zTable,jTable,z);
end

See Use coder.const with Extrinsic Function Calls (MATLAB Coder).

• If coder.const is unable to constant-fold a function call, try to force constant-folding by making the function call extrinsic. The extrinsic function call causes evaluation of the function call by MATLAB instead of by the code generator. For example:

function yi = fcn(xi)
y = coder.const(feval('rand',1,100));
yi = interp1(y,xi);
end

See Use coder.const with Extrinsic Function Calls (MATLAB Coder).