Main Content

coder.const

在生成的代码中将表达式折叠为常量

说明

示例

out = coder.const(expression) 会计算 expression 并在生成的代码中将 out 替换为计算结果。

示例

[out1,...,outN] = coder.const(handle,arg1,...,argN) 计算具有句柄 handle 的多输出函数。然后,它会在生成的代码中将 out1,...,outN 替换为计算结果。要了解当 handle 接受零个输入并返回零个或一个输出时 coder.const 的行为,请参阅提示

示例

全部折叠

此示例说明如何使用 coder.const 在生成的代码中指定常量。

编写函数 AddShift,它接受 Shift 输入并将其添加到一个向量的元素。该向量由前 10 个自然数的平方组成。AddShift 可生成此向量。

function y = AddShift(Shift) %#codegen
y = (1:10).^2+Shift;

使用 codegen 命令为 AddShift 生成代码。打开代码生成报告。

codegen -config:lib -launchreport AddShift -args 0

代码生成器生成用于创建该向量的代码。它在向量创建过程中向向量的每个元素添加 Shift。在生成的代码中,AddShift 的定义如下:

void AddShift(double Shift, double y[10])
{
  int k;
  for (k = 0; k < 10; k++) {
    y[k] = (double)((1 + k) * (1 + k)) + Shift;
  }
}

将表达式 (1:10).^2 替换为 coder.const((1:10).^2),然后再次使用 codegen 命令为 AddShift 生成代码。打开代码生成报告。

codegen -config:lib -launchreport AddShift -args 0

代码生成器创建包含前 10 个自然数的平方的向量。在生成的代码中,它将 Shift 添加到此向量的每个元素。在生成的代码中,AddShift 的定义如下:

void AddShift(double Shift, double y[10])
{
  int i;
  static const signed char iv[10] = { 1, 4, 9, 16, 25, 36, 
                                 49, 64, 81, 100 };

  for (i = 0; i < 10; i++) {
    y[i] = (double)iv[i] + Shift;
  }
}

此示例说明如何在生成的代码中将用户编写的函数折叠为常量。

编写函数 getsine,该函数接受 index 作为输入,并从正弦查找表中返回 index 引用的元素。函数 getsine 使用另一个函数 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

使用 int32 类型的参量为 getsine 生成代码。打开代码生成报告。

codegen -config:lib -launchreport getsine -args int32(0)

生成的代码包含创建该查找表的说明。

将以下语句:

tbl = gettable(1024);

替换为:

tbl = coder.const(gettable(1024));

使用 int32 类型的参量为 getsine 生成代码。打开代码生成报告。

生成的代码包含查找表本身。coder.const 强制在代码生成期间计算表达式 gettable(1024)。生成的代码不包含计算的说明。生成的代码包含计算本身的结果。

此示例说明如何在 coder.const 语句中使用多输出函数在生成的代码中指定常量。

编写函数 MultiplyConst,该函数接受 factor 作为输入,并将两个向量 vec1vec2 的每个元素乘以 factor。该函数使用另一个函数 EvalConsts 生成 vec1vec2

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

使用 codegen 命令为 MultiplyConst 生成代码。打开代码生成报告。

codegen -config:lib -launchreport MultiplyConst -args 0

代码生成器生成用于创建向量的代码。

将以下语句:

[vec1,vec2]=EvalConsts(pi.*(1./2.^(1:10)),2);

替换为:

[vec1,vec2]=coder.const(@EvalConsts,pi.*(1./2.^(1:10)),2);

使用 codegen 命令为 MultiplyConst 生成代码。打开代码生成报告。

codegen -config:lib -launchreport MultiplyConst -args 0
代码生成器不生成用于创建向量的代码。在这种情况下,它会计算向量并在生成的代码中指定计算的向量。

此示例说明如何使用 coder.const 调用外部函数。

编写包含以下语句的 XML 文件 MyParams.xml

<params>
    <param name="hello" value="17"/>
    <param name="world" value="42"/>
