代码覆盖的MathWorks有限许可
参加本课程,学习如何自动从你的MATLAB生成可读和可移植的C代码®算法。用MATLAB编码器™,你可以减少开发时间的顺利过渡使用C代码自动生成算法来实现。这个C代码不需要任何进一步的MATLAB库和可以自由分配。
这个演讲展示了如何使用命令行方法或图形项目管理工具:
记录:2014年8月19日
你好,我的名字叫Daryl宁,今天我们将讨论如何使用MATLAB编码器自动MATLAB转换为C代码。首先,让我们先从一个例子使用欧氏距离度量,我将向您展示如何用MATLAB函数,并使用MATLAB的编码器,生成通用的NCC代码。让我们跳回到MATLAB。这里在MATLAB中,你可以看到原来的函数,函数叫做欧几里得。欧几里得需要一些输入向量,这个向量x,然后比较代码书并返回向量的向量的最小距离。你可以看到,我们打电话给另一个函数称为常态。
我们有一个for循环,我们有一个if语句。但这只是一个相当基本的MATLAB函数。现在,当我们运行这个通过MATLAB编码器,这是什么我们会得到C代码。所以如果你看看这个C代码,你会发现我们有这个helper函数称为规范,还有C代码,我会进一步滚动下来。你会看到这是我们的主要入口点函数欧几里得C代码。希望,您可以看到,我们生成的C代码是首先通用的,可读的。这是一个客户,已经成功使用MATLAB编码器。iSonea开发移动应用程序和服务软件的喘息和哮喘管理检测。使用MATLAB编码器,他们能够减少手工编码工作,他们加速算法的开发迭代,和在这一切之上,他们的代码维护开销减少。
你可以在这里看到的报价,他们说没有其他环境或编程语言,它们可以用来在相同的时间产生类似的结果。让我们看一下议程。首先,我们将讨论的动机MATLAB生成c代码。然后,我们将讨论三步工作流生成C代码。我们会看看一些用例和快速总结。为什么工程师翻译MATLAB C ?嗯,有很多原因。首先,他们可能需要实现C代码到流程或这段代码移交到软件工程师,所以他们需要原始NCC代码。或者,他们可能需要集成MATLAB算法与现有的C环境,所以他们想把源代码并创建一些静态或动态库。
他们可能想这样做的另一个原因是他们想原型MATLAB算法在台式机上作为独立的可执行文件。最后,有些人只是想让C代码从MATLAB加速他们的用户编写的MATLAB算法,基本上为更快的模拟。如果我们考虑这个问题从技术计算工作流的观点,我们有我们的访问数据阶段,我们的探索和发现阶段,以及我们共享阶段,我们将展示如何从一个算法开发部署,部署独立的NCC的代码。但更重要的是,我们如何在这些阶段之间来回移动,很快。如果我们考虑我们在这里做什么,我们开始,我们开始在MATLAB环境中。在MATLAB环境中,你可以做很多事情。所以你可以想象你的数据,你可以发展你的算法,你甚至可以开发用户界面,环绕你的算法的应用。
现在,如果你想要,你想把可视化,算法,以及用户界面和部署,一些目标,解决我们所谓的MATLAB编译器。现在,C MATLAB编译器可以创建独立的可执行程序和共享库从MATLAB算法,包括可视化和任何用户界面你环绕。的缺点是,这个应用程序需要一种叫做MATLAB编译器运行时,因此有一些开销。有一个引擎,需要在后台运行。MATLAB编译器不会将MATLAB算法转换为C代码。然而,如果你只是想把算法和创建独立的NCC的代码,这就是MATLAB编码器。所以MATLAB编码器能够为大多数MATLAB算法和生成C代码给你独立的可读的C代码,就像你看到的,在最初的例子。你可以把这个C代码,做你想做的事情,无论你想创建一个可执行的或一个图书馆。
所以这条路是我们将要讨论的其余本课程,但是我将简要讨论了MATLAB编译器实现的用例。让我们从入门开始演示,我将向您展示如何使用MATLAB编码器应用代码生成过程中帮助你。让我跳回到MATLAB。好吧,这里我们要看着只是一个简单的矩阵乘法。所以你可以看到,我有一个基本的功能,它叫做mymult繁殖两个输入。现在,如果我想从这个函数生成C代码,我要做的就是去我在MATLAB的应用程序选项卡,我将打开我的MATLAB编码器应用。所以如果我这里向下滚动代码生成应用程序,我要点击MATLAB编码器。第一件事是让我给我的项目的名称,我将称之为mymult。
现在,当项目打开我首先需要添加入口点文件。所以,我只需点击添加文件并单击mymult。现在,因为我们生成C代码,我现在需要定义输入大小和类型。所以,我可以点击这里来定义他们。所以为输入,我们就保持这个简单的开始,我会说,输入是一个双标量。同样,b,这是一个双标量。一旦我做了,我可以点击构建选项卡,我可以改变我的输出类型C静态库,就开始我要生成C代码。我不会编译它。然后我可以点击。当我点击构建、MATLAB编码器将继续从我的MATLAB函数生成C代码。 If there are any errors or any troubles that it runs into, it will give me some warnings here. But it was successful, and then I can click on View Report. And what you'll see here is that here is my main entry point function, so I've got returns a double and simply multiplies a and b.
现在,我将讨论所有这些函数或C头文件生成之后表示,现在让我们回到这个函数,看看我们可以改变输入定义和生成不同的代码。如果我回到我概述选项卡在这里,我在这里可以改变输入定义生成不同的繁殖。另外,我还可以自动定义这些大小和类型使用某种试验台。如果我回到MATLAB,你会看到我已经创建了一个试验台mymult这里调用。你可以看到在这个试验台,它增加一个双输入的大小三四个双输入的大小四个,五个,这就造成了一些随机矩阵。我可以使用这个试验台自动定义类型在MATLAB编码器项目。如果我回到这里,我能做的就是点击汽车定义类型,和所有我需要做的就是指定试验台,试验台。如果我跑,MATLAB编码器将做的是实际运行试验台,试验台,它将计算出实际的输入数据类型和大小。
我可以点击使用这些类型,您可以看到,MATLAB编码器自动更新我的输入定义。现在,当我点击构建,可以产生一个矩阵相乘而不是一个标量相乘。如果我点击查看报告,在这里你会看到现在我的主要入口点函数有一个嵌套的四个循环,执行我的矩阵乘法定义在我的试验台。是什么当你手动将MATLAB的一些挑战C ?因为这通常是大多数人没有MATLAB编码器。所以他们会有人在MATLAB进行算法设计,然后重新编码成C或c++的部署,他们是否希望生C代码或一些图书馆或一个可执行的。但在这里,然而,通常你需要验证,C代码的行为一样MATLAB代码,因为通常MATLAB代码是你金色的参考,你想确保手动实现行为一样的原始MATLAB算法。
所以有这个验证步骤。不仅如此,但通常情况是该算法将会改变。这可能是改善算法,或者设计的要求已经发生了变化。但不可避免的是,该算法将改变这意味着你必须做出适当的改变手工编写的C代码。这个迭代可以发生很多,很多次在任何设计周期。所以我们这里的问题是,我们实际上有一个单独的功能和实现规范。我们需要管理MATLAB和C代码。因此很难修改需求在开发期间,因为这意味着任何需求变更将导致更多的迭代。和很难保持参考MATLAB与C代码同步代码。除此之外,每个人都是人类,所以你可能也介绍一些手工编码错误,你需要调试和修复。
所以整个过程或整个手动过程非常耗时和昂贵的。当这样做时,有实现的考虑。例如,记得我们最初的函数,它是一个简单的乘法。这里,我们写的函数作为一个= foo b和c, a等于b乘以c。如何实现?可以是一个元素相乘的元素,它可以是一个点的产品,它可以是一个矩阵相乘。另外,数据类型可以是不同的。他们可能是逻辑值,可以是整数,他们可以是任何东西。当实现这个C,它不仅仅是一个简单的问题说返回b乘以C。这个简单的乘法可能是某种完全不同取决于原始算法设计的目标是集成到一些大的代码库。这是多态性的一个例子。你还得考虑你想如何处理内存分配。
MATLAB是非常容易使用,因为它将仅仅当你需要动态分配的内存。但是当你实现C代码,您需要决定是否要使用静态内存分配或动态内存分配或两者的结合。多态性有关,你处理矩阵或数组,因为那是会影响实现。你在MATLAB代码使用定点数据类型,和如何转换到C整数类型?所以最终的结果是,一个基本的MATLAB函数这样的卡尔曼滤波器可以是五行的MATLAB代码,因为它基本上是一个大量的矩阵运算。这可能变成数百行C代码。当我们使用自动翻译的MATLAB C,这个想法是在算法设计和代码生成所有在MATLAB完成。所以我们最初的算法设计者可以简单地生成一个墨西哥人。现在,如果你不熟悉一个墨西哥人的文件是什么,一个墨西哥人文件基本上是编译C代码。这就像一个图书馆,可以直接从MATLAB。
墨西哥人的文件有一个包装的C代码允许您通过MATLAB与C数据类型,并创建一个墨西哥人的想法文件时从MATLAB生成C代码,这样我们可以确认生成的C代码的行为与MATLAB相同。一旦我们确认这个C代码行为和MATLAB一样,我们可以创建库或可执行文件。或者,我们可以继续迭代算法。但因为没有人工翻译涉及到现在,整个过程更加简化。用MATLAB编码器,你基本上可以保持一个设计在MATLAB和C,更快。得到C更快的优点是,你可以执行更多的测试原始算法和花时间改进算法在MATLAB实现什么,而是这实际上可能不会实施只是由于时间限制。
让我们看看从MATLAB生成C代码的三步工作流。所以在这里。你可以看到的第一步是,你需要准备你的MATLAB代码生成算法。当你准备你的MATLAB的算法,你需要决定实现选择你要做什么,但也确保你的MATLAB算法使用受支持的语言特性。万博1manbetx当从MATLAB生成C代码,我们不支持所有的MATLAB语言,但是我们大部分的MATLAB语言的万博1manbetx支持。我稍后会讨论这个。所以一旦你准备您的代码,然后你需要测试你的MATLAB代码是兼容的。你需要验证MATLAB代码可以生成代码,然后你可以对这段代码进行迭代优化,最后,你可以生成墨西哥人文件来验证c代码实现对原始的试验台。一旦你这样做验证,你可以把原始的C代码,NCC代码,实现它作为源或一个库或者一个可执行。取决于你想使用它。
所以给你一个例子工作流的MATLAB算法和将它转换为C,我要通过一个更广泛的例子现在使用牛顿迭代算法。让我们跳出再次MATLAB。关闭一些。让我们打开我的牛顿迭代算法。好了,这是要做的是使用牛顿搜索技术的n根一个数字。所以我看代码之前,我先给你我的意思的一个例子。这是我的试验台。所以我NRT函数在这种情况下将第四根10。好的,所以我希望第四根10,我要指定一些公差值。这是使用,因为算法是迭代的,所以我想告诉它什么时候停止。 So if I was to execute this, you'll see that the fourth root of 10 using this algorithm is about 1.7783. So let's take a look at the algorithm itself.
你可以看到它返回n根。它还返回的迭代次数以及价值观的历史,它在每一个迭代计算。它有一个变量输入的数量。如果我不爽滚动应该让我把最大化算法本身我们可以看到如果输入指定一个值小于零,我们只是会返回零。另外,如果用户指定一个值大于零,然后我们会执行这个牛顿搜索算法。如果我们看看,牛顿的搜索算法可以看到这里基本上是一个while循环,所以它会通过循环迭代发现n根。你会注意到的一件事是,50后它会自动停止迭代。进一步下降,在这里你会看到子函数,这子函数是用来计算导数。所以我们有一个主要功能。我们有一个子函数。
这将返回n根以及历史,如果我们回去主要调用函数,当我们得到历史上我们也可以计算的迭代的数量必须达到我们的最终价值。这就是这个函数。让我们从这个函数使用MATLAB编码器生成C代码。但我要做的第一件事就是用所谓的代码准备工具。因为也许我要做的是首先了解多长时间我让这个代码生成好了。所以我能做的是我可以选择我想生成代码的功能。右键点击它,你可以看到下面我将有一个选项说,检查代码生成准备。当我选择,这将会给我一个估计的难度将会从这个函数生成C代码。你可以看到代码生成准备分数是5,所以MATLAB认为它可能需要最少的变化让这个MATLAB代码生成C代码。
甚至将它按代码结构,所以你可以看到这将是多么困难的内部函数生成C代码。在其当前状态,它看起来很好。让我们打开我们的编码器的应用。这一次,我会打电话给我们的项目NRT。我们会和上次一样。我们将添加入口文件,这是NRT.m。然后,而不是指定的输入是什么,我将自动定义的类型使用试验台。这是我的试验台。让我们运行,编码器的应用程序可以计算出输入数据类型。在这种情况下,很简单的。 They're just three scalar doubles. So the first thing I need to do then when I generate C code if you remember our three-step workflow is to check that it actually can generate C code. And we can do this by trying to create a MEX function. So if I just try to create a MEX function to start with, if I click on build, this will try to generate C code and then turn it into a MEX function for verification.
现在,如果遇到错误,它会让我知道。你可以看到它实际上遇到错误。所以我要打开我的错误报告,你可以看到错误的列表,在这里遇到了。如果我选择第一个,你看到它的突出显示。还说当我鼠标悬停在这里,有一个未定义的函数变量,h。第一个分配一个局部变量将决定它的类。所以它告诉我的是,当我第一次分配函数的局部变量,这将定义为类。说这,我已经将它定义为一个标量。问题是如果你看到这个小红强调这是在一个循环中,我们实际上做的是我们增加h的大小在这个循环。这就是为什么我们得到这个错误消息。但我知道迭代的数量将会有一个最大的50岁,所以我能做的是预先分配内存这个值,h,这是一个历史,希望能解决我们的问题。
如果我回去了MATLAB和牛顿的搜索算法,这就是我们的问题。我在这里只是添加一行说,h = 0 50元素的向量。所以我们首先预分配内存,然后我们就保存一下。让我们看看这帮助我们。如果我去我的代码生成程序,试图构建again-OK,现在代码生成成功。我不会看报道,因为它实际上是一个墨西哥人的功能。我们可以看它,但它有很多包装器代码使它看起来有点乱。在任何情况下,墨西哥人的功能仅仅是生成的验证。所以我们能做的是我们可以使用墨西哥人函数来验证生成的C代码的行为一样的原始MATLAB算法。为此,我们有下面这个验证部分。 You can see we'll use our original test file test bench.
但重要的是这个复选框。它说,它将重定向的入口点函数调用墨西哥人。这意味着当我们运行试验台是在这里,而不是打电话NRT MATLAB函数,它将调用我们的墨西哥人函数编译C代码。所以我们的墨西哥人函数实际上是调用,NRT凸显墨西哥人。所以这要做的是把任何调用NRT NRT凸显墨西哥人。如果我点击运行,它将运行试验台,但是当它运行一个试验台,它实际上运行调用我们的墨西哥人函数。如果你看一下命令窗口,你看到我们得到相同的答案。这是我们的验证,我们生成的C代码的行为一样的MATLAB代码。现在,显然你可以建立一个更复杂的实验台,但这只是一个简化的例子。现在我们已经验证的C代码的行为和MATLAB一样,我们要做的是我们现在就产生了原始的C代码,而墨西哥人包装。 So let me just change our output time to C static library, and we'll just generate the code and click on Build.
现在,这将为这个函数创建原始NCC的代码。我们可以看一下报告。所以我们看一下报告。首先我们可以看到我们有这个helper函数。好的,看来是处理一些无限数字,一些非谓语形式的数字。如果我再往下滚动,你会看到这是我的主要入口点函数NRT然后的所有C代码生成来实现特定的功能。所以我们有大约175行C代码。我想另一件事我应该指出的是,如果你回到MATLAB代码,在MATLAB代码也给你一个报告的原始MATLAB代码。当你鼠标悬停在其中的一些变量,你可以看到它给你信息大小和类和复杂性。这有时是有用的,当你试图调试代码。 I just thought I'd point that out.
但是如果我们回到C代码,您将注意到的第一件事是,有很多功能,我们生成的。那么为什么我们产生了大量的功能吗?首先我们看到的是初始化和终止功能。现在,每当我们生成C代码时,我们总是会生成一个初始化和终止功能。这是好的做法调用初始化。好,这里是,初始化函数。之前,你叫你的主要入口点函数当你将其集成到你的目标代码,然后在调用终止功能。显然在初始化函数,初始化状态。也许你有一些持久的记忆。这样做是很重要的主要入口点函数调用之前。 Terminate may be used. If you've opened up maybe some file pointers, it will close down some file pointers. Things like that. But the important thing to remember is always call the initialize function first before calling the entry point function, and then call the terminate to finish if required. Now, there may not always be something inside the initialize functions and the terminate functions, but it's a good practice to simply keep them in your target code because if you happen to change your algorithm and we do generate some code which happens to be put inside that initialize function, after you've generated the code there is no need to change the code in your target environment.
你可以离开它,因为它已经调用初始化,会打电话给你的入口点,它会调用你的终止。我们在这里的其他功能得到国际货币基金组织(imf) C,得到nans-this所有代码处理非谓语形式的数字。我们这样做是因为MATLAB可以处理非谓语形式的数字,如果你碰巧需要处理,生成代码,那么你准备好了。但是如果你不需要支持,您也可以把它关掉。所以,我们要做万博1manbetx的是我将去更多的设置,在我这里有一些选项更多设置。其中一个选项是速度,你可以看到我可以关掉支持非谓语形式的数字。万博1manbetx如果我这样做,点击关闭,然后重建,MATLAB将重建的代码没有非谓语形式的支持。万博1manbetx现在,如果事实证明你的代码确实需要支持非谓语形式的数字,它会抛出一个错误在这里告诉你,你需要再次检万博1manbetx查框。然而,在这种情况下,我们不需要它。所以当我看报告,您可以看到,现在我们有更少的C头文件,如果我们现在向下滚动,你会发现原来辅助文件,上面我们有入口点函数不再存在。
这看起来像helper函数只是处理非谓语形式的数字。如果我们再往下滚动,这是我们所有的代码。我们现在从175行代码到大约115行代码,只需删除非谓语形式的数字支持。万博1manbetx另一件我想说你这是你会发现其实在这里评论。所以你可以看到这里的评论,50个迭代停止后,这里的评论,确定迭代。现在,这些评论直接来自MATLAB代码,从MATLAB代码和注释将帮助您跟踪C代码的MATLAB代码。它不会总是工作,因为有优化,当生成C代码执行。我们不只是做一个线对线翻译。否则,它将是非常低效的。然而,它将帮助你痕迹,原始的MATLAB代码是在引用生成的C代码。
但有一点我想指出的是在这之后确定迭代,我们又可以看到一群C代码看起来是执行一个while循环检查。如果我们回到这里的MATLAB代码,你会发现这是我们确定的迭代,但在那之后我们只是有一个MATLAB代码。所以我们有一行MATLAB代码,然而生成的多个行C代码。所以这是为什么呢?如果我们看看这个MATLAB代码,它要做的是确定需要多少次迭代计算n根。虽然只有一行的MATLAB代码和它的工作,它是一个非常低效的方式找到有多少次迭代。这就是我想如果你把垃圾到MATLAB编码器,你可能会得到垃圾。所以你需要聪明自己实际上构建算法,这样它将产生不错的C代码。
这里,这行代码是没有必要的。我们可以将这行代码替换为类似迭代=历史的总和不等于零。实际上我的意思是,这可能是另一种方式计算的迭代次数根据逻辑向量返回历史不等于零。如果我保存,然后退出并重新生成C代码并查看报告,我会回到滚动区域的代码,你可以在这里看到我们现在倒塌很多代码。之前是115行。现在,我们下降到约92只通过一个非常微妙的变化对MATLAB代码使算法更加高效。你甚至可以更进一步。假设你想要更详细的关于你想计算的迭代次数和写它甚至有点像C代码。所以我可以说类似迭代实际上等于零,然后做一个for循环,循环对JJ = 1的长度的历史。我们可以说迭代=迭代+ 1。 Else, we will break.
我需要做一个检查。如果历史的JJ不等于零,然后我们会增加迭代的数量。这是更多的一个C摊位的方式做同样的事情。所以如果我保存并返回应用程序和重建的代码,看一看报告,现在我们下降到90行代码。我想一件事我想指出的是,即使在我的MATLAB代码,我写了一个for循环,里面一个if语句,MATLAB编码器是足够聪明去看,说,好吧,而不是做if语句的for循环,我们就改变一个while循环的条件。这是一个例子一个MATLAB的优化编码器可能为你做的。好的,现在我们下降到90行代码。我想看看这个入口点函数。
所以当我们看的入口点函数,我们有我们所有的输入。然后我们有输出,这是第n根,迭代的数量。但是如果我们看看这里,历史上看起来有点奇怪。历史上的输出。我预计50元素向量输出我们的历史价值,但这是我所看到的历史数据变量和历史的大小。每当你看到这两个,我猜这两个变量,这样的论点,表明你有一些代码中的变量大小。所以MATLAB所做的是返回一些数据,这也是返回你在哪里在预先分配的内存,因为它并不总是知道因为它可以大小不同。现在,如果我们回到我们的代码,我们可以找出原因。这发生在主要功能NRT。所以尽管50牛顿这里搜索算法将返回一个元素向量对历史,因为我们记得在牛顿搜索算法,我们预先分配到50元素,问题是,这种NRT函数调用时的值小于零,它将分配一个值0到历史的这意味着MATLAB编码器将看这个说,历史可以是一个标量或它可以是一个50元素向量。
这就是这个变量大小。所以为了解决,鉴于历史零,我们可以定义这个是零的向量。这意味着历史将永远是一个50元素向量。让我们保存并回到MATLAB编码器应用和重建。当我们重建它,我们可以看一下报告。这里您将看到的是这是我们期望的更多。我们的输出仅仅50一个向量元素,这是清理一点体的代码。所以现在我们大约82行代码,所以我们开始在大约170行代码,现在我们在82行代码只有一些小的修改。你会注意到的另一件事是,牛顿的搜索算法已经被内联成这个入口点函数。
所以在主NRT在MATLAB,我们有这个else语句如果输入大于零,我们打电话到牛顿搜索算法。但在实际的C代码,你会发现,牛顿搜索算法的else语句张照牛顿搜索算法一直在内联代码。现在,假设你不想内联。现在,编码器将内联如果它认为只有几行代码,使其更有效率。但是你可以,如果你喜欢。我们能做到这一点的方法是在牛顿搜索算法是在这里,我只能说,看,coderdotinline从来没有。永不内联代码。如果我这样做,我可以回到代码生成,重建它,当我现在重建在这个报告中您将看到,在我的入口点函数else语句后,实际上我现在打电话牛顿搜索算法。如果我点击它,你可以看到,这实际上是一个独立的C代码有自己的头文件。
好的,让我们关闭这个。希望给你一个更好的主意,你如何可以使用此工作流从MATLAB代码生成C代码。现在,我之前提到过,MATLAB编码器只支持MATLAB语言的一个子集。万博1manbetx我们不能为所有的MATLAB语言生成C代码。这个小维恩图的给你说明我们所做的支持。万博1manbetx一切在这个淡蓝色的支持,所以我们支持大小可变的数据,我们支持定点持久性类、全局变万博1manbetx量、结构,但是你会注意到在外面的一些事情,我们不支持。所以可视化是我们不支持。万博1manbetx我们不会为情节生成C代码或冲浪或类似的东西。我们不会生成C代码如果本地Java调用,如果你使用细胞数组,我们还不支持他们。万博1manbetx有几件事情我们不支持,但这都是完全文档化。万博1manbetx In terms of features and functions, you can see here here, here's a table.
支持大部分的MATLAB的特性和功能。万博1manbetx你所有的不同的矩阵和数组,最支持的数据类型以及编程结构。万博1manbetx在功能方面,我们支持MATLAB的大部分基本功能。万博1manbetx我们支万博1manbetx持很多信号处理工具箱,通信系统工具箱,工具箱和计算机视觉系统,也有一些统计工具箱的函数。但是,这都是完全文档化。现在,我向您展示了如何生成C代码,让我们看一看一些用例。所以我提到的用例首先集成与定制软件算法,加速MATLAB算法,模型算法在电脑以及实现嵌入过程。让我们看一个示例代码集成。这里我要为一个缩放算法生成一些代码,然后集成到Visual Studio父项目。
所以我们跳回到MATLAB。我将关闭一些。让我打开算法我要谈谈。所以向你们展示它所做的只是,让我这个小模拟运行。所以在左边,我们有一些稳定的形象。现在,我已经有了一个缩放因子。我想做的是稳定图像放大。你可以看到我移动滑动条,我可以放大它。同样的,我可以让它更小。现在,我不是为整个应用程序生成代码。 It's just for the algorithm which does the zoom. So if I stop this, we'll take a look with this algorithm. The algorithm is called image process. It takes an input image as well as some factor. Obviously, if the factor is greater than one it will magnify, if the factor is less than one it will shrink it. So you can think if you're magnifying an image—let's just say you've made an image twice as big—you'd need to somehow interpolate between each of the pixels to make that image bigger.
这就是这个算法。现在,我想这不是重要的什么算法。我们只是想表明我们可以集成到另一个系统。我先打开一个现有的项目只是为了节省一些时间。现在,你在这里会看到一个有趣的事情是我定义为类型的输入图像由结肠双和结肠无穷个乘无穷。这意味着输入维度是由什么东西到无穷无限,这意味着我不知道输入图像的大小,这意味着我不得不使用动态内存分配。如果我点击建立,在更多设置你会看到我在哪里可以设置下内存。你可以看到,我可以使变量大小的支持,这实际上在默认情况下,然后启用动态内存分配。万博1manbetx所以你可以控制。如果你想使用静态内存分配,显然你可以取消,但是我们不能为这个项目生成代码。
让我点击构建。这是要做的是生成C代码需要实现该算法。但因为我们使用的是动态内存分配,它还包括一些其他功能。所以你可以看到,如果我们看一看的入口点函数图像过程中,你会发现这种类型的输入图像EMX数组强调真正凸显t。现在,这是因为输入未知,MATLAB编码器需要做的就是创建自己的数据结构来处理动态内存分配。现在,因为我们正在创建自己的数据结构,我们还创建一个API允许您使用这些自定义数据结构。如果我看这个图片过程强调EMX API。CPP,在这里您将看到这些功能来帮助你处理这个自定义数据结构。我想在这里您将看到的一件事是EMX创建真实的,这是如何创建这个数据结构。你可以看到它基本上是任命一些数据以及任命为多大。
同样的,因为我们创造了我们自己的数据结构,我们也有一个效用函数来破坏,一旦你完成它。现在我们生成的代码,让我们融入到另一个项目。再一次,让我打开一个现有的项目。让我们打开这个解决方案。这将打开在Visual Studio。对不起,我打开这个外部MATLAB。这里的想法是我们刚刚创建的一些通用的NCC代码,我们想整合到另一个环境中是用C或c++编写的。我打开一个现有的解决方案,这种解决方案确实是需要一个输入流从一个网络摄像头,然后这些数据我们得到从摄像头将融入到我们的放大算法,然后显示它。这是我的文件。让我们看一看原来的主。CPP file here we've got in this parent project.
我们将使用一些公开的简历实用程序就跟摄像头并显示它在我们的电脑。但是如果你滚动这个主文件,最主要的是在这里,我们使用效用函数,这EMX创建强调真正凸显t,所以我们创建我们需要使用自定义数据结构。这就是我们运行初始化函数,这里我们创建的输出图像,因为我们有一些未知的大小与未知大小输出图像输入图像。如果我滚动往下一点,这里有一个for循环,只是填充数据从网络摄像头数据,这是调用MATLAB代码生成器的编码器。我的图像处理功能。一旦我们处理它,我们填充输出数组。所以我来构建解决方案。好吧,既然是建立。我要关闭它,我将进入我的发布目录。
你可以看到,这是我的视频摄像头点EXE我刚建的,我要做的是调用MATLAB。所以我将使用爆炸运营商视频摄像头,我会给它一个放大倍数为1.5。现在,你看到的是我有一个网络摄像头连接到我的笔记本电脑,所以我只是移动它。我在桌子上。有一把椅子,你可以在这里看到的是放大的图像放大了1.5。这只是给你们,我们从MATLAB编码器生成的C代码运行在其他一些家长Visual Studio项目中。好吧,我们可以做的另一件事是我们可以集成现有的C代码到代码生成过程。这是有用的,如果你有一些现有的C代码,您想要使用MATLAB编码器生成C代码,这可能是因为你有一些优化的实现函数,您目前正在使用。
有很多方法可以做到这一点,我要向你们展示一个简单的方法使用所谓的编码器。目标和Coder.CUL。让我们跳回到MATLAB,让我们看看这个定制的卷积函数,将积分。所有我做的是做一个卷积。这是我的试验台。我可以运行这个。它有两个输入向量,然后我可以做一个卷积。这是所有做的。但在实际的函数本身,这叫一个自定义com凸显ceval。这是函数。我已经安排这个让我调用外部C代码。 So by the way, the actual C code I'm going to use is here. It's called custom underscore com dot c. It takes the input signal as well as the signal length, the input kernel as well as the kernel length, and then returns the output And then what we've got here is just some C code for a convolution. So in the MATLAB code itself, when I call this MATLAB function it branches off into two separate paths depending on what MATLAB is doing.
所以当我使用编码器。目标,我可以说,如果我执行在MATLAB和如果我给它输入,这将测试如果是在MATLAB运行。如果在MATLAB运行这个函数,我将调用MATLAB的本机卷积函数,因为我需要,因为我需要运行在MATLAB仿真的目的。其他的,如果我不运行在MATLAB生成代码。所以如果我生成代码,我想打个电话到外部调用C函数定义conv。当我打电话这个外部C函数,我要通过我的输入x,但我会通过只读引用。我将通过在x的长度。我还打算通过在内核中,只读经过参考只读以及长度,然后我将返回输出y。所以这处理的数据类型转换,当你调用C函数。所以当我为这个函数生成C代码,它不会使用这条路。这里要用这条路和集成一些外部C代码。
让我们证明。我们就回到MATLAB-oh,我已经在MATLAB但我要打开一个现有的项目,好吧,在这里我有我的入口点函数。现在,唯一真实的东西,我要做的是更多的设置当我生成C代码,你可以看到在定制代码,我将选项卡,我可以指定自定义C代码驻留的地方以及包括目录,一旦我指定的,我可以构建它。当我构建它时,你会注意到当你看C代码不从com函数生成C代码。相反,它使得直接调用自定义强调com我之前给你们的c函数。如果我点击,这里是。所以,我们所做的是我们已经能够将一些外部C代码集成到代码生成过程,这是有用的,当你得到优化的例程。如果你想加速MATLAB算法?
嗯,我总是说的第一件事是而不是看C代码生成,总是先看一下更好的算法。例如,如果你正在做一个矩阵的逆,也许你可以看看不同的方法来解决同样的问题。看看不同的更有效的实现使用优化库。或者,看看使用额外的计算资源通过matlab访问额外的流程和gpu并行计算工具箱。所以有很多其他的选择你可以看看之前看着C代码生成。所以加速算法时,你应该做的第一件事是看看你MATLAB优化代码。研究并行计算选项。如果你处理DSP系统和通讯,看看系统对象。尝试使用墨西哥人实现自己的自定义代码,但是如果你不想写你自己的C代码,那么这就是你可以尝试用MATLAB生成C代码。
这里的示例中我将使用只是再次运行牛顿迭代算法和比较的墨西哥人文件生成原始的MATLAB代码。如果我回去MATLAB,我所做的是我写的一个小脚本。我要运行1000次迭代。现在,我要做的第一件事是MATLAB代码,你可以看到在这我所做的一切都是调用MATLAB代码NRT算法,我包装它滴答声和谈话时间执行。我们在MATLAB运行几次。在MATLAB中,平均需要0.003秒。现在,让我们来一次墨西哥人的代码。所以之前我所做的是我已经NRT算法转换为墨西哥人文件,和我使用最后的迭代的例子,我在这演讲。所以我要做同样的事情,但我要运行墨西哥人1000次,看的平均时间。好吧,当我运行几次我看到它有点不同。 I mean, we're looking at small numbers here, but we're looking at about 2.7, 2.8 by 10 to the negative five seconds to run the same algorithm.
如果我看一下加速因子在这种特殊情况下,我们看到的是一个加快约11倍,但这并不意味着你会得到什么。这将真正取决于MATLAB编写的代码,但是你可以得到加速。加速因子不同,我猜,你可能会看到加快通常是当你处理通信和信号处理,几乎总是当你处理不动点算法,并且当你原来的MATLAB代码有很多的循环状态,你没你的算法进行向量化。你会经常看到加快。你不会看到加快或你可能不会看到加速是当你做很多线性代数的矩阵计算,因为在MATLAB他们已经非常快因为他们打电话IPP和布拉斯特区图书馆,和他们已经多线程计算。所以你不会看到一个加速,当你试着墨西哥人类型的计算。
他们已经在MATLAB优化。如果你有并行计算工具盒,我们为墨西哥人也支持多核函数。万博1manbetx如果你使用一个parfor循环,例如,当您生成墨西哥人函数还将运行多核使用开放mp技术。但这确实需要有一个编译器,它支持开放的议员。万博1manbetx同样的,如果你只是生成独立的C代码,不是墨西哥人文件时,它也将使用这个开放的议员。但是,你需要一个编译器,它支持开放的议员。万博1manbetx我猜,人们可能想要做的另一件事是原型算法在PC上。所以在这里你还可以使用生成的代码并提供一个主要点C文件作为切入点,不仅让MATLAB生成独立的C代码XE然后编译它。让我们看看其中的一个例子。我要再次运行这个演示视频稳定。 So similar to the one you saw before when you saw the zoom.
它使用很多计算机视觉系统工具箱对象。所以如果我运行这个而不是看代码,你会看到这个视频稳定。现在,我之前提到的,MATLAB编码器不支持可移植的C代码生成可视化。万博1manbetx现在,这个特定的计算机视觉系统工具箱系统对象是一个例外。我们这里确实万博1manbetx支持可视化。我们将支持代码生万博1manbetx成这个窗口,这主要是因为它不是一个独立的C,它实际上是一个C库,其中包括,它将依赖于平台。但让我们看看我们能做些什么。如果我回到我的文件夹,打开项目,让我点击构建。现在,我有这里的输出类型指定为c可执行。我必须指定一个主要功能。
如果我看看主要功能,这是它是什么样子。我必须包含头文件。然后在主函数,很简单。所有我做的是调用初始化,我调用的入口点函数,然后调用终止,这就是我做的。让我们回到项目和构建。所以当我点击建立,这将从MATLAB代码生成C代码,一旦完成,它将主要的编译。C文件。当它结束的时候,它会给我一个可执行的当前目录,我可以运行。它还必须指定主要的位置。C文件只是在这个更多settings选项卡下我之前给你们相同的自定义代码部分。因此,代码生成。 If I go back out here to my current folder, you will see a video stabilize.EXC. Let me open that outside MATLAB. And there you have that same little stabilization application. If you want to work with Simulink, what we have is a MATLAB function block in Simulink. So in Simulink, we've got this MATLAB function block.
你可以结合MATLAB代码,当仿真软件运行时,模型会这MATLAB代码转换为C代码并万博1manbetx将其转化为图书馆实际仿真软件世界跑得快。记得当我们有这两种期权给你们一开始这两个选项,我们谈论的是MATLAB编码器。好吧,让我来简要讨论MATLAB编译器。所以基本上,MATLAB编译器还允许您共享应用程序,允许你创建费用,dll,您还可以创建Excel ad-ins,和Java类。MATLAB编译器的优点是,它实际上支持几乎所有的MATLAB语言,大多数的MATLAB语言和工具箱。万博1manbetx这意味着你不需要作出许多改变。但正如我之前所说的,不利的一面是,它还需要一个MATLAB编译器运行时引擎,虽然这是一个版权免费部署,这意味着这些编译应用程序只能运行在MATLAB平台上运行,因为MATLAB编译器不给你通用NCC代码。
它基本上是写代码的包装器,并将其编译为一种可以被称为MCR。如果你思考你应该采取什么选择,你必须考虑你的需求是什么。对MATLAB编码器,它会给你便携和可读的C源代码。MATLAB编译器只会给你一个可执行文件或共享库。MATLAB编码器只支持一个子集的M万博1manbetxATLAB语言和一些工具箱。MATLAB编译器,另一方面,支持和语言MATLAB的大部分功能。万博1manbetxMATLAB编码器不需要运行时。只是普通的C代码,你可以拿走并编译,而MATLAB为MATLAB编译器创建的可执行文件和软件库需要MATLAB Compilor运行时。但两种解决方案都是万博 尤文图斯版权免费。
一旦生成或一旦生成的代码库,你可以做任何你想做的。我没有给你一个定点或嵌入式应用程序使用MATLAB编码器,但我确实有一个用户故事。这是从VivaQuant,开发和验证心电图传感的嵌入式设备。他们使用MATLAB以及我们的定点工具MATLAB编码器来实现他们的算法在一只手臂皮层m处理器。你可以看到这里的结果,他们实际上加速了开发了300%。他们能够最大限度地减少权力和记忆和使用此工作流程执行更严格的测试。现在让我们快速总结。我们在这里显示你如何从算法开发通用NCC代码还如何迅速两者之间来回移动,改变你的算法和自动生成C代码。所以这样做,这确实加速自己的发展。
如果你思考你的传统的工作流,通常你发展你的算法,你测试它,你把它转换成C手动,然后你做更多测试和迭代,这个过程在这里,这变得非常,非常耗费时间。当你使用C代码自动生成,得到巨大的节省了时间,和节省这些时间可以花在改进算法和测试算法确保你部署的生产质量。所以关键外卖从这里——MATLAB提供的直接路径C代码从浮点和定点MATLAB代码。它适合应用程序需要的源代码和一个小内存占用是必需的,所以你不能有一个MATLAB编译器运行时在后台运行。和自动生成也帮助你加速设计迭代和减少你的验证工作。欲了解更多信息,你可以访问我们的产品页面mathworks.com/products/matlab编码器。s manbetx 845从这里,你可以要求试用许可证。或者,你可以告诉你Mathworks客户经理要求审判,或者你可以直接联系我们在这个电子邮件地址或电话号码。
你也可以从下面的列表中选择一个网站:
选择中国网站(中文或英文)最佳站点的性能。其他MathWorks国家网站不优化的访问你的位置。