Matlab external Interface : Mat-File generation program - sunhaohui _Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2188 | 回复: 0   主题: Matlab external Interface : Mat-File generation program - sunhaohui         下一篇 
    本主题由 koei123 于 2015-6-2 8:56:15 移动
薯片
注册用户
等级:中士
经验:237
发帖:75
精华:0
注册:2012-2-10
状态:离线
发送短消息息给薯片 加好友    发送短消息息给薯片 发消息
发表于: IP:您无权察看 2015-3-31 17:32:51 | [全部帖] [楼主帖] 楼主

Matlab external Interface这玩意的中文不知道是什么,感觉是Matlab插件一类的东西。我用c++写了一个函数可以生成一个巨大的矩阵。但是这个矩阵的svd分解我可不想再用c++写了。于是我想把这个大矩阵导入matlab的*.mat文件中,让matlab的svd命令来计算这个矩阵的svd分解。Matlab external Interface允许我写一个可以生成matlab Mat文件的c++程序。当然要包含matlab的头文件 "mat.h",同时还要与matlab的*.so(linux) *.lib(win32)等库文件链接。可执行文件的编译和链接功能可以有mex命令自动实现,不用自己写Makefile。我自己尝试写一个makefile但是没有编译成功。先贴出我的代码在细讲吧:

1 #include <stdio.h>
2 #include <string.h> /* For strcmp() */
3 #include <stdlib.h> /* For EXIT_FAILURE, EXIT_SUCCESS */
4 #include <vector> /* For STL */
5 #include <iostream>
6 #include <fstream>
7 #include "mat.h"
8
9 using namespace std;
10
11 #define BUFSIZE 256
12
13 int main() {
      14 MATFile *pmat;
      15 mxArray *pa1;// *pa2, *pa3;
      16 fstream infile("outputMat", ios::in);
      17 if( ! infile.is_open() )
      18 {
            19 cout << "no file" << endl;
            20 return -1;
      21 }
      22 std::vector<int> myInts;
      23 myInts.push_back(1);
      24 myInts.push_back(2);
      25 printf("Accessing a STL vector: %d\n", myInts[1]);
      26
27 //double data[9] = { 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 };
      28 double *data = NULL;
      29 const char *file = "mattest.mat";
      30 char str[BUFSIZE];
      31 int status;
      32 int width,height;
      33 infile >> height;
      34 infile >> width;
      35 cout << height;
      36 data = (double*)malloc(sizeof(double)*width*height);
      37 if( !data )
      38 {
            39 cout << "Out of Memory !" << endl;
            40 return -1;
      41 }
      42 for(unsigned i = 0; i < width * height; i++)
      43 {
            44 float tmp;
            45 infile >> tmp;
            46 data[i] = (double)tmp;
            47 //cout << data[i] << " ";
      48 }
      49 infile.close();
      50
      51 printf("Creating file %s...\n\n", file);
      52 pmat = matOpen(file, "w");
      53 if (pmat == NULL) {
            54 printf("Error creating file %s\n", file);
            55 printf("(Do you have write permission in this directory?)\n");
            56 return(EXIT_FAILURE);
      57 }
      58
      59 pa1 = mxCreateDoubleMatrix(width,height,mxREAL);
      60 if (pa1 == NULL) {
            61 printf("%s : Out of memory on line %d\n", __FILE__, __LINE__);
            62 printf("Unable to create mxArray.\n");
            63 return(EXIT_FAILURE);
      64 }
      65
      66 status = matPutVariable(pmat, "GlobalDouble", pa1);
      67 if (status != 0) {
            68 printf("%s : Error using matPutVariable on line %d\n", __FILE__, __LINE__);
            69 return(EXIT_FAILURE);
      70 }
      71
      72
      73
      74 /*
      75 * Ooops! we need to copy data before writing the array. (Well,
      76 * ok, this was really intentional.) This demonstrates that
      77 * matPutVariable will overwrite an existing array in a MAT-file.
      78 */
      79 memcpy((void *)(mxGetPr(pa1)), (void *)data, sizeof(double)*width*height);
      80 status = matPutVariable(pmat, "GlobalDouble", pa1);
      81 if (status != 0) {
            82 printf("%s : Error using matPutVariable on line %d\n", __FILE__, __LINE__);
            83 return(EXIT_FAILURE);
      84 }
      85
      86 /* clean up */
      87 mxDestroyArray(pa1);
      88
      89 if (matClose(pmat) != 0) {
            90 printf("Error closing file %s\n",file);
            91 return(EXIT_FAILURE);
      92 }
      93
      94 /*
      95 * Re-open file and verify its contents with matGetVariable
      96 */
      97 pmat = matOpen(file, "r");
      98 if (pmat == NULL) {
            99 printf("Error reopening file %s\n", file);
            100 return(EXIT_FAILURE);
      101 }
      102
      103 /*
      104 * Read in each array we just wrote
      105 */
      106 pa1 = matGetVariable(pmat, "GlobalDouble");
      107 if (pa1 == NULL) {
            108 printf("Error reading existing matrix LocalDouble\n");
            109 return(EXIT_FAILURE);
      110 }
      111 if (mxGetNumberOfDimensions(pa1) != 2) {
            112 printf("Error saving matrix: result does not have two dimensions\n");
            113 return(EXIT_FAILURE);
      114 }
      115
      116
      117
      118 /* clean up before exit */
      119 mxDestroyArray(pa1);
      120
      121 if (matClose(pmat) != 0) {
            122 printf("Error closing file %s\n",file);
            123 return(EXIT_FAILURE);
      124 }
      125 printf("Done\n");
      126 return(EXIT_SUCCESS);
127 }


代码的第33~48行是读取一个写有矩阵数据的文件,该文件的前两个int是这个矩阵的行和列。之后就是 行x列 个float型的数据。都读入一个double型的数组中。59和66行的代码就是matlab提供的API。使用这两行代码可以生成一个matlab矩阵。并给这个矩阵起个变量名。最后把之前存在double数组里的数据拷贝到这个matlab矩阵中就可以了。在编译这个代码的时候,要使用mex命令。
打开matlab,输入如下命令

mex('-v', '-f', ['matlabroot' '/bin/matopts.sh'], 'matcreat.cpp')


其中matcreat.cpp就是源文件的名称。matlabroot是matlab安装的路径。生成的可执行文件不一定能执行。我的系统是fedora x64,系统提示我缺少libmat.so。这是因为没有设置好环境变量。在bash中输入如下代码就可以把环境变量设置好,每次启动终端的时候都要如此设置!如果觉得麻烦就写在~/.bashrc中,但是这样在我的fedora15电脑上出现很多莫名其妙的状况。所以不推荐。输入的命令是:

$LD_LIBRARY_PATH=/home/local/MATLAB/R2011b/bin/glnxa64:/home/local/MATLAB/R2011b/sys/os/glnxa64:$LD_LIBRARY_PATH
$export LD_LIBRARY_PATH


这样运行之后可以生成mattest.mat文件,能正常导入到matlab中。

--转自 北京联动北方科技有限公司

该贴由koei123转至本版2015-6-2 8:56:15



赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论