readDMAT.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "readDMAT.h"
  2. #include "verbose.h"
  3. #include <cstdio>
  4. #include <iostream>
  5. #include <cassert>
  6. // Static helper method reads the first to elements in the given file
  7. // Inputs:
  8. // fp file pointer of .dmat file that was just opened
  9. // Outputs:
  10. // num_rows number of rows
  11. // num_cols number of columns
  12. // Returns
  13. // 0 success
  14. // 1 did not find header
  15. // 2 bad num_cols
  16. // 3 bad num_rows
  17. static inline int readDMAT_read_header(FILE * fp, int & num_rows, int & num_cols)
  18. {
  19. // first line contains number of rows and number of columns
  20. int res = fscanf(fp,"%d %d\n",&num_cols,&num_rows);
  21. if(res != 2)
  22. {
  23. return 1;
  24. }
  25. // check that number of columns and rows are sane
  26. if(num_cols < 0)
  27. {
  28. fprintf(stderr,"IOError: readDMAT() number of columns %d < 0\n",num_cols);
  29. return 2;
  30. }
  31. if(num_rows < 0)
  32. {
  33. fprintf(stderr,"IOError: readDMAT() number of rows %d < 0\n",num_rows);
  34. return 3;
  35. }
  36. return 0;
  37. }
  38. #ifndef IGL_NO_EIGEN
  39. template <typename DerivedW>
  40. IGL_INLINE bool igl::readDMAT(const std::string file_name,
  41. Eigen::PlainObjectBase<DerivedW> & W)
  42. {
  43. FILE * fp = fopen(file_name.c_str(),"r");
  44. if(fp == NULL)
  45. {
  46. fprintf(stderr,"IOError: readDMAT() could not open %s...\n",file_name.c_str());
  47. return false;
  48. }
  49. int num_rows,num_cols;
  50. int head_success = readDMAT_read_header(fp,num_rows,num_cols);
  51. if(head_success != 0)
  52. {
  53. if(head_success == 1)
  54. {
  55. fprintf(stderr,
  56. "IOError: readDMAT() first row should be [num cols] [num rows]...\n");
  57. }
  58. fclose(fp);
  59. return false;
  60. }
  61. // Resize output to fit matrix
  62. W.resize(num_rows,num_cols);
  63. // Loop over columns slowly
  64. for(int j = 0;j < num_cols;j++)
  65. {
  66. // loop over rows (down columns) quickly
  67. for(int i = 0;i < num_rows;i++)
  68. {
  69. double d;
  70. if(fscanf(fp," %lg",&d) != 1)
  71. {
  72. fclose(fp);
  73. fprintf(
  74. stderr,
  75. "IOError: readDMAT() bad format after reading %d entries\n",
  76. j*num_rows + i);
  77. return false;
  78. }
  79. W(i,j) = d;
  80. }
  81. }
  82. // Try to read header for binary part
  83. head_success = readDMAT_read_header(fp,num_rows,num_cols);
  84. if(head_success == 0)
  85. {
  86. assert(W.size() == 0);
  87. // Resize for output
  88. W.resize(num_rows,num_cols);
  89. double * Wraw = new double[num_rows*num_cols];
  90. fread(Wraw, sizeof(double), num_cols*num_rows, fp);
  91. // Loop over columns slowly
  92. for(int j = 0;j < num_cols;j++)
  93. {
  94. // loop over rows (down columns) quickly
  95. for(int i = 0;i < num_rows;i++)
  96. {
  97. W(i,j) = Wraw[j*num_rows+i];
  98. }
  99. }
  100. }
  101. fclose(fp);
  102. return true;
  103. }
  104. #endif
  105. template <typename Scalar>
  106. IGL_INLINE bool igl::readDMAT(
  107. const std::string file_name,
  108. std::vector<std::vector<Scalar> > & W)
  109. {
  110. FILE * fp = fopen(file_name.c_str(),"r");
  111. if(fp == NULL)
  112. {
  113. fprintf(stderr,"IOError: readDMAT() could not open %s...\n",file_name.c_str());
  114. return false;
  115. }
  116. int num_rows,num_cols;
  117. bool head_success = readDMAT_read_header(fp,num_rows,num_cols);
  118. if(head_success != 0)
  119. {
  120. if(head_success == 1)
  121. {
  122. fprintf(stderr,
  123. "IOError: readDMAT() first row should be [num cols] [num rows]...\n");
  124. }
  125. fclose(fp);
  126. return false;
  127. }
  128. // Resize for output
  129. W.resize(num_rows,typename std::vector<Scalar>(num_cols));
  130. // Loop over columns slowly
  131. for(int j = 0;j < num_cols;j++)
  132. {
  133. // loop over rows (down columns) quickly
  134. for(int i = 0;i < num_rows;i++)
  135. {
  136. double d;
  137. if(fscanf(fp," %lg",&d) != 1)
  138. {
  139. fclose(fp);
  140. fprintf(
  141. stderr,
  142. "IOError: readDMAT() bad format after reading %d entries\n",
  143. j*num_rows + i);
  144. return false;
  145. }
  146. W[i][j] = (Scalar)d;
  147. }
  148. }
  149. // Try to read header for binary part
  150. head_success = readDMAT_read_header(fp,num_rows,num_cols);
  151. if(head_success == 0)
  152. {
  153. assert(W.size() == 0);
  154. // Resize for output
  155. W.resize(num_rows,typename std::vector<Scalar>(num_cols));
  156. double * Wraw = new double[num_rows*num_cols];
  157. fread(Wraw, sizeof(double), num_cols*num_rows, fp);
  158. // Loop over columns slowly
  159. for(int j = 0;j < num_cols;j++)
  160. {
  161. // loop over rows (down columns) quickly
  162. for(int i = 0;i < num_rows;i++)
  163. {
  164. W[i][j] = Wraw[j*num_rows+i];
  165. }
  166. }
  167. }
  168. fclose(fp);
  169. return true;
  170. }
  171. #ifndef IGL_HEADER_ONLY
  172. // Explicit template specialization
  173. template bool igl::readDMAT<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  174. template bool igl::readDMAT<double>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&);
  175. template bool igl::readDMAT<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  176. #endif