📄 matlab 大观园 --- 程序下载.htm
字号:
<BLOCKQUOTE>
<P><BR>M<DOUBLE> b("b",0,0); <BR>M<DOUBLE> a("a",0,0); <BR>M<DOUBLE>
n("n",0,0); <BR>M<DOUBLE> x("x",0,0); <BR>M<DOUBLE> y("y",0,0);
<BR>b=(BR(1.0),2.0,1.0); <BR>a=(BR(1.0),-1.58,0.64); <BR>n=50.0;
<BR>x=(BR(1.0),ones(1.0,n-1.0)); <BR>y=filter(b,a,x);
<BR>plot(rdivide(y,70.0),TM("*")); <BR>hold(TM("on"));
<BR>plot(x,TM(".")); <BR>grid(); <BR></P></BLOCKQUOTE>
<P>(3)Visual C++环境设置。 <BR>在Visual C++中的"Project / Settings / C, C++ /
Preprocessor /Additional include subdirectories"
中填入当前Matcom所处的路径.。(如"c:\matcom\")在Visual C++中的工程窗口处" "Project / Add to
Project / Files".加入mlibvc0.lib库文件。 <BR>(4)修改C++源代码。 </P>
<P>注意: <BR>①在头文件处应包含matlib.h.</P>
<P> #define MLIB 0<BR> #include "matlib.h." </P>
<P>②在类成员函数CMfcApp::InitInstance中调用. InitM启动对Matlab函数的调用。</P>
<P> BOOL CEcgstarApp::InitInstance() <BR>
{ <BR> TRACE0("initM\n"); <BR> initM(stin,stout,sterr);
<BR> ...... <BR> } </P>
<P>③在类构造函数CMfcApp::CMfcApp.中不要调用任何Matlab函数
<BR>④在类构造函数CMfcApp::~CmfcApp中调用exitM结束对Matlab函数的调用。</P>
<P> CEcgstarApp::~CEcgstarApp() { exitM(); } </P>
<P>⑤在程序中合适的位置插入经Matcom翻译过后的C++源码。 <BR>⑥编译工程文件,就可得到你所需的结果。</P>
<P align=left>3 结束语 </P>
<P align=left>
笔者在从事生物医学工程ECG信号的检测与处理项目中,对采用不同方法完成同一任务在代码量和运行时间上进行了比较,如表1、表2所列。
</P>
<P align=left>表1 ECG检测核心算法代码量 </P>
<TABLE width="67%" border=1>
<TBODY>
<TR>
<TD width="28%">全部用C++编写</TD>
<TD width="29%">全部用Matlab编写</TD>
<TD width="43%">用Matcom转换后的C编写</TD></TR>
<TR>
<TD width="28%">约3400行</TD>
<TD width="29%">约400行</TD>
<TD width="43%">约600行</TD></TR></TBODY></TABLE>
<P align=left>表2 ECG检测核心算法运行时间 </P>
<TABLE width="68%" border=1>
<TBODY>
<TR>
<TD width="27%">全部用C++编写</TD>
<TD width="33%">全部用Matlab编写</TD>
<TD width="40%">用Matcom转换后的C编写</TD></TR>
<TR>
<TD width="27%">约30秒</TD>
<TD width="33%">约25分钟</TD>
<TD width="40%">约1分钟</TD></TR></TBODY></TABLE>
<P
align=left> 由此可见,采用Matcom进行程序设计,这是一种时间、效率上的极好的折衷,它使得你可以将更多的时间放在项目关键问题的思考上,而不是放在算法的实现和程序的编码中,对于广大工程技术人员的开发工作是十分有益的。
</P>
<TABLE width="100%" bgColor=#00ffff border=0>
<TBODY>
<TR>
<TD width="100%">
<P align=center><SPAN class=tm><FONT face=隶书 size=4><A
name=ml_c></A>Matlab 和 C++
接口中函数注册的实现</FONT></SPAN></P></TD></TR></TBODY></TABLE>
<P align=center>李江红 韩正之<BR>《计算机应用》COMPUTER APPLICATIONS<FONT lang=ZH-CN>
2000 </FONT><FONT color=#000000>Vol.20 </FONT><FONT lang=ZH-CN>No.4 <SPAN
class=p>P.18-20</SPAN></FONT>
<P align=left>作者简介:<SPAN
class=zj>李江红(1970-)男,湖南长沙人,博士研究生,主要研究方向:随机决策以及智能控制</SPAN>;韩正之(1947-)男,上海人,教授,主要研究方向:非线性控制以及智能控制。<BR>作者单位:<SPAN
class=zz>李江红(上海交通大学智能工程研究所 上海 200030)<BR> 韩正之(上海交通大学智能工程研究所 上海 200030)</SPAN></P>
<P align=left>摘 要:<SPAN
class=zy>函数注册在Matlab和C++接口中起着重要的作用。在介绍函数注册作用的基础上,详细分析了函数注册的过程及应当注意的问题,并给出了一种实现函数注册的最简单的方法。用实例展示了函数注册的具体实现过程。</SPAN><BR>关键词:<SPAN
class=gj>Matlab;C++;函数注册</SPAN><BR>中图分类号:<SPAN
class=fl>TP317,TP319</SPAN> 文献标识码:<SPAN class=wm>A</SPAN><BR>文章编号:<SPAN
class=wh>1001-9081(2000)04-0018-03</SPAN></P>
<P align=center><SPAN class=tme><FONT face="Times New Roman">FUNCTION
REGISTERING IN<BR>THE INTERFACE BETWEEN MATLAB AND C++</FONT></SPAN></P>
<P align=center><FONT face="Times New Roman">LI Jiang-hong</FONT> <FONT
face="Times New Roman">HAN Zheng-zhi<BR></FONT>(<FONT
face="Times New Roman">Intelligent Engineer Research Institute of Shanghai
Jiaotong University, Shanghai 200030 China</FONT>)</P>
<P align=left> <FONT face="Times New Roman">Abstract: <SPAN
class=zye>Function registration plays an important role in the interface
between Matlab and C++. This paper analyzes the procedure of function
registering. Each step of function registering is discussed in detail in
the paper, and at the end</FONT>,<FONT face="Times New Roman">an example
is given for illustration.</FONT></SPAN><FONT
face="Times New Roman"><BR></FONT> <FONT face="Times New Roman">Key
words:<SPAN class=gje>Matlab; C++; function registration</SPAN></FONT></P>
<P align=left>1 研究意义</P>
<P> Matlab为用户提供了丰富的Windows图形界面设计方法,使用户能够在利用其强大数值计算功能的同时设计出友好的图形界面。在编程效率、可读性、可移植性和可扩充性上,Matlab远远优于其它高级编程语言。Matlab能够设计出功能强大、界面优美、性能稳定的高质量程序,它受到了越来越多用户的欢迎。然而作为一种以解释方式运行的高级计算机语言,Matlab程序的执行效率较低。为了解决这一问题,MathWorks公司提供了Matlab和C的接口。MathWorks公司提供的Matlab和C的接口方式共有三种:(a)将Matlab程序编译成MEX文件C或C++文件;(b)在C,C++程序中利用Matlab
Engine调用Matlab函数;(c) 在C,C++程序中利用Matlab C Math Library或Matlab C++ Math
Library调用Matlab函数。其中通过方式(a)、(b)生成的程序只有在安装了Matlab系统上才能正常运行,而由方式(c)
生成的程序则没有这样的要求,它能够以独立执行程序的形式运行,即使客户没有安装Matlab系统。方式(c)唯一的缺点就是不能利用Matlab中丰富的图形句柄处理函数,但是对于VC++等开发工具而言,这不是一个很严重的问题。因此方式(c)是实现功能和效率兼顾的最好接口方法<SUP>[2]</SUP>。</P>
<P> 当用方式(c)
生成应用程序时,一个重要的问题就是那些以函数作为自身输入参数的函数实现问题。众所周知,Matlab提供了一组能完成极值及极值点计算,线性规划,二次规划以及非线性方程求解等数值运算的优化函数<SUP>[3]</SUP>。</P>
<P> 在Matlab中使用这组优化函数时,用户定义的待优化函数必须作为输入参数传递给这些函数。在优化函数运行的过程中,系统将最终执行用户定义的待优化函数,并且这一切无须程序员的参与。但是当程序员通过方式(c)在C++程序中调用Matlab
C++ Math
Library中的优化函数时,事情就变得比较复杂。要利用这些优化函数所提供的数值计算功能,保证用户定义的待优化函数真正得到执行,程序员就必须自己完成对待优化函数的注册。因此,函数注册的研究具有重要的实用价值。</P>
<P align=left>2 Matlab和C++接口中函数注册</P>
<P> 在C++程序中,当调用优化函数等以函数为输入参数的函数时,Matlab C++ Math Library调用Matlab C Math
Library中的mlfFeval()来执行作为参数传递的函数。在mlfFeval()中又是通过对转换函数的调用来真正地执行作为参数传递的函数。转换函数和映射表是这一过程能够顺利进行的重要原因。函数注册就是定义函数的转换函数并建立相应的它的映射表。对于Matlab
C++ Math
Library中的函数,MathWorks公司都定义了它们转换函数并建立了它们的映射表,完成了对它们的注册。但是对于用户自定义的函数,程序员就必须自己完成这项工作。</P>
<P> 函数注册可以分成:(1)定义待注册函数;(2)定义转换函数;(3)建立映射表;(4)初始化映射表等以下四个部分来完成。下面将对各个部分进行详细地介绍。<BR> (1)
定义待注册函数 待注册函数因用户要求而异。为便于后面的分析,设用户定义的函数为:<BR> mwArray MyFunc(mwArray
x){<BR> ……//函数体。<BR> }<BR> 注意待注册函数的输入、输出参数的类型必须是mwArray。mwArray是Matlab
C++ Math Library中最基本的数据类,它对应Matlab中的基本编程单位—数组。<BR> (2)
定义转换函数 转换函数的功能是完成Matlab C Math Library和用户函数之间的翻译。由于它面向Matlab C Math
Library,因此必须用C定义。对(1)中定义的待注册函数,其转换函数的一般形式如下(为简单起见,该转换函数忽略了错误处理代码):<BR> typedef
mwArray (*PMYFUNC) (mwArray);<BR> extern "C" {<BR> int MyThunk (mlfFuncp
pFunc, int nArgOut, mxArray **<BR> ArgOut, int nArgIn, mxArray **
ArgIn){<BR> mwArray tmp=mwArray(ArgIn[0],0);<BR> mwArray
Out=(*((PMYFUNC)pFunc)) (tmp);<BR> ArgOut[0]=Out.FreezeData(
);<BR> return
1<BR> }<BR> }<BR> 转换函数共有5个输入参数,以MyThunk为例,pFunc是指向待注册函数的指针;nArgIn、nArgOut,
分别是待注册函数的输入、输出参数的个数;
ArgIn、ArgOut,则分别是输入、输出参数构成的数组。其中ArgIn[0]对应第1个输入参数,ArgIn[1]对应第2个输入参数……。ArgOut的情形类似。<BR> 由于转换函数面向Matlab
C Math Library,因此它的输入、输出参数中的数组类型只能是mxArray (mwArray是Matlab C Math
Library中基本的数据,它对应Matlab中的基本编程单位—数组);而注册的函数又只能接受mwArray类型的参数。因此,在调用注册函数之前必须将mxArray型数据转化为mwArray型数据,如MyThunk中:mwArray
tmp=mwArray(ArgIn[0],0);
在转换函数返回之前必须将注册的函数的返回值由mwArray型转化为型mxArray,如MyThunk中:ArgOut[0]=Out.FreezeData()。<BR> (3)
建立映射表 映射表的作用是把待注册函数的名称映射到指向该函数的指针。映射表中的元素由三元组:函数名称、函数指针、转换函数构成。对(1)、(2)中定义的待注册函数和转换函数,相应的映射表为:<BR> static
mlfFuncTabEnt MfuncTab[]={<BR> {"MyFunc", (mlfFuncp) MyFunc,
MyThunk}<BR> {0, 0 ,0}<BR> }<BR> 其中mlfFuncTabEnt是Matlab C Math
Library中用于存储函数项的数据结构。{0, 0 ,0}表示映射表的结束。<BR> (4)
初始化映射表 初始化映射表的方式比较单一。例如对(3)中的映射表,程序段:<BR> class
feval<SUB>—</SUB>init{<BR> feval<SUB>—</SUB>init{mlfFevalTableSetup(MfuncTab);}<BR> static
feval<SUB>—</SUB>init
feval<SUB>—</SUB>setup;<BR> }<BR> feval<SUB>—</SUB>init
feval<SUB>—</SUB>init::feval<SUB>—</SUB>setup;<BR> 将完成其初始化。其中mlfFevalTableSetup是Matlab
C Math
Library中用于初始化映射表的函数。设置静态对象的目的是保证映射表初始化在系统初始化静态变量时就得以完成。<BR> 从上面的分析可以看出,函数注册的过程比较复杂。不过MathWorks公司注意到了这个问题,它定义并提供了DECLARE<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE,
EVAL<SUB>—</SUB>ENTRY,
END<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE等一组宏来帮助用户简单、轻松地完成函数注册。例如对于(1)中定义的函数MyFunc,程序段:<BR> DECLARE<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE<BR> FEVAL<SUB>—</SUB>ENTRY(MyFunc)<BR> END<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE<BR>就实现了对MyFunc的注册,它取代了(2)、(3)、(4)中的所有工作。事实上,只要待注册函数的输入参数数目不大于8,输出参数数目不大于5,就能用这组宏来完成函数注册。</P>
<P align=left>3 应用实例</P>
<P> 下面的VC++程序通过调用Matlab C++ Math
Library中的fmin(),计算函数<BR> f(x,y)=e<SUP>x</SUP>(4x<SUP>2</SUP>+2y<SUP>2</SUP>+4xy+2y+1)<BR> 在y=2时,位于区间[-2,2]中使函数值最小的自变量x的值。<BR>#include
"matlab.hpp"<BR>#include <stdlib.h><BR>/***(1) 定义注册函数
***/<BR>mwArray MyFunc(mwArray x,mwArray y){<BR> mwArray
mResult=exp(x)*(4*x ^ 2+2*y ^ 2+4*x*y+2*y+1);<BR> return
mResult;<BR>}<BR>/***(2) 定义转换函数 ***/<BR>typedef mwArray
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -