主要内容

使用MATLAB Coder应用程序从符号表达式生成C代码

这个例子展示了如何使用MATLAB®Coder™应用程序从符号表达式生成静态C库。首先,在symbolic Math Toolbox™中使用符号表达式,并使用将符号表达式转换为可部署的MATLAB函数matlabFunction.接下来,从MATLAB函数生成C代码。生成的C代码接受具有固定的、预先分配的大小的输入,但是您也可以在代码生成期间指定可变大小的输入。

本例遵循中描述的步骤使用MATLAB Coder App生成C代码(MATLAB编码器),但更新了从符号表达式生成MATLAB函数的步骤。或者,可以在MATLAB命令行中使用MATLAB函数生成C代码codegen(MATLAB编码器)命令。有关此工作流的教程,请参见在命令行生成C代码(MATLAB编码器)

请注意,MATLAB在线™中不支持MATLAB Coder应用程序。金宝app要在MATLAB Online中生成C/ c++代码,请使用codegen(MATLAB编码器)命令。

从符号表达式生成可展开的MATLAB函数

这个例子求解了哈密顿模型的特征值:

H - 1 2 - δ 2 Ω Ω δ 2 + + 1 2

在哪里 Ω , δ 是哈密顿量的参数。

创建符号变量ω,δ来表示哈密顿量的参数。为哈密顿量创建一个符号矩阵。

信谊ωδH = [(q-1)^2 - /2,;(q+1)²+ /2]
H =

- 1 2 - δ 2 Ω Ω δ 2 + + 1 2

求出哈密顿量的两个特征值。

E = eig(H)
E =

2 - 4 Ω 2 + δ 2 + 8 δ + 16 2 2 + 1 2 + 4 Ω 2 + δ 2 + 8 δ + 16 2 2 + 1

接下来,转换两个特征值E (1)而且E (2)生成MATLAB函数文件matlabFunction.编写结果函数,该函数返回两个元素E1而且E2,转到文件myEigenvalues.m.指定输入参数的顺序为[q Omega delta]

matlabFunction (E (1), (2),“文件”“myEigenvalues”...“var”,[q ω],“输出”, {“E1”“E2”});

文件中转换后的函数myEigenvalues.m可以使用没有符号数学工具箱。MATLAB文件myEigenvalues.m包含函数myEigenvalues实现了本例中的核心算法。函数取ω,δ作为输入,所有这些都必须是相同大小或标量。然后计算两个特征值作为这些输入的函数。

类型myEigenvalues
function [E1,E2] = myEigenvalues(q,Omega,delta) %myEigenvalues % [E1,E2] = myEigenvalues(q,Omega,delta) %该函数由符号数学工具箱9.0版本生成。% 01-Sep-2021 16:44:40 t2 = ω .^2;T3 =。^2;T4 = q.^2;T6 = delta.*q.*8.0;T5 = t2.*4.0;T7 = t4.*1.6e+1;T8 = t3+t5+t6+t7;T9 =√(t8);T10 = t9./2.0; E1 = t4-t10+1.0; if nargout > 1 E2 = t4+t10+1.0; end

运行MATLAB测试脚本

为了计算一组输入的特征值,创建并运行测试脚本myTest.m在MATLAB。测试脚本用以下大小指定输入:

  • qGrid是一个128——- - - - - -256表示二维( Ω )空间。

  • OmegaGrid是一个128——- - - - - -256表示二维( Ω )空间。

  • δ是标量。

然后脚本调用该函数myEigenvalues.m来计算特征值。输出显示这些输入值的特征值的图形。下面是脚本的内容myTest.m

Q = linspace(-2,2,256);= linspace(0,2,128);Delta = 1;[qGrid,OmegaGrid] = meshgrid(q,Omega);[E1,E2] = myEigenvalues(qGrid,OmegaGrid,delta);冲浪(q,ω,E1);冲浪(q,ω,E2)的阴影插值函数

图中包含一个轴对象。axis对象包含2个surface类型的对象。

从MATLAB函数生成C代码

为了使您的MATLAB代码适合代码生成,请使用代码分析器和代码生成准备工具。当你输入代码时,MATLAB编辑器中的代码分析器会不断检查你的代码。它报告问题并提出修改建议,以提高性能和可维护性。代码生成准备工具筛选MATLAB代码中不支持代码生成的特性和功能。金宝app

