利用Matcom实现基于MATLAB的混合编程

利用Matcom实现基于MATLAB的混合编程
 来源: 神经网络 作者:AI俱乐部 网友评论 0 条 浏览次数 42

Matcom是mathTools公司推出的最早的Matlab到C++的编译器。后来,由于Mathtools被Matlab公司收购,Mtacom对Matlab 5.3以后的版本就没有推出新的版本。相比Matlab自带的编译器Compiler,用Matcom转化代码要简单和方便得多;且对于采用C++的工程和研究人员来说Matcom的C++矩阵库(Matrix Lib)依然有非常大的利用价值。
通过Matcom连接M函数这类脚本语言或者高级算法语言有三种办法:—是将M文件编译成C++代码,然后在C++工程中插入这些代码,最后编译成为独立的可执行程序;二是直接在C++程序中使用Matcom提供的Matrix,方法与一相似,但常用。最后一种是利用MIDEVA直接生成EXE文件,然后在VC中通过shell调用,方法简单,但通用性差,仅适用于VC中调用Matlab实现图形显示的场合。
Mideva软件平台本身的功能相当强大,提供近千个Matlab的基本功能函数,通过必要的设置,就可以直接实现与C++的混合编程,而不必再依赖Matlab;同时,Mediva还提供编译转换功能,能够将Matlab函数或编写的Matlab程序转换为C++形式的DLL,从而实现脱离Matlab环境对Matlab函数和过程的有效调用,这样就有可能实现对Matlab强大的工具箱函数的利用。
  Mideva的缺点是C++与Matlab混合编写的应用软件必须携带必要的DLL,从而增大了软件的体积(约4M),同时也不能对所有的Matlab函数提供支持,例如采用类库进行设计的部分函数。
本节将以VC++6.0和Matcom为例,1,详细介绍如何利用Matcom进行VC++与Matlab的联合编程(即一);2 ,介绍一下在VC++中怎样使用Matcom C++矩阵库(即二)。
 1. 目前,Matcom的最高版本为4.5。首先安装Matcom 4.5,如下图

 

 

 

利用Matcom实现基于MATLAB的混合编程_第1张图片

 

 

 


安装Matcom前要已求安装VC++6.0。在安装过程中出现选择编译器对话框,选择”是” 如下图:


出现选择是否安装了Matlab时,如果本机上安装的是Matlab 5.3版本,可以选择“是(Y)”确认,因为Matcom4.5不支持Matlab 6.1以上的版本。其他选项采用默认设置。Matcom可以独立于Matlab运行,但需要外部的C++编译器,指定Matlab的位置是为了让编译文件中需要的一些系统函数找到路径用的。
安装完成后,在“lib”下,可以找到使用MatcomC++矩阵库(Matrix Lib)的头文件matlib.h和v4501v.lib文件,在Windows操作系统目录的system32目录下,可以找到使用MatcomC++矩阵库的动态链接库文件v4501v.dll。启动界面MIDEVA,如下图。MIDEVA集成开发环境包括命令行窗口、变量列表窗口、命令列表窗口和编译链接信息窗口等几部分,并有详细的帮助文档。
 

 


Matcom命令输入方法与Matlab相同。如果安装在中文版操作系统时,输入命令前加一空格,否则显示为乱码。

下面详细介绍如何将m文件编译后放入VC++中。
启动MIDEVA ,File->New,新建如下huatu.m文件。
m文件保存的默认位置为:matcom安装目录matcom45,生成的C++文件保存的默认位置为matcom安装目录matcom45Debug,本例matcom安装目录为C盘 即 C:matcom45Debug,在该目录下将会产生huatu.h、huatu.cpp、huatu.r 、huatu.obj文件。

在VC++中用MFC Wizard(exe)创建一个基于对话框名为Example的工程。在面板上添加一个ID为IDC_BUTTON1按扭。

C:matcom45Debug目录下的huatu.cpp文件的内容拷贝到void CExamleDlg::OnButton1()如下,
void CExampleDoc::OnButton1()
{
dMm(x); dMm(y);

#line 1 "c:/matcom45/huatu.m"
call_stack_begin;
#line 1 "c:/matcom45/huatu.m"
_ x = colon(-2.0,0.1,2.0);
#line 2 "c:/matcom45/huatu.m"
_ y = power(x,2.0);
#line 3 "c:/matcom45/huatu.m"
_ display( plot((CL(x),y)) );
call_stack_end
}

