matlab与C++数据交换

一组MATLAB和 C++数据交换类的设计
南京航空航天大学 san  email :
 visualsan@yahoo.cn

(源代码:http://blog.csdn.net/visualsan/archive/2011/03/05/6226205.aspx)

一组MATLAB和 <wbr>C++数据交换类的设计


总体结构图


本文将针对如何进行 MATLAB 和 C++ 交互进行探讨,编程环境问为 matlab2009 和 VC6.0 。具体如何设置编程环境请参考 help 。内容总体分三部分: 1.matlab 引擎调用类封装。 2. 数据接口类设计,包括 mat 类型文件操作类设计。 3. 具体举几个实例。所有源代码包括例子,在我的空间中可以找到,有参考需要的朋友可以关注一下。

MATLAB 引擎总体结构分成两部分:数据交换和后台计算服务,由 matlab 命令控制。数据交换接口负责数据输入和数据输出。数据输入将计算说需要的变量导入到计算引擎中;数据输出接口则将计算结果提取出来进一步处理,典型的matlab应用是首先向matlab 传递参数、然后进行复杂的运算,最后提取感兴趣的结果。利用matlab 强大的计算能力以及C++的灵活性可发挥各种功能的极限,从而提高工作效率。关于matlab 和c++的相互调用的文章很多,但是在两者之间进行数据传递是一个比较麻烦的事情,要求程序员对MATLAB 的C API相当熟悉,所以非常不便。我接触MATLAB 和C++有几年了,相关书籍和文件教程让我受益匪浅,闲暇之余就总结了一下自己所学的知识,用面向对象方法开发了matlab和c++交互的类,写出来探讨一下。

 

计算引擎分为全局引擎和局部引擎。全局引擎只有一个,一旦启动全局引擎,则所有的计算结果和变量都是全局共享的。局部引擎是独立于线程的一个计算引擎,它的数据是局部拥有的,可以启动任意多的局部引擎,取决于计算机配置。启动一个局部引擎相当于开启一个独立的 MATLAB 线程,由于启动 MATLAB 是一个很耗时间的过程,因此应该尽量减少局部引擎的启动数量。引擎控制有类 CMatlabEngine 控制。 CMatlabEngine 的结构如下:

 一组MATLAB和 <wbr>C++数据交换类的设计

bSingleUse=1 表示启动局部引擎, bSingleUse=0 表示启动全局引擎,全局引擎在第一次调用时打开 MATLAB ,以后每调用一次 OpenEngine 打开全局 MATLAB ,则引用计数加一;调用一次 closeEngine 引用计数减一。当引用计数为 0 时,表示当前没有程序对全局 MATLAB 进行调用,此时将自动关闭 MATLAB 。

调用 void SetEngineVisible(BOOL bVisible) 将决定是否显示 MATLAB 的窗口界面。函数 void PutVar(char *name,MatlabData* d) 将向 MATLAB 空间中添加一个自定义变量,其中 name 为变量名称, d 为变量内容,若该变量已经存在,则调用该函数将覆盖已存在变量值。函数 BOOL GetVar(char *name,MatlabData** d) 将从 MATLAB 空间中提取一个变量,其中 name 为变量名称, d 为输出指向内容指针的指针,若该变量不存在,则返回 FALSE 。

void EvalString(char* matlabString) 可以和计算引擎进行命令交互, matlabString 为命令,和常规使用 MATLAB 软件所进行的输入一致。一旦调用某个命令, MATLAB 将有反馈输出,可能是计算结果,也可能是错误信息,这些信息可以通过调用 const char* GetOutPut() 来获取。

 

2. 数据类型接口设计

   所有 MATLAB的 C API的数据类型是 mxArray , MATLAB 提供了一组 C  API 来进行数据操作。 mxArray 是一种包含多种类型的数据,可以是数值,字符, cell 或者是结构体;数据类型可以是标量,矩阵,STRUCT或者是 Array 。
一组MATLAB和 <wbr>C++数据交换类的设计


针对实际应用,将常用的数据类型进行接口设计。数据结构可分为标量,矩阵和阵列。数据类型有双精度浮点数,单精度浮点数, 32 位整数, 64 位整数,字符串,布尔型。

如图所示,将数据结构分为三种,分别是:标量、矩阵和阵列。将数据类型分位四种:

浮点数、布尔型,整形和字符串。类继承关系图如下

 一组MATLAB和 <wbr>C++数据交换类的设计
以 ImxAray 为借口类,派生出矩阵 xMatrix<T> 和阵列 xAray<T> ,其中 T 位具体类型,采用模板技术,再将类型 T 具体化位实际数据类型如 int,double 等,可以得到相应的矩阵类和阵列类如 xMatrixDouble , xMatrixInt 等。

一组MATLAB和 <wbr>C++数据交换类的设计

图中并为列出所有模板绑定的类型,更具体的类列表如下:
// 矩阵
typedef xMatrix<bool> xMatrixBool;   
typedef xMatrix<char> xMatrixChar;   
typedef xMatrix<double> xMatrixDouble;   
typedef xMatrix<float> xMatrixFloat;   
typedef xMatrix<int> xMatrixInt;   
typedef xMatrix<unsigned int> xMatrixUInt;   
typedef xMatrix<__int64> xMatrixInt64;   
typedef xMatrix<unsigned __int64> xMatrixUInt64;   
//阵列   
typedef xArray<bool> xArrayBool;   
typedef xArray<char> xArrayChar;   
typedef xArray<double> xArrayDouble;   
typedef xArray<float> xArrayFloat;   
typedef xArray<int> xArrayInt;   
typedef xArray<unsigned int> xArrayUInt;   
typedef xArray<__int64> xArrayInt64;   
typedef xArray<unsigned __int64> xArrayUInt64;   
//浮点数   
typedef xDouble_Float<double>  xDouble;   
typedef xDouble_Float<float>  xFloat;   
//整数   
typedef xinterger<int>  xInt;   
typedef xinterger<unsigned int>  xUInt;   
typedef xinterger<__int64>  xInt64;   
typedef xinterger<unsigned __int64>  xUInt64;   
最后开发包装接口mxWrap 。mxWrap 的构造函数提供了从标量、矩阵、阵列到字符的封装。根据不同的数据类型动态创建数据类型,从而实现了用

单一接口类来操作不同数据类型。下面将逐一介绍每个类的实现情况。

1.       ImxArray
一组MATLAB和 <wbr>C++数据交换类的设计

ImxArray 是数据接口类,主要成员数据有三个:
mxArray *m_pArray;
int       m_dataType;
char     m_szTypeName[64];

(其中 mxArray 是 MATLAB C API 的主要数据类型,通过 MATLAB C API 可以实现数据交互。具体使用情况可以参考 MATLAB HELP 。)

m_pArray 是存放 MATLAB 数据的指针, m_pArray 可以存放 MATLAB 中所有的数据,包括标量、矩阵、 STRUCT 和 CELL 等类型数据,通过 CLASSID 来标示数据类型,通过获取数据维数来标示是标量,矩阵还是阵列。可用的 CLASSID 列表如下:
typedef enum   
   
 
    mxUNKNOWN_CLASS = 0,    
 
    mxCELL_CLASS,    
 
    mxSTRUCT_CLASS,    
 
    mxLOGICAL_CLASS,    
 
    mxCHAR_CLASS,    
 
    mxVOID_CLASS,    
 
    mxDOUBLE_CLASS,    
 
    mxSINGLE_CLASS,    
 
    mxINT8_CLASS,    
 
    mxUINT8_CLASS,    
 
    mxINT16_CLASS,    
 
    mxUINT16_CLASS,    
 
    mxINT32_CLASS,    
 
    mxUINT32_CLASS,    
 
    mxINT64_CLASS,    
 
    mxUINT64_CLASS,    
 
    mxFUNCTION_CLASS,    
 
    mxOPAQUE_CLASS,    
 
    mxOBJECT_CLASS,     
 
#if defined(_LP64) || defined(_WIN64)    
 
    mxINDEX_CLASS = mxUINT64_CLASS,    
 
#else    
 
    mxINDEX_CLASS = mxUINT32_CLASS,    
 
#endif    
 
    mxSPARSE_CLASS = mxVOID_CLASS     
 
   
 
本文封装了的数据类型包含了大部分 MATLAB 的数据类型 :

int32,int64,single,double,char,bool,string,struct,uint32,uint64.

未涉及的数据类型有 :

mxCELL_CLASS,mxFUNCTION_CLASS,mxOPAQUE_CLASS, mxOBJECT_CLASS 。

m_dataType 标示数据类型:

//matlab 数据类型 mxarray 封装

  1. //matlab数据类型mxarray封装  
  2. #define  MX_DATA_DOUBLE           //double  
  3. #define  MX_DATA_FLOAT            //double  
  4. #define  MX_DATA_BOOL             //bool  
  5. #define  MX_DATA_INT              //bool  
  6. #define  MX_DATA_UINT             //bool  
  7. #define  MX_DATA_INT64            //bool  
  8. #define  MX_DATA_UINT64           //bool  
  9. #define  MX_DATA_STRING           //string  
  10. #define  MX_DATA_NUMRIC_MATRIX    //数值矩阵  
  11. #define  MX_DATA_NUMRIC_ARRAY     10 //数值阵列  
  12. #define  MX_DATA_STRUCT           12 //结构体  
  13.   
  14. //matrix  
  15. #define  MX_DATA_MATRIX_DOUBLE           21 //double  
  16. #define  MX_DATA_MATRIX_FLOAT            22 //double  
  17. #define  MX_DATA_MATRIX_BOOL             23 //bool  
  18. #define  MX_DATA_MATRIX_INT              24 //bool  
  19. #define  MX_DATA_MATRIX_UINT             25 //bool  
  20. #define  MX_DATA_MATRIX_INT64            26 //bool  
  21. #define  MX_DATA_MATRIX_UINT64           27 //bool  
  22. #define  MX_DATA_MATRIX_STRING           28 //string  
  23. #define  MX_DATA_MATRIX_STRUCT           29 //结构体  
  24.   
  25. //array  
  26. #define  MX_DATA_ARRAY_DOUBLE           31 //double  
  27. #define  MX_DATA_ARRAY_FLOAT            32 //double  
  28. #define  MX_DATA_ARRAY_BOOL             33 //bool  
  29. #define  MX_DATA_ARRAY_INT              34 //bool  
  30. #define  MX_DATA_ARRAY_UINT             35 //bool  
  31. #define  MX_DATA_ARRAY_INT64            36 //bool  
  32. #define  MX_DATA_ARRAY_UINT64           37 //bool  
  33. #define  MX_DATA_ARRAY_STRING           38 //string  
  34. #define  MX_DATA_ARRAY_STRUCT           39 //结构体 


virtual mxArray* GetArray(){ return m_pArray;}
virtual bool     SetArray(mxArray* pArray,bool bCopy=0){ return 1;};
GetArray 和 SetArray 未设置数据和获取数据的接口。 SetArray 带一个参数 bCopy 标示是否拷贝一份输入参数 pArray ,当 bCopy=0 是 ImxAray 对象将指向 pArray 所标示的数据,此时不能调用 mxDestroyArray 销毁 pArray ,否则将出错;若 bCopy=1 , ImxAray 对象将拥有一份独立的 pArray 的拷贝。 ImxAray 一般不单独使用,而是通过 mxWrap 来调用, mxWrap 定义了一系列含不同参数的构造函数来生成特定类型的数据,具体可参考 mxWrap 的实现部分。

2.xBool 布尔类型
一组MATLAB和 <wbr>C++数据交换类的设计


3.xDouble_Float<T> 浮点型
 一组MATLAB和 <wbr>C++数据交换类的设计

浮点型数据分为实数和复数, IsComplex 可判断数据类型。构造函数如下:

xDouble_Float(T valReal=0.0,T valImg=0,bool bComplex=0);

通过 bComplex 设置数据是实数还是复数。数据操作函数如下:
//real    
T GetRealData();    
void   SetRealData(T val);    
//img    
T GetImgData();    
void   SetImgData(T val);   

4. xinterger<T> 整型

一组MATLAB和 <wbr>C++数据交换类的设计

5.string 字符串
一组MATLAB和 <wbr>C++数据交换类的设计 


6.xMatrix<T> 矩阵
一组MATLAB和 <wbr>C++数据交换类的设计


模板实例化如下:
// 矩阵    
typedef xMatrix<bool> xMatrixBool;   
typedef xMatrix<char> xMatrixChar; 
typedef xMatrix<double> xMatrixDouble;   
typedef xMatrix<float> xMatrixFloat;   
typedef xMatrix<int> xMatrixInt;   
typedef xMatrix<unsigned int> xMatrixUInt;   
typedef xMatrix<__int64> xMatrixInt64;   
typedef xMatrix<unsigned __int64> xMatrixUInt64;   
// 矩阵

typedef xMatrix<bool> xMatrixBool;
typedef xMatrix<char> xMatrixChar;
typedef xMatrix<double> xMatrixDouble;
typedef xMatrix<float> xMatrixFloat;
typedef xMatrix<int> xMatrixInt;
typedef xMatrix<unsigned int> xMatrixUInt;
typedef xMatrix<__int64> xMatrixInt64;
typedef xMatrix<unsigned __int64> xMatrixUInt64;

 

矩阵的主要参数是行和列, GetR() 获得行数; GetC() 获取列数。构造函数如下:

       xMatrix(mwSize m=1, mwSize n=1, T *valReal=0,T *valImg=0,mxComplexity flag=mxREAL);

这里需要注意几点:

1.       matlab 和 c++ 的数据存储方式有差别, matlab 的矩阵是按列存储的,所有在数据交互是需注意数据的格式。当输入矩阵时,比如:

view plaincopy to clipboardprint?
double  dm1[]=//2*3    
   
      11,12,13,   
      21,22,23,    
};    
xMatrixDouble  dm(2,3,dm1);  

 
输入数据是

11 12 13

21 22 23

而在 matlab 中矩阵是这样的:

11 13 22

12 21 23

即先从输入数据顺序读入: 11,12,13,21,22,23 ,,然后按列放置

先放置第一列

11

12

第二列:

11 13

12 21

第三列:

11 13 22

12 21 23

 
可以调用 static void  C2Mat(T* c_input,int r,int c,T*m_outPut); 来把 C 格式转换为 matlab 格式。这样你所输入的矩阵将和 MATLAB 空间中的矩阵一致:
double  dm1[]=//2*5   
  
    11,12,13,14,15,   
    21,22,23,24,25   
};   
xMatrixDouble::C2Mat(dm1,2,5,dm1);   
xMatrixDouble  dm(2,5,dm1);   
cout<<"\nmatrix\n";   
for (int i=0;i<dm.GetR();i++)   
  
    for (int k=0;k<dm.GetC();k++)   
    {   
        cout<<dm.GetRealAt(i,k)<<"  ";   
    }   
    cout<<endl;   
      }  
        double  dm1[]=//2*5
    {
        11,12,13,14,15,
        21,22,23,24,25
    };
    xMatrixDouble::C2Mat(dm1,2,5,dm1);
    xMatrixDouble  dm(2,5,dm1);
    cout<<"\nmatrix\n";
    for (int i=0;i<dm.GetR();i++)
    {
        for (int k=0;k<dm.GetC();k++)
        {
            cout<<dm.GetRealAt(i,k)<<"  ";
        }
        cout<<endl;
       }

一组MATLAB和 <wbr>C++数据交换类的设计

2. 只有 double 和 float 拥有复数类型,所有对于其他矩阵,复数没有意义,所以在构造函数初始化时: xMatrix(mwSize m=1, mwSize n=1, T *valReal=0,T *valImg=0,mxComplexity flag=mxREAL) ,参数 valImg=0 , flag=mxREAL 。


7. xArray<T> 阵列
一组MATLAB和 <wbr>C++数据交换类的设计 


所谓阵列就是指维数在二维以上的数据,

int  GetDimSize(); 获取维数

int  GetDim(int index ); 获取第几维的长度

int  GetDataSize(); 获取存放的总数据个数,即维数尺寸的乘积

矩阵时维数维二维的阵列,在数据类型设计中,原本是这样考虑的:先构建阵列维模板,然后通过将阵列的维数设置为两维,从而派生出矩阵类,矩阵类的所有操作都委托给二维阵列,将矩阵的行数和列数设置为 1 ,从而派生出标量类,操作委托给行数和列数为 1 的矩阵,由于这些类都是模板类,所有对模板进行实例化可以得到各种不同的类型。

后来参考了 MATLAB C API ,发现 API 里对不同的数据类型的都有各自的处理函数,通过阵列函数来操作矩阵或者标量或许有些大材小用,影响性能。阵列的数据存放和矩阵一样是按列来的,对于三维以上的阵列,数据的输入可能就比较复杂了,处理时可要细心。 MATLAB 提供了 API 来进行数据转换,可以参考 HELP.