使MATLAB代码适合代码生成

  • 开放myEigenvalues.m在MATLAB编辑器中。函数声明之后,添加% # codegen指令:

  • MATLAB编辑器右上角的代码分析器消息指示器是绿色的。分析器没有检测到代码中的错误、警告或改进机会。有关使用代码分析器的详细信息,请参见使用代码分析器检查代码中的错误和警告

  • 保存文件。现在,您已经准备好使用MATLAB Coder应用程序编译代码。编译指从MATLAB代码生成C/ c++代码。

打开MATLAB编码器App,选择源文件

  • 在MATLAB工具条上应用程序选项卡,在代码生成,按MATLAB编码器应用程序图标。应用程序打开选择源文件页面。

  • 选择源文件页中,输入或选择入口点函数的名称myEigenvalues.一个入口点函数是一个顶级的MATLAB函数,您可以从中生成代码。应用程序用默认名称创建一个项目myEigenvalues.prj在当前文件夹中。

  • 点击下一个定义输入类型的一步。应用程序运行代码分析器(在前一步中已经运行过),以及入口点函数上的代码生成准备工具。如果应用程序发现问题,它会打开检查代码生成准备情况页,您可以在此查看和修复问题。在本例中,因为应用程序没有检测到问题,所以它会打开定义输入类型页面。有关更多信息,请参见代码生成准备工具(MATLAB编码器)

请注意,代码分析器和代码生成准备工具可能无法检测到所有的代码生成问题。在消除这两个工具检测到的错误或警告后,使用MATLAB Coder生成代码,以确定MATLAB代码是否有其他遵从性问题。

支持C/ c++代码生成的某些MATLAB内置函数和工具箱函数、类和系统对象具有特定的代码生成限制。金宝app中列出了这些限制和相关的使用说明扩展功能相应的参考页的部分。有关更多信息,请参见C/ c++代码生成支持的函数和对象金宝app(MATLAB编码器)

定义输入类型

因为C使用静态类型,代码生成器必须在代码生成时确定MATLAB文件中所有变量的类、大小和复杂性,也称为编译时.因此,必须指定所有入口点函数输入的属性。要指定输入属性,您可以:

  • 通过提供调用带有示例输入的入口点函数的脚本,指示应用程序自动确定输入属性。

  • 直接指定属性。

在本例中,定义输入的属性δ,ω,指定测试文件myTest.m用于自动定义类型的代码生成器:

  • 输入或选择测试文件myTest.m在MATLAB提示符中。

  • 点击自动定义输入类型. .测试文件,myTest.m,调用入口点函数,myEigenvalues,使用预期的输入类型。应用程序确定输入双(128 * 256),输入ω双(128 * 256),和输入δ双(1 × 1)

  • 点击下一个检查运行时问题的一步。

检查运行时问题

检查运行时问题步骤从入口点函数生成一个MEX函数,运行MEX函数,并报告问题。MEX函数是生成的代码,可以从MATLAB内部调用。执行此步骤是一种最佳实践,因为您可以检测并修复在生成的C代码中难以诊断的运行时错误。缺省情况下,MEX功能包含内存完整性检查功能。这些检查执行数组边界和维数检查。这些检查可以检测为MATLAB函数生成的代码中违反内存完整性的情况。有关更多信息,请参见控制运行时检查(MATLAB编码器)

为了将MATLAB代码转换为高效的C/ c++源代码,代码生成器引入了一些优化,这些优化在某些情况下会导致生成的代码与原始源代码的行为不同。看到生成的代码和MATLAB代码的区别(MATLAB编码器)

  • 打开检查运行时问题对话框(如果对话框没有自动出现),请单击检查问题箭头

  • 检查运行时问题对话框中,指定测试文件或输入代码,使用示例输入调用入口点函数。对于本例,使用测试文件myTest用来定义输入类型的。

  • 点击检查问题.该应用程序生成一个可以在MATLAB中运行的MEX函数。这一步运行测试脚本myTest替换对myEigenvalues即调用生成的MEX函数[E1,E2] = myEigenvalues_mex(qGrid,OmegaGrid,delta).生成的MEX文件myEigenvalues_mex位于文件夹中工作\ codegen \ lib \ myEigenvalues(适用于Microsoft®Windows®平台)或工作/ codegen / lib / myEigenvalues(在Linux®或Mac平台上),其中工作的位置myEigenvalues.m而且myTest.m.如果应用程序在生成或执行MEX函数期间检测到问题,它会提供警告和错误消息。单击这些消息可导航到有问题的代码并修复问题。在本例中,应用程序没有检测到问题。

  • 默认情况下,应用程序会收集行执行计数。这些计数可以帮助您了解测试文件的情况myTest.m锻炼的myEigenvalues函数。单击,查看行执行次数查看MATLAB行执行计数.应用程序编辑器在代码的左侧显示一个用颜色编码的条。若要在代码上扩展颜色高亮显示并查看行执行计数,请将光标放在该工具条上。绿色表示代码只执行一次调用来计算特征值。

  • 点击下一个生成代码的一步。

