美文网首页
MATLAB编程与应用系列-第16章 外部接口技术(3)

MATLAB编程与应用系列-第16章 外部接口技术(3)

作者: 德特数据 | 来源:发表于2018-10-31 22:56 被阅读0次

    本章教程共分为7篇进行阐述:
    MATLAB编程与应用系列-第16章 外部接口技术(1)
    MATLAB编程与应用系列-第16章 外部接口技术(2)
    MATLAB编程与应用系列-第16章 外部接口技术(3)
    MATLAB编程与应用系列-第16章 外部接口技术(4)
    MATLAB编程与应用系列-第16章 外部接口技术(5)
    MATLAB编程与应用系列-第16章 外部接口技术(6)
    MATLAB编程与应用系列-第16章 外部接口技术(7)

    本系列教程来源于出版书籍《基于MATLAB编程基础与典型应用书籍》,如涉及版权问题,请联系:156204968@qq.com。 出版社:人民邮电出版社, 页数:525。

    本系列教程目前基于MATLABR2006a,可能对于更高级版本的功能和函数有差异,教程中如有问题,请联系:156204968@qq.com

    16.3 MAT文件应用

    MAT文件是MATLAB开发环境存储数据的一种特殊的数据格式,使用MAT数据文件可以在不同的开发平台下进行数据交换和通信,可以在独立MATLAB应用程序中导出和读入数据文件。MATLAB应用程序接口(API)函数库提供了使用C,C++和FORTRAN等语言编写的MAT函数库,通过调用MAT函数库,MEX函数库以及MX函数库相关函数,可以非常轻松地编写MEX文件读入和导出MAT格式的数据文件。

    �###16.3.1 MATLAB数据导入导出方式
    在MATLAB开发环境下,可以通过多种不同的手段向MATLAB开发环境中导入数据或者从MATLAB开发环境中向其他开发平台导出数据。

    1. 向MATLAB开发环境中导入数据

    可以通过以下不同的方式向MATLAB开发环境中导入数据,但是对于不同的情况,比如数据规模的大小,开发平台的外部需求等,读者可以选择其中最方便的某一种导入数据方式:

    • 使用命令行导入数据
      这种方法适合与当导入的数据规模比较小,那么可以直接在MATLAB命令行窗口中导入数据。例如:
    >> a = rand(3)
    a =
    
        0.9501    0.4860    0.4565
        0.2311    0.8913    0.0185
        0.6068    0.7621    0.8214
    >> assignin('base','T',a)   //在应用程序中将a变量赋值给变量T
    
    • 创建数据输入的M文件
      很明显,这种数据导入方式仅仅适合与当数据文件还不存在与工作环境下,需要人工输入数据文件时,采用这种方式比较方便。或者从其他环境比如TEXT文件,EXCEL文件中导入数据文件。

    • 使用load命令导入数据文件
      同save命令相对,当数据变量存在与MATLAB工作环境下时,可以使用save命令将数据变量存储为MAT数据文件格式。那么使用load命令就可以直接向Workspace中导入数据文件。

    • 使用MATLAB的I/O函数读取数据文件
      使用MATLAB的I/O函数fopen, fread以及其他的一些I/O读写函数读入其他平台下的数据文件格式。

    • 编写MEX文件读入MAT数据
      通过MATLAB应用程序接口(API)的MEX函数库,MX函数库和MAT函数库,编写MEX文件读入MAT数据文件。在本节的实例演示中将提供一个标准的MEX文件读入MAT数据的程序代码。

    2. 从MATLAB环境中导出数据

    同向MATLAB环境导入数据相仿,从MATLAB环境中导出数据也有相对应的一些方式可以供读者进行选择参考。

    • 创建DIARY文件
      通过使用MATLAB命令行diary来创建当前工作窗口中输入和输出结果文本,可以通过文本编辑器或者使用MATLAB函数open命令打开diary文件查看当前输入的数据和输出结果。使用diary on和diary off命令来启动和关闭记录。当在命令行窗口中输入diary on命令后,那么从该条命令开始,将在diary文件中进行记录,直到输入diary off命令结束输入输出的记录。
    • 使用save命令存储数据文件
      MATLAB使用save命令存储数据文件,可以使用save file.dat variableName –ascii命令将数据文件以ASCII文件存储威为.dat文件。例如:
    >> a = rand(3);
    >> save fileName.dat a -ascii
    >> load fileName.dat
      5.2515250e-001  8.3811845e-001  3.7948102e-001
      2.0264736e-001  1.9639514e-002  8.3179602e-001
      6.7213747e-001  6.8127716e-001  5.0281288e-001
    
    • 使用MATLAB的I/O函数写入数据
      使用MATLAB的I/O函数fopen, fwrite等函数可以将MATLAB环境下的数据存储为其他开发平台所需要的数据文件格式。

    • 创建MEX文件写MATLAB环境数据
      同读入数据一样,可以使用MATLAB应用程序接口(API)函数库MAT函数库,MEX函数库和MX函数库写出MATLAB环境数据。在本节中也提供了一个标准的创建MEX文件写数据的程序代码。

    16.3.2 MAT函数库函数

    使用MATLAB命令行save命令可以将MATLAB工作环境中的数据存储为MAT数据文件格式。在其他开发平台,需要使用MATLAB应用程序接口来读入和写出MAT数据文件中的数据变量。在MEX一节中,已经介绍了MATLAB应用程序接口(API)函数库的MEX函数库和MX函数库相关函数,在读写MAT文件时,同样需要使用到MEX函数库和MX函数库。本节中主要简单介绍MAT函数库相关函数的功能描述,在下一小节中,将通过实例演示如何使用MATLAB应用程序接口(API)进行MAT文件的读写。

    表16.4所示为C语言常用MAT函数库函数

    MAT函数 功能描述
    matOpen 打开MAT文件
    matClose 关闭MAT文件
    matGetDir 从MAT文件中获取变量列表
    matGetVariable 从MAT文件中读入变量
    matPutVariable 向MAT文件中写入变量
    matGetNextVariable 从MAT文件中读入下一个变量
    matDeleteVariable 从MAT文件中删除变量

    16.3.3 Mex文件读写MAT文件

    在了解MAT文件基本概念和MATLAB应用程序接口(API)函数库常用MAT函数库函数后。在本小节,将通过两个实例matCDemo.c文件和matMexLoadDemo分别演示使用MATLAB应用程序接口(API)函数库函数读写MAT文件。编写以下matCDemo.c文件,可以实现写入MATLAB数据到MAT文件中的功能。

    /*  
     *  matCDemo.c
    */
    #include "mex.h"
    #include "mat.h"
    
    void mexFunction(int nlhs, mxArray *plhs[],
                                    int nrhs, const mxArray *prhs[])
    {
        //初始变量定义,包括数组和mxArray数据结构定义
        mxArray *pString, *pArray1, *pArray2;
        double a1[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0};
        double a2[] = {9.0, 4.0,5.4,6.4,3.2,1.5};
        //MATFile文件定义和文件名定义
        char *filename;
        MATFile *file;
        int flag, buflen;
        
        //输入个数检测数据
        if (nrhs != 1)
            mexErrMsgTxt("Error: One intput parameter is required to represent the file name!");
        if (nrhs > 1)
            mexErrMsgTxt("Error: No more than one input parameter.");
        
        //输入参数类型检测,输入必须为字符串类型。
        if ( mxIsChar(prhs[0]) != 1)
            mexErrMsgTxt("Error: Input must be string!");
        if ( mxGetM(prhs[0]) != 1)
            mexErrMsgTxt("Error: Input must be a row vector!");
        //创建字符串和错误检测
        pString = mxCreateString("This is the MAT demo in C lanuage! Enojy it~!");
        if (pString == NULL)
            mexErrMsgTxt("Error: Cannot create string!");
        //创建mxArray参数矩阵初始大小
        pArray1 = mxCreateDoubleMatrix(3,3,mxREAL);
        pArray2 = mxCreateDoubleMatrix(2,3,mxREAL);
        if( (pArray1 == NULL)||(pArray2 ==NULL) )
            mexErrMsgTxt("Error: Cannot create the double matrix!");
        //将定义的数组拷贝给mxArray变量
        memcpy( (void *)(mxGetPr(pArray1)), (void *)a1, sizeof(a1));
        memcpy( (void *)(mxGetPr(pArray2)), (void *)a2, sizeof(a2));
        
        //获取文件名称
        buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
        //申请建立字符串大小的内存空间
        filename = mxCalloc(buflen,sizeof(char));
        flag = mxGetString(prhs[0], filename, buflen);
        if( flag != 0)
            mexWarnMsgTxt("Not enough memory space!");
        
        //创建新的MAT文件
        file = matOpen(filename,"w");
        if ( file = NULL )
            mexWarnMsgTxt("Error: Cannot create the mat file!");
    
        //向MAT文件中写入数据
        matPutVariable(file, "variableString", pString);
        matPutVariable(file, "variableDoubleMatrix1", pArray1);
        matPutVariable(file, "variableDoubleMatrix2", pArray2);
        
        //关闭MAT文件
        matClose(file);
        
        //释放内存空间
        mxDestroyArray(pString);
        mxDestroyArray(pArray1);
        mxDestroyArray(pArray2);
        
        mxFree(filename);
        
    }
    

    使用mex命令编译该文件,在Matlab命令行窗口中调用该函数:

    >> matcDemo('matfile.mat')
    

    通过which命令查看matfile文件是否已经建立:

    >> which matfile.mat
    C:\Program Files\MATLAB\R2006a\work\matfile.mat
    在命令行窗口中使用load命令可以查看matfile.mat数据文件的内容:
    >> load matfile.mat
    >> whos
      Name                        Size                    Bytes  Class
    
      variableDoubleMatrix1       3x3                        72  double array
      variableDoubleMatrix2       2x3                        48  double array
      variableString              1x45                       90  char array
    
    Grand total is 60 elements using 210 bytes
    

    在该实例中,演示了使用MEX文件写MAT数据文件,基本的编写程序步骤包括:首先定义mxArray数据结构变量,进行输入输出参数个数和类型的检测,使用mxCreate前缀函数创建mxArray数据结构变量的初始值,将定义的数组拷贝给mxArray变量,然后matOpen函数打开MAT文件,使用matPutVariable函数向MAT文件写入数据,matClose函数关闭MAT文件,释放定义存储mxArray数据变量的内存空间。以下matMexLoadDemo.c程序则实现读入MAT文件数据的功能,编写程序的步骤和写入MAT文件数据刚好相反,程序代码如下:

    /*
     *  matMexLoadDemo.c
     */
    
    #include <string.h>
    #include "mex.h"
    #include "mat.h"
    const int MAXSIZE = 100;
    void mexFunction(int nlhs, mxArray *plhs[],
                                    int nrhs, const mxArray *prhs[])
    {
        //MATFile文件定义和相关变量定义
        MATFile *file;
        char *fileName;
        char *variableName[MAXSIZE];
        int counter,buf_len,index;
        mxArray *variableValue = NULL;
        // 给函数文件名分配内存空间并获取文件名
        buf_len = mxGetN(prhs[0]) + 1;
        fileName = (char *) mxCalloc(buf_len, sizeof (char));
        mxGetString(prhs[0], fileName, buf_len);
        //读取MAT文件函数名
        counter = 0;
        for( index = 1; index < nrhs; index ++ )
        {
            int variableLength = mxGetN(prhs[index]) + 1;
            variableName[ counter ] = (char *)mxCalloc(variableLength, sizeof (char));
            mxGetString(prhs[index], variableName[counter],variableLength);
            counter ++;
        }
        // 打开MAT文件
        file = matOpen(fileName, "r");
        if ( file < (MATFile *) 3 )
        {
            mexErrMsgTxt("Error: Cannot open the mat file!");
        }
        //读取MAT文件变量
        if (counter > 0)
        {
            for ( index = 0; index < counter; index ++)
            {
                variableValue = matGetVariable(file, variableName[index]);
                mexPutVariable("Caller",variableName[index], variableValue);
                
                mxFree(variableName[index]);
            }
        }
        else
        {
            const char *var_name;
            while((variableValue=matGetNextVariable(file, &var_name))!=NULL) 
            {
                mexPutVariable("caller", var_name, variableValue);
            }
        }
        //关闭MAT文件
        matClose(file);
        mxFree(fileName);
    }
    

    使用mex命令编译matMexLoadDemo.c文件,在MATLAB命令行窗口中输入:

    >> mex matMexLoadDemo.c
    

    通过调用matMexLoadDemo编译文件,就可以读入mat数据文件的数据:

    >> matMexLoadDemo('matfile.mat')
    >> whos
      Name                        Size                    Bytes  Class
    
      variableDoubleMatrix1       3x3                        72  double array
      variableDoubleMatrix2       2x3                        48  double array
      variableString              1x45                       90  char array
    
    Grand total is 60 elements using 210 bytes
    

    以上通过两个实例分别演示了使用MATLAB应用程序接口(API)函数库函数,编写MEX文件以实现MAT数据文件的写入和读出。16.4节将介绍MATLAB引擎技术实现在其他语言环境下后台调用MATLAB命令的功能,但这种调用方法要求工作环境必须安装MATLAB应用程序,否则无法启动MATLAB引擎。

    作者:德特数据
    联系方式:156204968@qq.com

    相关文章

      网友评论

          本文标题:MATLAB编程与应用系列-第16章 外部接口技术(3)

          本文链接:https://www.haomeiwen.com/subject/ndgztqtx.html