void  GetRealData(T*bufferReal,int buffersize);    
 
void  SetRealData(T*bufferReal,int buffersize);    
 
void  GetImgData( T*bufferImg, int buffersize);    
 
void  SetImgData( T*bufferImg, int buffersize);   
 
通过调用 GetRealData 可获取实部数据,注意缓存区大小要够,即 buffersize>= GetDataSize().
调用 SetRealData 设置数据。虚部处理一样。

8.xStruct 结构体

一组MATLAB和 <wbr>C++数据交换类的设计


结构体由若干数据项组成,每个数据项包括名称和数据,和 C 语言的结构体是一样的, xStruct 可以增加数据相或者删除数据项 .
int      GetFieldCount();// 获得数据项数量    
bool     AddField( const char *fieldname);// 增加一个数据项,    
bool     RemoveField( int index);// 删除数据项    
mxWrap  *GetField( mwIndex i);// 获取每个数据项的数据    
std::string  GetFieldName(mwIndex i);// 获得某项数据项的名称    
bool      SetField(mwIndex i,mxWrap *value);// 设置数据    
bool     SetField(std::string item_name,mxWrap *value);   

9.mxWrap
一组MATLAB和 <wbr>C++数据交换类的设计
mxWrap 主要有多个不同参数的构造函数,通过传递不同的参数可以构造出不同的数据类型出来,包括标量、矩阵、阵列和结构体。和 matlab 的交互过程可简化为:

写入变量、执行计算和提取结果。使用 mxWrap 来写入变量和提取结果客大大简化交互程序。

举例子如下:

       矩阵 A=[1 2 3;4 5 6; 7 8 9;]; B=[11 21 31;41 51 61; 71 81 91;]; 求 矩阵 C=A*B;

代码如下:

CMatlabEngine  g;//gobal engine    
g.OpenEngine();;//open engine    
 
//MATRIX A    
double  A[]=    
   
    1,2,3,    
    4,5,6,    
    7,8,9    
};    
xMatrixDouble::C2Mat(A,3,3,A);    
 
//MATRIX B    
double  B[]=    
   
    11,21,31,    
    41,51,61,    
    71,81,91    
 };    
xMatrixDouble::C2Mat(B,3,3,B);    
 
//VAR A and B    
mxWrap  a(3,3,A);    
mxWrap  b(3,3,B);    
 
//PUT VAR    
g.PutVar("A",a.GetArray());    
g.PutVar("B",b.GetArray());    
 
//CAL    
g.EvalString("C=A*B");    
 
//get val    
mxWrap c;    
g.GetVar("C",&c);    
//disp data    
 
xMatrixDouble*ptr=(xMatrixDouble*)c.GetArrayInterface();    
cout<<"C=A*B\n";    
for (int i=0;i<ptr->GetR();i++)    
   
   for (int j=0;j<ptr->GetC();j++)    
    {    
 
        cout<<ptr->GetRealAt(i,j)<<"  ";    
 
     } cout<<endl;    
   
g.CloseEngine();//close   


一组MATLAB和 <wbr>C++数据交换类的设计


10.xFile
一组MATLAB和 <wbr>C++数据交换类的设计

Mat 文件是 matlab 特有的数据存储文件类型,将变量存储于 mat 文件可以很方便进行数据交互。 MATLAB 提供了一组 API 进行 mat 文件操作,这些 API 以 mat 开头,如 matOpen 。
xFile 封装类 mat 文件的操作。

调用 bool  Open(char *matFile,char* mode="u"); 打开一个 mat 文件, mode 为操作方式,可以为 mode="r" 读 , "u" 读写 ,"w" 写 ,"w4","wL","wz" 压缩模式。

mxWrap* GetArray(char*name,bool bCopy=1); 获取特定名称的变量

void    SetArray(char*name,mxWrap*pArray); 添加变量,若该变量已经存在,则会更新变量

int     GetVarCount();// 获得变量的个数

mxWrap* GetArray(int index,std::string*nameOut=NULL,bool bCopy=1);

遍历所有遍历:

for (int i=0;i<GetVarCount();i++)
{
       std::string name;
       mxWrap*ptr=GetArray(i,&name);
}
一个写mat文件的例子:
    cout<<"===========写mat文件测试====================\n";   
    xFile f;   
    mxWrap d(12.0);   
    if(0==f.Open("D:\\write.mat","w"))   
    {   
        cout<<"打开文件:D:\\write.mat失败\n";   
        return ;   
    }   
       
    xDouble v1(123.0);   
    f.SetArray("double_v",&mxWrap(v1.GetArray()));   
    //替换测试   
    xString v11("double_v——通过测试");   
    f.SetArray("double_v",&mxWrap(v11.GetArray()));   
 
 
    xFloat v2(223.0);   
    f.SetArray("xFloat_v",&mxWrap(v2.GetArray()));   
       
    xString v3("xString");   
    f.SetArray("xString_v",&mxWrap(v3.GetArray()));   
       
    //替换测试   
    xString v31("xString——通过测试");   
    f.SetArray("xString_v",&mxWrap(v3.GetArray()));   
       
    xBool v4(1);   
    f.SetArray("xBool_v",&mxWrap(v4.GetArray()));   
      
    xInt v5(1569);   
    f.SetArray("xInt_v",&mxWrap(v5.GetArray()));   
       
       
    xUInt v6(136);   
    f.SetArray("xUInt_v",&mxWrap(v6.GetArray()));   
       
    xInt64 v7(64);   
    f.SetArray("xInt64_v",&mxWrap(v7.GetArray()));   
       
    xUInt64 v8(164);   
    f.SetArray("xUInt64_v",&mxWrap(v8.GetArray()));   
       
    double dt[8]={1,2,3,4,5,6,7,8};   
    xMatrixDouble v9(2,4,dt);   
    f.SetArray("xMatrixDouble_v",&mxWrap(v9.GetArray()));   
       
       
    mwSize dm[3]={2,2,2};   
    xArrayDouble v10(3,dm,dt);   
    f.SetArray("xArrayDouble_v",&mxWrap(v10.GetArray()));   
       
 
    xStruct  xs;   
    xs.AddField("sam");   
    xs.AddField("love");   
    xs.SetField(0,new mxWrap(120.364));   
    xs.SetField(1,new mxWrap("The type_info class describes type information generated within the program by the compiler. Objects of this class effectively store a pointer to a name for the type and an encoded value suitable for comparing two types for equality or collating order. The encoding rules and collating sequence for types are unspecified and may differ between programs."));   
    f.SetArray("xstruct",&mxWrap(xs.GetArray()));   
       
    ///删除变量   
    if(f.RemoveVar("xInt_v"))cout<<"成功删除变量!\n";   
    if(f.RemoveVar("xMatrixDouble_v"))cout<<"成功删除变量!\n";   
    if(0==f.RemoveVar("不存在的名称"))   
        cout<<"删除不存在变量失败!\n";   
       
    f.Close();   
 
 
 将得到的mat文件调入matlab查看:
一组MATLAB和 <wbr>C++数据交换类的设计


下面举例如何使用该程序

例一:

输入任意y=f(x),求y对x的n阶导数,结果存放到字符串中取得,并计算原函数和n阶导数在x0处的值。

    CMatlabEngine  eng;
    eng.OpenEngine();
    
    char tmp[200];//表达式
    char tmp1[200];
    mxWrap  df;//导数表达式
    mxWrap  val;//原函数值
    mxWrap  dfval;//导数值
    xDouble  vx0;//x0 输入
    double  x0=0;
    int n=1;//导数阶数

    
    strcpy(tmp,"syms x;");
    eng.EvalString(tmp);
    
    cout<<"输入表达式:";
    cin>>tmp;
    cout<<"输入导数阶数:";
    cin>>n;
    cout<<"输入x0:";
    cin>>x0;
    vx0.SetRealData(x0);
    while( tmp[0] != 'q' )
    {
        eng.PutVar("x0",vx0.GetArray());//input x0
        //get express
        sprintf(tmp1,"%s;z1=char(diff(y,%d)),z=char(z1),val=subs(y,x,x0),dfval=subs(z,x,x0)",tmp,n);
        //cal
        eng.EvalString(tmp1);
        //get val
        eng.GetVar("z",&df);//n阶导数表达式
        eng.GetVar("val",&val);//原函数在x0处的数值
        eng.GetVar("dfval",&dfval);//n阶导数在x0处的数值
        cout<<"---------------------------matlab output----------------\n";
        cout<<eng.GetOutPut()<<endl;
        cout<<"---------------------------------------------------------\n";
        cout<<"---------------------------求导结果----------------\n";
        xString*ps=(xString*)df.GetArrayInterface();
        cout<<"求导结果:"<<ps->GetString().data()<<endl;
        xDouble*pd=(xDouble*)val.GetArrayInterface();
        cout<<"原函数在x0处的值:"<<pd->GetRealData()<<endl;
        pd=(xDouble*)dfval.GetArrayInterface();
        cout<<"原函数导n阶数在x0处的值:"<<pd->GetRealData()<<endl;
        cout<<"----------------------------------------------------\n";
        cout<<"输入表达式:";
        cin>>tmp;
        cout<<"输入导数阶数:";
        cin>>n;
        cout<<"输入x0:";
        cin>>x0;
        vx0.SetRealData(x0);
    }
    eng.CloseEngine();

