Matlab集成程序:matGear(仿真工程方面)

Matlab集成程序:matGear(仿真工程方面)  

J-SUN-SO visualsan@yahoo.cn 2013.3      代码下载:

matlab作为一种强大的科学计算语言,其强大的计算能力和海量的函数工具包,把它作为后台计算语言嵌入到你的软件中去,可以省去繁杂的数学公式编程,是一种很好的计算资源。而matlab本身也提供了一组C语言API供程序调用。本文基于这组C语言API对MATLAB进行二次开发matGear,其目的只有一个:以更简便的方式,把MATLAB集成到自己的工程项目中去。

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

MEngine的结构如下:

View Code
class MEngine  
{
public:
//初始化函数的bSingleUse=1表示启动一个局部引擎,bSingleUse=0表示启动全局引擎。
    MEngine(BOOL bSingleUse=0);// bSingleUse=0启动全局引擎,计算空间数据共享
    virtual ~MEngine();

    BOOL IsEngineOpen();//是否候已经打开引擎
    BOOL IsSingleUse();//是否是局部引擎
    
    BOOL OpenEngine();//打开引擎
    BOOL CloseEngine();//关闭引擎
    
    void SetEngineVisible(BOOL bVisible);//设置引擎是否可见
    BOOL GetEngineVisible();
    
    void PutVar(char *name,MatlabData* d);//向MATLAB输入参数
    BOOL GetVar(char *name,MatlabData** d);// 获取MATLAB参数
    
    //执行命令
    void EvalString(char* matlabString);
    const char* GetOutPut();//执行命令后的反馈输出
    
protected:
    Engine *m_matlabEng;
    int     m_bInit;
    char    m_OutBuffer[MAX_OUT_PUT];//局部matlab输出
    static char    g_OutBuffer[MAX_OUT_PUT];//全局malab输出
    int     m_bSingleUse;//是否独立开启一个matlab线程,否则将共享一个MATLAB线程。
};

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语言的数据类型是mxArray,MATLAB提供了一组C语言API来进行数据操作。mxArray是一种包含多种类型的数据,可以是数值,字符,cell或者是结构体;数据类型可以是标量,矩阵或者是Array。

   针对实际应用,将常用的数据类型进行接口设计。数据结构可分为标量,矩阵,阵列和结构体。数据类型有双精度浮点数,单精度浮点数,32位整数,64位整数,字符串。最后开发包装接口,实现类位mxWrap。mxWrap结构如下。mxWrap的构造函数提供了从标量、矩阵、阵列到字符的封装。根据不同的数据类型动态创建数据类型,从而实现了用单一接口类来操作不同数据类型。

测试函数:

/************************************************************************/
    /* test matlab engine                                                                     */
    /************************************************************************/
    static void TestEngine();

    static void ArrayTest();
    static void MatricTest();

    //test matlab file write,you can check the file in matlab
    static void mat_file_write_test(std::string path="c:\\mat_test.mat");//mat文件测试
    //read mat file test
    static void    mat_file_read_test(std::string path="c:\\mat_test.mat");

    //inout var to engine,run cmd and get result 
    static  void test1();

    //Calculate Derivation
    static void cal_der();

    //test mxWrap
    static void mxWrap_test();

    //read the var name from mat file
    static void mat_var_name(std::string path="c:\\mat_test.mat");