</params>

MyParams.xml 保存在当前文件夹中。

编写读取一个 XML 文件的 MATLAB® 函数 xml2struct。该函数会识别在另一个标记 params 内的 XML 标记 param

识别 param 后,该函数将其属性 name 的值赋给结构体 s 的字段名称。该函数还将属性 value 的值赋给该字段的值。

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

xml2struct 保存在当前文件夹中。

编写 MATLAB 函数 MyFunc,该函数使用函数 xml2struct 将 XML 文件 MyParams.xml 读入结构体 s。使用 coder.extrinsicxml2struct 声明为外部函数,并在 coder.const 语句中调用它。

function y = MyFunc(u) %#codegen
  assert(isa(u, 'double'));
  coder.extrinsic('xml2struct');
  s = coder.const(xml2struct('MyParams.xml'));
  y = s.hello + s.world + u;

使用 codegen 命令为 MyFunc 生成代码。打开代码生成报告。

codegen -config:dll -launchreport MyFunc -args 0

代码生成器在代码生成期间执行对 xml2struct 的调用。它在生成的代码中用值 17 和 42 替换结构体字段 s.hellos.world

输入参数

全部折叠

MATLAB 表达式或用户定义的单输出函数。

该表达式只能包含编译时常量。该函数只能接受常量参量。例如,以下代码会导致代码生成错误,因为 x 不是编译时常量。

function y=func(x)
   y=coder.const(log10(x));

要修复该错误,请将 x 赋给 MATLAB 代码中的常量。或者,在代码生成过程中,您可以使用 coder.Constant 定义输入类型,如下所示:

codegen -config:lib func -args coder.Constant(10)

示例: 2*pi, factorial(10)

内置函数或用户编写函数的句柄。

示例: @log, @sin

数据类型: function_handle

具有句柄 handle 的函数的参量。

参量必须为编译时常量。例如,以下代码会导致代码生成错误,因为 xy 不是编译时常量。

function y=func(x,y)
   y=coder.const(@nchoosek,x,y);

要修复该错误,请将 xy 赋给 MATLAB 代码中的常量。或者,在代码生成过程中,您可以使用 coder.Constant 定义输入类型,如下所示:

codegen -config:lib func -args {coder.Constant(10),coder.Constant(2)}

输出参量

全部折叠

expression 的值。在生成的代码中,MATLAB Coder™ 将出现的 out 替换为 expression 的值。

具有句柄 handle 的函数的输出。MATLAB Coder 会计算该函数,并在生成的代码中将出现的 out1,...,outN 替换为常量。

提示

  • 如果可能,代码生成器会自动对表达式进行常量折叠。通常,自动常量折叠发生在只具有标量的表达式中。当代码生成器不自行对表达式进行常量折叠时,请使用 coder.const

  • 当对计算密集型函数调用进行常量折叠时,为了减少代码生成时间,请执行外部函数调用。外部函数调用会导致由 MATLAB(而不是由代码生成器)来计算函数调用。例如:

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

    请参阅Use coder.const with Extrinsic Function Calls

  • 如果 coder.const 无法对函数调用进行常量折叠,请尝试执行外部函数调用来强制进行常量折叠。外部函数调用会导致由 MATLAB(而不是由代码生成器)来计算函数调用。例如:

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

    请参阅Use coder.const with Extrinsic Function Calls

  • 假设您对具有零个输入和零个或一个输出的函数句柄调用 coder.const 。例如:

    out = coder.const(@fcn);
    在这种情况下,代码生成器不计算 fcn,而是将 out 设置为函数句柄 @fcn 本身。要在这种特殊情况下强制计算 fcn,请在 coder.const 命令中显式调用该函数。例如:
    out = coder.const(fcn());

扩展功能

C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。

GPU 代码生成
使用 GPU Coder™ 为 NVIDIA® GPU 生成 CUDA® 代码。

版本历史记录

在 R2013b 中推出