将C:matcom45lib下的matlib.h 和v4501v文件和C:matcom45debug下的huatu1.h文件拷贝到工程Example目录下,然后在VC中将库文件和头文件加入到工程中:工程->添加工程->Files,选择刚刚拷贝到Example目录下的matlib.h 、v4501v和huatu1.h文件
五,在ExamleDlg.cpp中加入如下代码:
#include "matlib.h"
#include "huatu.h"
在void CExamleDlg::OnButton1()中分别添加一个初始化类库调用函数”initM(MATCOM_VERSION)”和一个结束类库调用函数”exitM()”如下。
void CExampleDoc::OnButton1()
{
initM(MATCOM_VERSION)
dMm(x); dMm(y);

#line 1 "c:/matcom45/huatu.m"
call_stack_begin;
#line 1 "c:/matcom45/huatu.m"
_ x = colon(-2.0,0.1,2.0);
#line 2 "c:/matcom45/huatu.m"
_ y = power(x,2.0);
#line 3 "c:/matcom45/huatu.m"
_ display( plot((CL(x),y)) );
call_stack_end
exitM()
}
运行程序,点击画图按扭得图:
 


Matcom C++ 矩阵库的初始化和释放是成对出现的,在初始化时,调用函数initM(Matcom_VERSION),在需要释放的时候,调用函数exitM()即可。Matcom C++ 矩阵库的初始化需要一定的时间,为了加快程序的执行速度,应尽量减少Matcom C++ 矩阵库的初始化的次数。所以开发人员应仔细考虑Matcom C++ 矩阵库生存周期的长度,在Matcom C++ 矩阵库生存周期的开始初始化C++库,在生存周期结束的时候,释放 C++库。这样虽然会占用一定的内存,但是会提高程序运行的速度。
Matcom不但可以生成C++文件,而且还可以生成exe文件和dll文件。如图所示:
 


2.下面通过一个例子来说明Matcom C++ 矩阵库在Visual C++ 6.0中使用的过程:
在Visual C++ 6.0中,新建一个Win32 Console工程,如下图。实际上在任何类型的 C++工程中都可以使用Matrix,为了简单我们以控制台程序为例。
 


二.设置工程,打开Project|Setting的link标签,作如下修改见下图:

打开C/C++标签,作如下修改见下图:
 


加入头文件matlib.h,看是否成功?不成功检查设置!
在Example.cpp中输入如下程序
#include "stdafx.h"
#include "stdio.h"
#include "matlib.h"
int main(int argc, char* argv[])
{
initM(Matcom_VERSION);
 Mm a;
 a=rand(3,3);
 display(a);
 exitM();
 return 0;
}
输出结果:
ans (3x3)=9 double elements real (72 bytes)=
0.9501    0.4860    0.4565
0.2311    0.8913    0.0185
0.6068    0.7621    0.8214
在这说明一下,Matcom C++矩阵库采用面向对象的设计风格,矩阵数据和操作都封装在类Mm中。当需要创建矩阵的时候,只要声明一个Mm对象实例即可。如:Mm a;

关于Matlab所生成的COM组件,还有以下几个在实践中较为有用的说明:
1. 对于用于生成COM的任何一个Matlab函数,在COM组件中即为一个COM的方法,而Matlab函数中的全局变量(global)则为COM组件的一个属性。这一点对于神经网络编程中颇为有用,比如说,在ANN训练结束后,做仿真(simulate)时,我们需要调用Matlab生成的COM组件,但是,显然我们不能每调用一次COM就读一次ANN的配置(如权重、偏置等项目的值),也不能在VC中出现Matlab的结构体或者类。在这种情况下,我们就可以专门做一个Matlab函数,使用该函数调入ANN配置文件(一般为.mat文件)。而把ANN的配置量声明为全局变量,则可以在仿真函数中直接使用该变量。就像以下的示例:
function y = sim_ann(x)
global net
y = sim(net, x);

function LoadAnnParam
global net
% AnnMat.mat文件中存储了net变量
load AnnMat net

在VC中调用时,设COM对象为comObj,则有以下调用方式:
comObj.LoadAnnParam(); //载入ANN参数
for(int I = 0; I < n; I++)
comObj.sim_ann(1, x, y); //多次仿真ANN

2. 在Matlab中可以自定义数据类型,也就是VC中的类,但是这在生成COM组件时,会出现在load新类的对象时Matlab不认识该类型。这种情况下,我们可以在load该类以前,先初始化一个同名的该类型的对象。比如我们有NewClass这种新类,要load进来一个该类型的名字为NewObj的对象,对象的初始化函数为InitNewClass,则可以:
NewObj = InitNewClass;
Load mat_file NewObj;

3. 另外,在编程过程中曾遇到过这种情况,在生成的COM接口中如果输出变量为结构体时,有时会出现莫名其妙的峰鸣器常鸣的效果。这种情况经过多方查找无法找到原因,如果各位读者在使用中出现类似情况,可以从这个方面考虑问题的解决方法。


你可能感兴趣的:(语言无关技术性文章)