编译运行:

输入 y=x^2+x

        n=1

        x0=10

输出:

       dff=2*x+1

       val=110

       dfval=21
一组MATLAB和 <wbr>C++数据交换类的设计 



例2:mat文件操作

这个例子将展示如何用xFile读取mat文件和写mat文件

A=[1 2 3;4 5 6;7 8 9];

B="南京航空航天大学 san visualsan@yahoo.cn";

C.name="san";C.address="NUAA";C.score=99.9;C.matrix=[12  22 32];

D=123.00

E=100;

将A,B,C,D,E写入d:\\result.mat
int dA[]=   
  
    1 ,2 ,3,   
    4 ,5 ,6,   
    7 ,8 ,9   
};   
xMatrixInt::C2Mat(dA,3,3,dA);   
 
mxWrap A(3,3,dA);   
mxWrap B("南京航空航天大学 san visualsan@yahoo.cn");   
 
xStruct* xs=new xStruct;   
//add field   
xs->AddField("name");   
xs->AddField("address");   
xs->AddField("score");   
xs->AddField("matrix");   
 
mxWrap*ptr;   
ptr=new mxWrap("san");   
xs->SetField(0,ptr);//add name   
ptr=new mxWrap("NUAA");   
xs->SetField(1,ptr);//add address   
ptr=new mxWrap(99.9);   
xs->SetField(2,ptr);//add score   
double m[]={12 ,22, 32};   
xMatrixDouble::C2Mat(m,1,3,m);   
ptr=new mxWrap(1,3,m);;   
xs->SetField(3,ptr);//add matrix   
 
 
mxWrap  C(xs);   
mxWrap  D(123.00);   
mxWrap  E(100);   
 
xFile  xf;   
//OPEN FILE   
xf.Open("d:\\result.mat","w");   
 
//ADD VAR   
xf.SetArray("A",&A);   
xf.SetArray("B",&B);   
xf.SetArray("C",&C);   
xf.SetArray("D",&D);   
xf.SetArray("E",&E);   
 
//CLOSE   
xf.Close();  

 
将result.mat调入matlab查看:
一组MATLAB和 <wbr>C++数据交换类的设计


从d:\result.mat读取所有变量并显示:


template<class T>   
struct   disp_matrix//矩阵打印   
  
    void operator()(ImxArray*m)   
    {   
        xMatrix<T>*pm=(xMatrix<T>*)m;   
        cout<<"==============matrix===========\n";   
        cout<<m->GetTypeName()<<endl;   
        for (int i=0;i<pm->GetR();i++)   
        {   
            for (int j=0;j<pm->GetC();j++)   
            {   
                cout<<pm->GetRealAt(i,j)<<"  ";   
            }   
            cout<<endl;   
               
        }   
    }   
};   
 