void
MatTest::TestEngine() { char *msg= "----Test For Matlab Engine!----------------------\n" "----Type any matlab cmd and type empty to exit!--\n" " visualsan@yahoo.cn 2013.3.9--\n" "-------------------------------------------------\n"; cout<<msg; MatEngine eng(0);//global engine cout<<"open engine.....\n"; if (!eng.OpenEngine()) { cout<<" fail to open matlab!\n"; return; } eng.SetEngineVisible(False); char cmd[500]; while (1) { cout<<">>"; cin>>cmd; if(strcmp(cmd,"exit")==0) { eng.CloseEngine(); return; } eng.EvalString(cmd); cout<<eng.GetOutPut()<<endl; } }
engine test
void MatTest::TestEngine()
{
    char *msg=
        "----Test For Matlab Engine!----------------------\n"
        "----Type any matlab cmd and type empty to exit!--\n"
        "                    visualsan@yahoo.cn 2013.3.9--\n"
        "-------------------------------------------------\n";
    cout<<msg;

    MatEngine  eng(0);//global engine
    cout<<"open engine.....\n";
    if (!eng.OpenEngine())
    {
        cout<<" fail to open matlab!\n";
        return;
    }

    eng.SetEngineVisible(False);
    char cmd[500];
    while (1)
    {
        cout<<">>";
        cin>>cmd;
        if(strcmp(cmd,"exit")==0)
        {
            eng.CloseEngine();
            return;
        }

        eng.EvalString(cmd);
        cout<<eng.GetOutPut()<<endl;
    }
 
}

ArrayTest()

void MatTest::ArrayTest()
 {
     char *msg=
         "----Test For Matlab Array data struct!----------------------\n"
         "                    visualsan@yahoo.cn 2013.3.9--\n"
         "-------------------------------------------------\n";
     cout<<msg;

     mwSize sz[2]={2,3};
     mwSize d=2;
     string str;
#define TEST_TYPE(s) str=s;cout<<str.data();
     
     TEST_TYPE("bool array test(bool阵列测试)\n");
     bool  ba1[]={false,true,false,false,true,false};
     bool  ba2[6]={false};
     xArrayBool ba(d,sz,ba1);
     ba.GetRealData(ba2,6);
     int i=0;
     for (;i<6;i++)
     {
         cout<<ba1[i]<<"="<<ba2[i]<<" ";
     }
     cout<<endl;

     TEST_TYPE("char array test(char阵列测试)\n");
     char  ca1[]={'a','b','c','d','e','f'};
     char  ca2[6]={'0'};
     xArrayChar ca(d,sz,ca1);
     ca.GetRealData(ca2,6);
     for ( i=0;i<6;i++)
     {
         cout<<"'"<<ca1[i]<<"'='"<<ca2[i]<<"' ";
     }
     cout<<endl;

     TEST_TYPE("double array test(double阵列测试)\n");
     double  da1[]={100.0,200.0,300.0,400.0,500.0,600.0};
     double  da2[6]={'0'};
     xArrayDouble da(d,sz,da1);
     da.GetRealData(da2,6);
     for ( i=0;i<6;i++)
     {
         cout<<da1[i]<<"="<<da2[i]<<" ";
     }
     cout<<endl;

     TEST_TYPE("float array test(float阵列测试)\n");
     float  fa1[]={1010.0,2010.0,3010.0,4010.0,5010.0,6010.0};
     float  fa2[6]={'0'};
     xArrayFloat fa(d,sz,fa1);
     fa.GetRealData(fa2,6);
     for ( i=0;i<6;i++)
     {
         cout<<fa1[i]<<"="<<fa2[i]<<" ";
     }
     cout<<endl;

     TEST_TYPE("int array test(int阵列测试)\n");
     int  ia1[]={101,201,301,401,501,601};
     int  ia2[6]={'0'};
     xArrayInt ia(d,sz,ia1);
     ia.GetRealData(ia2,6);
     for ( i=0;i<6;i++)
     {
         cout<<ia1[i]<<"="<<ia2[i]<<" ";
     }
     cout<<endl;

     NOTE_IN_END;
 }
matrix test
View Code
void  MatTest::MatricTest()
{

    char *msg=
        "----Test For Matlab Matrix !----------------------\n"
        "                    visualsan@yahoo.cn 2013.3.9--\n"
        "-------------------------------------------------\n";
    cout<<msg;

    double  dm1[]=//2*5
    {
        11,12,13,14,15,
        21,22,23,24,25
    };
    //change c++ matrix style to matlab matrix style
    xMatrixDouble::C2Mat(dm1,2,5,dm1);
    double dm2_r[10];
    double dm2_i[10];
    //a 2X5 matrix
    xMatrixDouble  dm(2,5,dm1,dm1,mxCOMPLEX);
    dm.GetRealData(dm2_r,10);//get real data
    dm.GetImgData(dm2_i,10);//get complex data
    cout<<"input real :\n";
    int i=0;
    for (;i<10;i++)
    {
        cout<<dm2_r[i]<<" ";
    }cout<<"\nmatrix real:\n";
    for (i=0;i<dm.GetR();i++)
    {
        for (int k=0;k<dm.GetC();k++)
        {
            cout<<dm.GetRealAt(i,k)<<"  ";
        }
        cout<<endl;
    }
    cout<<"\ninput img:\n";
    for ( i=0;i<10;i++)
    {
        cout<<dm2_i[i]<<" ";
    }
    cout<<"\nMatrix-real(matlab是按列存储的)\n";
    for (i=0;i<dm.GetR();i++)
    {
        for (int j=0;j<dm.GetC();j++)
        {
            cout<<dm.GetImgAt(i,j)<<" ";
        }
        cout<<endl;
    }

    cout<<"(1,1)="<<dm.GetRealAt(1,1)<<"+"<<dm.GetImgAt(1,1)<<"i"<<endl;
    cout<<"(1,1)changed:\n";
    dm.SetRealAt(1,1,12.111);
    dm.SetImgAt(1,1,22.111);
    cout<<"(1,1)="<<dm.GetRealAt(1,1)<<"+"<<dm.GetImgAt(1,1)<<"i"<<endl;

    NOTE_IN_END;

}

write mat file

void    MatTest::mat_file_write_test(std::string  path)//mat文件测试
{

    cout<<"===========写mat文件测试====================\n";
    xFile f;
    mxWrap d(12.0);
    if(0==f.Open((char*)path.c_str(),"w"))
    {
        cout<<"打开文件失败\n";
        return ;
    }

    xDouble v1(123.0);
    //add double
    f.SetArray("double_v",&mxWrap(v1.GetArray()));
    //replace double var wit string var
    xString v11("double_v——通过测试");
    f.SetArray("double_v",&mxWrap(v11.GetArray()));


    //add float var
    xFloat v2(223.0);
    f.SetArray("xFloat_v",&mxWrap(v2.GetArray()));

    //add string var
    xString v3("xString");
    f.SetArray("xString_v",&mxWrap(v3.GetArray()));

    //替换测试
    xString v31("xString——通过测试");
    f.SetArray("xString_v",&mxWrap(v3.GetArray()));

    //add bool var
    xBool v4(1);
    f.SetArray("xBool_v",&mxWrap(v4.GetArray()));


    //add int var
    xInt v5(1569);
    f.SetArray("xInt_v",&mxWrap(v5.GetArray()));


    //add UINT var
    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()));

    //add matrix
    double dt[8]={1,2,3,4,5,6,7,8};
    xMatrixDouble v9(2,4,dt);
    f.SetArray("xMatrixDouble_v",&mxWrap(v9.GetArray()));


    //add array
    mwSize dm[3]={2,2,2};
    xArrayDouble v10(3,dm,dt);
    f.SetArray("xArrayDouble_v",&mxWrap(v10.GetArray()));


    //add struct
    xStruct  xs;
    xs.AddField("double_number");
    xs.AddField("who_is");
    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();
    cout<<"success write mat file\nuse matlab to check the file\n";
    NOTE_IN_END;

}

 