生成C代码

  • 打开生成对话框(如果对话框没有自动出现),请单击生成箭头

  • 生成对话框,设置构建类型静态库(lib)而且语言其他项目生成配置设置使用默认值。您可以选择生成MEX函数或其他C/ c++构建类型,而不是生成C静态库。对于MEX和C/ c++构建类型,可以使用不同的项目设置。在MEX和C/ c++代码生成之间切换时,请验证所选的设置。

  • 点击生成.MATLAB Coder生成一个独立的C静态库,myEigenvalues,在文件夹中工作\ codegen \ lib \ myEigenvalues.的文件夹工作的位置myEigenvalues.m而且myTest.m.MATLAB Coder应用程序指示何时代码生成成功。它在页面左侧显示MATLAB源文件和生成的输出文件。在变量选项卡,显示MATLAB源变量信息。在目标生成日志选项卡,它显示生成日志,包括C/ c++编译器警告和错误。默认情况下,代码窗口显示C源代码文件,myEigenvalues.c.中,单击所需的文件名,可查看其他文件源代码输出文件窗格。

  • 点击查看报告,在报表查看器中查看报表。如果代码生成器在代码生成过程中检测到错误或警告,则报告将描述问题并提供到有问题的MATLAB代码的链接。有关更多信息,请参见代码生成报告(MATLAB编码器)

  • 点击下一个打开完成工作流程页面。

评审完成工作流程页面

完成工作流程页表示代码生成成功。它提供了项目摘要和生成输出的链接。

将生成的C代码与原始代码进行比较MATLAB代码

要将生成的C代码与原始MATLAB代码进行比较,请打开C文件,myEigenvalues.c,以及myEigenvalues.m文件在MATLAB编辑器。

关于生成的C代码的重要信息:

  • 函数签名为:

void myEigenvalues(const double q[32768], const double Omega[32768],双delta,双E1[32768],双E2[32768])
  • Const double q[32768]而且const double Omega[32768]对应于输入而且ω在MATLAB代码中。的大小32768,对应总大小(128 x 256)当您从MATLAB代码生成C/ c++代码时使用的示例输入。这同样适用于输入ω.在本例中,生成的代码使用一维数组来表示MATLAB代码中的二维数组。

  • 代码生成器保留函数名和注释。如果可能,代码生成器会保留变量名。请注意,如果MATLAB代码中的变量被设置为常数值,则它不会作为变量出现在生成的C代码中。相反,生成的C代码将变量的值作为文本包含。

生成可变大小输入的C代码

你为它生成的C函数myEigenvalues.m只能接受与您在代码生成期间指定的示例输入大小相同的输入。然而,对应的MATLAB函数的输入数组可以是任何大小。在示例的这一部分中,您将从myEigenvalues.m它接受可变大小的输入。

假设你想要维数ω,δ在生成的C代码中有这些属性:

  • 两者的第一个维度而且δ大小可以变化到One hundred.

  • 第二个维度而且δ大小可以变化到400

  • ω是大小的标量吗1——- - - - - -1

要使用MATLAB Coder指定这些输入属性,请遵循以下步骤:

  • 定义输入类型步骤,指定测试文件myTest.m并点击自动定义输入类型像以前一样。测试文件调用入口点函数,myEigenvalues.m,使用预期的输入类型。应用程序确定输入双(128 * 256),输入ω双(128 * 256),和输入δ双(1 × 1).这些类型指定固定大小的输入。

  • 单击输入类型规范以编辑它们。属性可以指定不超过指定限制的可变大小前缀。例如,: 100指定对应的维度的大小可以变化到One hundred..为更改类型双(:100 x:400),因为ω双(1 × 1),以及δ双(:100 x:400)

现在,您可以按照与以前相同的步骤生成代码。中生成的C代码的函数签名myEigenvalues.c现在写着:

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

生成的代码中的参数对应于原始MATLAB函数中的这些参数:

  • emxArray_real_T *问- - -输入参数

  • ω- - -ω输入参数

  • emxArray_real_T *δ- - -δ输入参数

  • emxArray_real_T * E1- - -E1输出参数

  • emxArray_real_T * E2- - -E2输出参数

C代码现在由一个名为an的数据结构组成emxArray_real_T表示在编译时大小未知且不限界的数组。详情请参见在生成的函数接口中使用C数组(MATLAB编码器)