Matlab external Interface : Mat-File generation program

來源:互聯網
上載者:User

  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但是沒有編譯成功。先貼出My Code在細講吧:

  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中。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.