主要内容

使用动态内存分配的原子模拟

这个例子展示了如何为MATLAB®算法生成代码,运行弹跳“原子”的模拟,并在多次迭代后返回结果。算法接受的原子数量没有上限,因此本例利用了动态内存分配。

先决条件

这个示例没有先决条件。

关于run_atoms函数

run_atoms.m函数运行跳跃原子的模拟(也应用重力和能量损失)。

帮助run_atoms
其中'atoms'表示原子的初始状态和最终状态(可以为空)“n”是要模拟的原子数。'iter'是模拟的迭代次数(如果省略,默认为3000次迭代)。

设置代码生成选项

创建代码生成配置对象

cfg = coder.config;%为可变大小的矩阵启用动态内存分配。cfg。DynamicMemoryAllocation =“AllVariableSizeArrays”

设置示例输入

创建一个模板结构'Atom',为编译器提供有关输入参数类型的必要信息。原子是一种具有四个场(x,y,vx,vy)的结构,在笛卡尔坐标系中指定位置和速度。

原子=结构(“x”0,“y”0,“vx”0,“v”, 0);

生成一个用于测试的MEX函数

使用命令codegen有以下论点:

args{编码器。类型of(atom, [1 Inf]),0,0}指示第一个参数是原子的行向量,其中列的数目可能是无限的。第二个和第三个参数是标量双精度值。

配置cfg启用由工作区变量定义的动态内存分配cfg

codegenrun_atomsarg游戏{编码器。类型of(atom, [1 Inf]),0,0}配置cfg- orun_atoms_mex
代码生成成功。

运行MEX命令

MEX函数在给定一个空原子列表的大约1000个迭代步骤中模拟10000个原子。返回值是模拟完成后所有原子的状态。

= repmat原子(原子,1,0);= run_atoms_mex原子(原子、10000、1000)
迭代:50迭代:100迭代:150迭代:200迭代:250迭代:300迭代:350迭代:400迭代:450迭代:500迭代:550迭代:600迭代:650迭代:700迭代:750迭代:800迭代:850迭代:900迭代:950迭代:1000完成迭代:1000
原子=1×10000带有字段的结构数组:X y vx vy

再次运行MEX功能

使用另外500个迭代步骤继续模拟

= run_atoms_mex原子(原子、10000、500)
迭代:50迭代:100迭代:150迭代:200迭代:250迭代:300迭代:350迭代:400迭代:450迭代:500完成迭代:500
原子=1×10000带有字段的结构数组:X y vx vy

生成独立的C代码库

要生成C库,请为库创建一个标准配置对象:

cfg = coder.config (“自由”);

启用动态内存分配

cfg。DynamicMemoryAllocation =“AllVariableSizeArrays”

在MATLAB中,默认的数据类型是double。然而,整数通常在C代码中使用,所以passint32整数示例值表示原子数和迭代数。

codegenrun_atomsarg游戏{编码器。类型of(atom, [1 Inf]),int32(0),int32(0)}配置cfg
代码生成成功。

检查生成的代码

在创建库时,会在文件夹中生成代码codegen / lib / run_atoms /.此文件夹中的代码是自包含的。要与编译后的C代码交互,您只需要生成的头文件和库文件。

dircodegen / lib / run_atoms
.rtGetNaN.h run_atoms_emxAPI.h . .rtGetNaN。o run_atoms_emxAPI。o. gitignore rt_nonfinite.c run_atoms_emxutil.c _clang-format rt_nonfinite.h run_atoms_emxutil.h buildInfo. c run_atoms_emxutil.c垫rt_nonfinite。o run_atoms_emxutil。o codeInfo。垫rtw_proj。tmw run_atoms_initialize.c codedescriptor。dmr rtwtypes.h run_atoms_initialize.h compileInfo. h run_atoms_initialize.h编译信息。垫run_atoms。run_atoms_initialize。o defines.txt run_atoms.c run_atoms_rtw.mk examples run_atoms.h run_atoms_terminate.c interface run_atoms.o run_atoms_terminate.h rtGetInf.c run_atoms_data.c run_atoms_terminate.o rtGetInf.h run_atoms_data.h run_atoms_types.h rtGetInf.o run_atoms_data.o rtGetNaN.c run_atoms_emxAPI.c

编写一个C主函数

通常,主函数是执行呈现或其他处理的与平台相关的代码。在本例中,一个纯ANSI-C函数生成一个文件run_atoms_state.m其中(运行时)包含原子模拟的最终状态。

类型run_atoms_main.c
/*包含标准C库*/ # Include  /*编译的主函数的接口。*/ #include "codegen/exe/run_atoms/run_atoms.h" /* EMX数据结构的接口。*/ #include "codegen/exe/run_atoms/run_atoms_emxAPI.h" int main(int argc, char **argv) {FILE *fid;int我;emxArray_Atom *原子;/*未使用的主要参数*/ (void) argc;(空白)argv;/*初始创建一个空的行向量的原子(1行,0列)*/ atoms = emxCreate_Atom(1,0);/*调用函数在1000个迭代步骤中模拟10000个原子*/ run_atoms(atoms, 10000, 1000);/*再次调用函数,再执行500个迭代步骤*/ run_atoms(atoms, 10000, 500); /* Print the result to a file */ fid = fopen("atoms_state.txt", "w"); for (i = 0; i < atoms->size[1]; i++) { fprintf(fid, "%f %f %f %f\n", atoms->data[i].x, atoms->data[i].y, atoms->data[i].vx, atoms->data[i].vy); } /* Close the file */ fclose(fid); /* Free memory */ emxDestroyArray_Atom(atoms); return(0); }

为可执行文件创建一个配置对象

cfg = coder.config (exe”);cfg。DynamicMemoryAllocation =“AllVariableSizeArrays”

生成独立的可执行文件

你必须传递函数(run_atoms.m)以及自定义C代码(run_atoms_main.c)codegen命令自动从MATLAB代码生成C代码,然后调用C编译器将生成的代码与自定义C代码捆绑在一起(run_atoms_main.c).

codegenrun_atomsrun_atoms_main.carg游戏{编码器。类型of(atom, [1 Inf]),int32(0),int32(0)}配置cfg
代码生成成功。

运行可执行文件

模拟完成后,将生成文件atoms_state.txt.TXT文件是一个10000x4的矩阵,其中每一行是一个原子的位置和速度(x, y, vx, vy),代表整个系统的当前状态。

系统([“。”filesep“run_atoms”]);

获取状态

运行生成的可执行文件atoms_state.txt.现在,从保存的矩阵重新创建结构数组:

负载atoms_state.txt美国信息交换标准代码清晰的原子I = 1:size(atoms_state,1) atoms(1, I)。x = atoms_state(我,1);原子(我)。y = atoms_state(我,2);原子(我)。vx = atoms_state(我,3);原子(我)。v = atoms_state(我,4);结束

呈现状态

调用run_atoms_mex只有零迭代来呈现。

run_atoms_mex(原子、10000 0);

图MATLAB编码器原子包含一个轴对象。axis对象包含一个image类型的对象。