MatFileIO.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /**
  2. * @file MatFileIO.cpp
  3. * @brief Read and write mat-files
  4. * @author Paul Bodesheim
  5. * @date 06-01-2012 (dd-mm-yyyy)
  6. */
  7. #include "MatFileIO.h"
  8. #ifdef NICE_USELIB_MATIO
  9. namespace NICE {
  10. //------------------------------------------------------
  11. // several constructors and destructors
  12. //------------------------------------------------------
  13. // Default constructor
  14. MatFileIO::MatFileIO() { mat = 0; }
  15. // Recommended constructor
  16. MatFileIO::MatFileIO(std::string _filename, const mat_acc mode) {
  17. mat = Mat_Open(_filename.c_str(),mode);
  18. if (mat == NULL && mode == MAT_ACC_RDONLY) {
  19. fthrow(Exception, "MatFileIO::MatFileIO(const char * _filename, int mode): mat-file does not exist");
  20. }
  21. }
  22. // Default destructor
  23. MatFileIO::~MatFileIO() {
  24. Mat_Close(mat);
  25. }
  26. //------------------------------------------------------
  27. // count number of stored variables
  28. //------------------------------------------------------
  29. int MatFileIO::getNumberOfVariables() {
  30. Mat_Rewind(mat); // get back to first variable
  31. int count = 0;
  32. matvar_t * matvar = Mat_VarReadNextInfo(mat);
  33. while (matvar != NULL) {
  34. count++;
  35. matvar = Mat_VarReadNextInfo(mat);
  36. }
  37. Mat_VarFree(matvar);
  38. return count;
  39. }
  40. //------------------------------------------------------
  41. // several methods for reading data
  42. //------------------------------------------------------
  43. matvar_t * MatFileIO::getVariableViaName(std::string _name) {
  44. return Mat_VarRead(mat,_name.c_str());
  45. }
  46. void MatFileIO::getSparseVariableViaName(sparse_t & sparseVariable, std::string _name) {
  47. matvar_t * matvar = getVariableViaName(_name);
  48. if (matvar == NULL) {
  49. fthrow(Exception, "MatFileIO::getSparseVariableViaName(sparse_t & sparseVariable, std::string _name): variable with specified name does not exist");
  50. return;
  51. }
  52. if (matvar->class_type != MAT_C_SPARSE) {
  53. Mat_VarFree(matvar);
  54. fthrow(Exception, "MatFileIO::getSparseVariableViaName(sparse_t & sparseVariable, std::string _name): format of variable is not sparse");
  55. return;
  56. }
  57. sparse_t * sparse_ptr = (sparse_t*) matvar->data;
  58. sparse_ptr->data = (double*) sparse_ptr->data;
  59. sparseVariable = *sparse_ptr;
  60. matvar->data = NULL;
  61. Mat_VarFree(matvar);
  62. free(sparse_ptr);
  63. }
  64. void MatFileIO::getFeatureMatrixViaName(std::vector<std::vector<double> > & features, std::string _name, const feature_matrix_order order) {
  65. matvar_t * matvar = getVariableViaName(_name);
  66. if (matvar == NULL) {
  67. fthrow(Exception, "MatFileIO::getFeatureMatrixViaName(char * _name, feature_matrix_order order): variable with specified name does not exist");
  68. return;
  69. }
  70. if (matvar->rank != 2) {
  71. Mat_VarFree(matvar);
  72. fthrow(Exception, "MatFileIO::getFeatureMatrixViaName(char * _name, feature_matrix_order order): dimension of variable != 2");
  73. return;
  74. }
  75. features.clear();
  76. std::vector<double> currentFeature;
  77. currentFeature.clear();
  78. // case 1: feature vectors in the rows of matrix
  79. if (order == NxD) {
  80. // depending on the class type of data elements, we have to treat several cases and cast the data elements correctly
  81. switch (matvar->data_type) {
  82. case MAT_T_DOUBLE:
  83. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  84. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  85. currentFeature.push_back( ((double*)matvar->data)[matvar->dims[0]*j+i] );
  86. }
  87. features.push_back(currentFeature);
  88. currentFeature.clear();
  89. }
  90. break;
  91. case MAT_T_SINGLE:
  92. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  93. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  94. currentFeature.push_back( ((float*)matvar->data)[matvar->dims[0]*j+i] );
  95. }
  96. features.push_back(currentFeature);
  97. currentFeature.clear();
  98. }
  99. break;
  100. #ifdef HAVE_MAT_INT64_T
  101. case MAT_T_INT64:
  102. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  103. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  104. currentFeature.push_back( ((signed long long*)matvar->data)[matvar->dims[0]*j+i] );
  105. }
  106. features.push_back(currentFeature);
  107. currentFeature.clear();
  108. }
  109. break;
  110. #endif
  111. #ifdef HAVE_MAT_UINT64_T
  112. case MAT_T_UINT64:
  113. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  114. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  115. currentFeature.push_back( ((unsigned long long*)matvar->data)[matvar->dims[0]*j+i] );
  116. }
  117. features.push_back(currentFeature);
  118. currentFeature.clear();
  119. }
  120. break;
  121. #endif
  122. case MAT_T_INT32:
  123. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  124. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  125. currentFeature.push_back( ((signed long*)matvar->data)[matvar->dims[0]*j+i] );
  126. }
  127. features.push_back(currentFeature);
  128. currentFeature.clear();
  129. }
  130. break;
  131. case MAT_T_UINT32:
  132. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  133. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  134. currentFeature.push_back( ((unsigned long*)matvar->data)[matvar->dims[0]*j+i] );
  135. }
  136. features.push_back(currentFeature);
  137. currentFeature.clear();
  138. }
  139. break;
  140. case MAT_T_INT16:
  141. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  142. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  143. currentFeature.push_back( ((signed short*)matvar->data)[matvar->dims[0]*j+i] );
  144. }
  145. features.push_back(currentFeature);
  146. currentFeature.clear();
  147. }
  148. break;
  149. case MAT_T_UINT16:
  150. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  151. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  152. currentFeature.push_back( ((unsigned short*)matvar->data)[matvar->dims[0]*j+i] );
  153. }
  154. features.push_back(currentFeature);
  155. currentFeature.clear();
  156. }
  157. break;
  158. case MAT_T_INT8:
  159. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  160. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  161. currentFeature.push_back( ((signed char*)matvar->data)[matvar->dims[0]*j+i] );
  162. }
  163. features.push_back(currentFeature);
  164. currentFeature.clear();
  165. }
  166. break;
  167. case MAT_T_UINT8:
  168. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  169. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  170. currentFeature.push_back( ((unsigned char*)matvar->data)[matvar->dims[0]*j+i] );
  171. }
  172. features.push_back(currentFeature);
  173. currentFeature.clear();
  174. }
  175. break;
  176. }
  177. // case 2: feature vectors in the columns of matrix
  178. } else if (order == DxN) {
  179. // depending on the class type of data elements, we have to treat several cases and cast the data elements correctly
  180. switch (matvar->data_type) {
  181. case MAT_T_DOUBLE:
  182. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  183. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  184. currentFeature.push_back( ((double*)matvar->data)[matvar->dims[0]*j+i] );
  185. }
  186. features.push_back(currentFeature);
  187. currentFeature.clear();
  188. }
  189. break;
  190. case MAT_T_SINGLE:
  191. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  192. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  193. currentFeature.push_back( ((float*)matvar->data)[matvar->dims[0]*j+i] );
  194. }
  195. features.push_back(currentFeature);
  196. currentFeature.clear();
  197. }
  198. break;
  199. #ifdef HAVE_MAT_INT64_T
  200. case MAT_T_INT64:
  201. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  202. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  203. currentFeature.push_back( ((signed long long*)matvar->data)[matvar->dims[0]*j+i] );
  204. }
  205. features.push_back(currentFeature);
  206. currentFeature.clear();
  207. }
  208. break;
  209. #endif
  210. #ifdef HAVE_MAT_UINT64_T
  211. case MAT_T_UINT64:
  212. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  213. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  214. currentFeature.push_back( ((unsigned long long*)matvar->data)[matvar->dims[0]*j+i] );
  215. }
  216. features.push_back(currentFeature);
  217. currentFeature.clear();
  218. }
  219. break;
  220. #endif
  221. case MAT_T_INT32:
  222. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  223. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  224. currentFeature.push_back( ((signed long*)matvar->data)[matvar->dims[0]*j+i] );
  225. }
  226. features.push_back(currentFeature);
  227. currentFeature.clear();
  228. }
  229. break;
  230. case MAT_T_UINT32:
  231. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  232. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  233. currentFeature.push_back( ((unsigned long*)matvar->data)[matvar->dims[0]*j+i] );
  234. }
  235. features.push_back(currentFeature);
  236. currentFeature.clear();
  237. }
  238. break;
  239. case MAT_T_INT16:
  240. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  241. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  242. currentFeature.push_back( ((signed short*)matvar->data)[matvar->dims[0]*j+i] );
  243. }
  244. features.push_back(currentFeature);
  245. currentFeature.clear();
  246. }
  247. break;
  248. case MAT_T_UINT16:
  249. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  250. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  251. currentFeature.push_back( ((unsigned short*)matvar->data)[matvar->dims[0]*j+i] );
  252. }
  253. features.push_back(currentFeature);
  254. currentFeature.clear();
  255. }
  256. break;
  257. case MAT_T_INT8:
  258. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  259. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  260. currentFeature.push_back( ((signed char*)matvar->data)[matvar->dims[0]*j+i] );
  261. }
  262. features.push_back(currentFeature);
  263. currentFeature.clear();
  264. }
  265. break;
  266. case MAT_T_UINT8:
  267. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  268. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  269. currentFeature.push_back( ((unsigned char*)matvar->data)[matvar->dims[0]*j+i] );
  270. }
  271. features.push_back(currentFeature);
  272. currentFeature.clear();
  273. }
  274. break;
  275. }
  276. } else {
  277. Mat_VarFree(matvar);
  278. fthrow(Exception, "MatFileIO::getFeatureMatrixViaName(char * _name, feature_matrix_order order): wrong feature_matrix_order specified");
  279. return;
  280. }
  281. Mat_VarFree(matvar);
  282. }
  283. void MatFileIO::getVectorViaName(NICE::Vector & vec, std::string _name) {
  284. matvar_t * matvar = getVariableViaName(_name);
  285. if (matvar == NULL) {
  286. fthrow(Exception, "MatFileIO::getVectorViaName(NICE::Vector & vec, std::string _name): variable with specified name does not exist");
  287. return;
  288. }
  289. // it can happen that a vector is treated as (N x 1) or (1 x N) matrix with two dimensions
  290. if (matvar->rank > 2 || ( (matvar->rank == 2) && (matvar->dims[0] != 1) && (matvar->dims[1] != 1) ) ) {
  291. Mat_VarFree(matvar);
  292. fthrow(Exception, "MatFileIO::getVectorViaName(NICE::Vector & vec, std::string _name): dimension of variable > 1");
  293. return;
  294. }
  295. std::vector<double> v;
  296. v.clear();
  297. // vector is stored as a variable with one dimensional
  298. if (matvar->rank == 1) {
  299. switch( matvar->data_type ) {
  300. case MAT_T_DOUBLE:
  301. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  302. v.push_back( ((double*)matvar->data)[i] );
  303. }
  304. break;
  305. case MAT_T_SINGLE:
  306. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  307. v.push_back( ((float*)matvar->data)[i] );
  308. }
  309. break;
  310. #ifdef HAVE_MAT_INT64_T
  311. case MAT_T_INT64:
  312. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  313. v.push_back( ((signed long long*)matvar->data)[i] );
  314. }
  315. break;
  316. #endif
  317. #ifdef HAVE_MAT_UINT64_T
  318. case MAT_T_UINT64:
  319. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  320. v.push_back( ((unsigned long long*)matvar->data)[i] );
  321. }
  322. break;
  323. #endif
  324. case MAT_T_INT32:
  325. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  326. v.push_back( ((signed long*)matvar->data)[i] );
  327. }
  328. break;
  329. case MAT_T_UINT32:
  330. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  331. v.push_back( ((unsigned long*)matvar->data)[i] );
  332. }
  333. break;
  334. case MAT_T_INT16:
  335. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  336. v.push_back( ((signed short*)matvar->data)[i] );
  337. }
  338. break;
  339. case MAT_T_UINT16:
  340. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  341. v.push_back( ((unsigned short*)matvar->data)[i] );
  342. }
  343. break;
  344. case MAT_T_INT8:
  345. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  346. v.push_back( ((signed char*)matvar->data)[i] );
  347. }
  348. break;
  349. case MAT_T_UINT8:
  350. for ( int i = 0; i < matvar->nbytes/matvar->data_size; i++ ) {
  351. v.push_back( ((unsigned char*)matvar->data)[i] );
  352. }
  353. break;
  354. }
  355. // it can happen that a vector is treated as (N x 1) or (1 x N) matrix with two dimensions, here we handle this case
  356. } else {
  357. switch( matvar->data_type ) {
  358. case MAT_T_DOUBLE:
  359. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  360. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  361. v.push_back( ((double*)matvar->data)[matvar->dims[0]*j+i] );
  362. }
  363. }
  364. break;
  365. case MAT_T_SINGLE:
  366. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  367. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  368. v.push_back( ((float*)matvar->data)[matvar->dims[0]*j+i] );
  369. }
  370. }
  371. break;
  372. #ifdef HAVE_MAT_INT64_T
  373. case MAT_T_INT64:
  374. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  375. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  376. v.push_back( ((signed long long*)matvar->data)[matvar->dims[0]*j+i] );
  377. }
  378. }
  379. break;
  380. #endif
  381. #ifdef HAVE_MAT_UINT64_T
  382. case MAT_T_UINT64:
  383. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  384. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  385. v.push_back( ((unsigned long long*)matvar->data)[matvar->dims[0]*j+i] );
  386. }
  387. }
  388. break;
  389. #endif
  390. case MAT_T_INT32:
  391. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  392. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  393. v.push_back( ((signed long*)matvar->data)[matvar->dims[0]*j+i] );
  394. }
  395. }
  396. break;
  397. case MAT_T_UINT32:
  398. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  399. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  400. v.push_back( ((unsigned long*)matvar->data)[matvar->dims[0]*j+i] );
  401. }
  402. }
  403. break;
  404. case MAT_T_INT16:
  405. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  406. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  407. v.push_back( ((signed short*)matvar->data)[matvar->dims[0]*j+i] );
  408. }
  409. }
  410. break;
  411. case MAT_T_UINT16:
  412. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  413. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  414. v.push_back( ((unsigned short*)matvar->data)[matvar->dims[0]*j+i] );
  415. }
  416. }
  417. break;
  418. case MAT_T_INT8:
  419. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  420. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  421. v.push_back( ((signed char*)matvar->data)[matvar->dims[0]*j+i] );
  422. }
  423. }
  424. break;
  425. case MAT_T_UINT8:
  426. for ( int i = 0; i < matvar->dims[0]; i++ ) {
  427. for ( int j = 0; j < matvar->dims[1]; j++ ) {
  428. v.push_back( ((unsigned char*)matvar->data)[matvar->dims[0]*j+i] );
  429. }
  430. }
  431. break;
  432. }
  433. }
  434. vec = NICE::Vector(v);
  435. Mat_VarFree(matvar);
  436. }
  437. }
  438. #endif