read mat file

View Code
void    MatTest::mat_file_read_test(std::string path)
{
    //从mat文件读取变量测试
    xFile f;
    mxWrap d(12.0);
    if(!f.Open((char*)path.c_str(),"r"))
    {
        cout<<"cant open file\n";
        return;
    }

    for (int i=0;i<f.GetVarCount();i++)
    {
        std::string n;
        ImxArray*ptr=f.GetArray(i,&n)->GetArrayInterface();
        cout<<"============================"<<n.data()<<ptr->GetType()<<endl;

        display_data(ptr,n);
        //struct
        if(ptr->GetType()==MX_DATA_STRUCT)
        {
            cout<<"     struct=====================\n";
            xStruct*ps=(xStruct*)ptr;
            for (int h=0;h<ps->GetFieldCount();h++)
            {
                cout<<ps->GetFieldName(h).data()<<"=======\n";
                char tmp[200];
                strcpy(tmp,ps->GetFieldName(h).data());
                n=std::string(tmp);
                display_data(ps->GetField(h)->GetArrayInterface(),n);
            }
        }



    }
    f.Close();
    NOTE_IN_END;
}

input and get var

View Code
void MatTest::test1()
{
    MatEngine  g;
    cout<<"open engine.....\n";
    g.OpenEngine();

    //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 
    NOTE_IN_END;
}

use engine sample

void MatTest::cal_der()
{
    MatEngine  eng;
    cout<<"open engine.....\n";
    eng.OpenEngine();
    eng.SetEngineVisible(0);

    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<<"输入表达式(et. y=sin(x) ):";
    cin>>tmp;
    cout<<"输入导数阶数(et. 2):";
    cin>>n;
    cout<<"输入x0(et. 10):";
    cin>>x0;
    vx0.SetRealData(x0);
    while( tmp[0] != 'q' )
    {
        eng.PutVar("x0",vx0.GetArray());//input x0
        //get express
        sprintf(tmp1,"%s;z1=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();
}

mat file var list

void test4()
{
    xFile  xf;
    if (xf.Open("C:\\Documents and Settings\\Administrator\\桌面\\SWING\\mexTest\\mexTest\\Debug\\dC.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(%2d)=%20s\n",i+1,name.data());
        }

        //输出每个变量
        for(i=0;i<var.size();i++)
        {
            display_data(var[i]->GetArrayInterface(),vname[i]);
        }
    }
}

mawrap test

void MatTest::mxWrap_test()
{

    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 and write var to file.you can check file in matlab
    xf.Open("c:\\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();

    mat_file_read_test("c:\\result.mat");
    

    
}

 源代码链接:http://www.pudn.com/downloads519/sourcecode/app/detail2153519.html

转载于:https://www.cnblogs.com/JustHaveFun-SAN/archive/2013/03/09/matGear.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值