template<class T>   
struct   disp_array//阵列打印   
  
    void operator()(ImxArray*m){   
    std::string str=typeid(T).name();   
    cout<<str.data()<<endl;   
    xArray<T>*pm=(xArray<T>*)m;   
    cout<<"============== array===========\n";   
    T *dt=new T[pm->GetDataSize()];   
    pm->GetRealData(dt,pm->GetDataSize());   
    for (int k=0;k<pm->GetDataSize();k++)   
    {   
        cout<<dt[k]<<" ";   
           
    }      
    cout<<endl;   
    delete dt;   
    }   
};   
void  display_data(ImxArray*ptr,std::string& n)//数据打印   
  
    if(!ptr)   
        return ;   
    //double   
    if(ptr->GetType()==MX_DATA_DOUBLE)   
    {   
        cout<<n.data()<<"  =====double======   "<<((xDouble*)ptr)->GetRealData()<<endl;   
    }   
    //FLOAT   
    if(ptr->GetType()==MX_DATA_FLOAT)   
    {   
        cout<<n.data()<<"  =====float======   "<<((xFloat*)ptr)->GetRealData()<<endl;   
    }   
    //string   
    if(ptr->GetType()==MX_DATA_STRING)   
    {   
        cout<<n.data()<<"  =====string======   "<<((xString*)ptr)->GetString().data()<<endl;   
    }   
    //bool   
    if(ptr->GetType()==MX_DATA_BOOL)   
    {   
        cout<<n.data()<<"  =====bool======   "<<((xBool*)ptr)->GetData()<<endl;   
    }   
    //int   
    if(ptr->GetType()==MX_DATA_INT)   
    {   
        cout<<n.data()<<"  =====uint======   "<<((xInt*)ptr)->GetData()<<endl;   
    }   
    //unsigned int   
    if(ptr->GetType()==MX_DATA_UINT)   
    {   
        cout<<n.data()<<"  =====int64======   "<<((xUInt*)ptr)->GetData()<<endl;   
    }   
    //int64   
    if(ptr->GetType()==MX_DATA_INT64)   
    {   
        cout<<n.data()<<"  =====uint64======   ";   
        printf("%I64d\n",((xInt64*)ptr)->GetData());   
    }   
    //unsigned int64   
    if(ptr->GetType()==MX_DATA_UINT64)   
    {   
        cout<<n.data()<<"  =====uint64======   ";   
        printf("%I64u\n",((xInt64*)ptr)->GetData());   
    }   
    // matrix   
    if(ptr->GetType()==MX_DATA_MATRIX_BOOL)   
    {   
        disp_matrix<bool>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_STRING)   
    {   
        disp_matrix<char>(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_DOUBLE)   
    {   
        disp_matrix<double>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_FLOAT)   
    {   
        disp_matrix<float>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_INT)   
    {   
        disp_matrix<int>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_UINT)   
    {   
        disp_matrix<unsigned int>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_INT64)   
    {   
        cout<<"__int64\n";   
        //disp_matrix<__int64>(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_MATRIX_INT64)   
    {   
        cout<<"unsigned __int64\n";   
        //disp_matrix<unsigned __int64>(ptr);   
    }   
    // array   
    if(ptr->GetType()==MX_DATA_ARRAY_BOOL)   
    {   
        disp_array<bool>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_STRING)   
    {   
        disp_array<char>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_DOUBLE)   
    {   
        disp_array<double>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_FLOAT)   
    {   
        disp_array<float>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_INT)   
    {   
        disp_array<int>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_UINT)   
    {   
        disp_array<unsigned int>()(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_INT64)   
    {   
        cout<<"__int64\n";   
        //disp_matrix<__int64>(ptr);   
    }   
    if(ptr->GetType()==MX_DATA_ARRAY_INT64)   
    {   
        cout<<"unsigned __int64\n";   
        //disp_matrix<unsigned __int64>(ptr);   
    }   
       
    //struct   
    if (ptr->GetType()==MX_DATA_STRUCT)   
    {   
        cout<<"---------------------struct----------------------------------------------\n";   
        xStruct*ps=(xStruct*)ptr;   
        for (int i=0;i<ps->GetFieldCount();i++)   
        {   
            if(ps->GetField(i)->GetArrayInterface())   
                display_data(ps->GetField(i)->GetArrayInterface(),n);   
        }   
        cout<<"---------------------struct----------------------------------------------\n";   
    }   
  
void test4()   
  
    xFile  xf;   
    if (xf.Open("d:\\result.mat","r"))   
    {   
        cout<<"变量个数:"<<xf.GetVarCount()<<endl;   
        std::vector<mxWrap*>  var;   
        std::vector<std::string>  vname;   
        for (int i=0;i<xf.GetVarCount();i++)   
        {   
            std::string name;   
            var.push_back(xf.GetArray(i,&name,1));   
            vname.push_back(name);   
            //输出名称   
            printf("var name(-)= s\n",i+1,name.data());   
        }   
 
        //输出每个变量   
        for(i=0;i<var.size();i++)   
        {   
            display_data(var[i]->GetArrayInterface(),vname[i]);   
        }   
    }   
 
结果如下:
一组MATLAB和 <wbr>C++数据交换类的设计

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值