readDMAT.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. fclose(fp);
  83. return true;
  84. }
  85. #endif
  86. template <typename Scalar>
  87. IGL_INLINE bool igl::readDMAT(
  88. const std::string file_name,
  89. std::vector<std::vector<Scalar> > & W)
  90. {
  91. FILE * fp = fopen(file_name.c_str(),"r");
  92. if(fp == NULL)
  93. {
  94. fprintf(stderr,"IOError: readDMAT() could not open %s...\n",file_name.c_str());
  95. return false;
  96. }
  97. int num_rows,num_cols;
  98. bool head_success = readDMAT_read_header(fp,num_rows,num_cols);
  99. if(head_success != 0)
  100. {
  101. if(head_success == 1)
  102. {
  103. fprintf(stderr,
  104. "IOError: readDMAT() first row should be [num cols] [num rows]...\n");
  105. }
  106. fclose(fp);
  107. return false;
  108. }
  109. // Resize for output
  110. W.resize(num_rows,typename std::vector<Scalar>(num_cols));
  111. // Loop over columns slowly
  112. for(int j = 0;j < num_cols;j++)
  113. {
  114. // loop over rows (down columns) quickly
  115. for(int i = 0;i < num_rows;i++)
  116. {
  117. double d;
  118. if(fscanf(fp," %lg",&d) != 1)
  119. {
  120. fclose(fp);
  121. fprintf(
  122. stderr,
  123. "IOError: readDMAT() bad format after reading %d entries\n",
  124. j*num_rows + i);
  125. return false;
  126. }
  127. W[i][j] = (Scalar)d;
  128. }
  129. }
  130. // Try to read header for binary part
  131. head_success = readDMAT_read_header(fp,num_rows,num_cols);
  132. if(head_success == 0)
  133. {
  134. assert(W.size() == 0);
  135. // Resize for output
  136. W.resize(num_rows,typename std::vector<Scalar>(num_cols));
  137. double * Wraw = new double[num_rows*num_cols];
  138. fread(Wraw, 8, num_cols*num_rows, fp);
  139. // Loop over columns slowly
  140. for(int j = 0;j < num_cols;j++)
  141. {
  142. // loop over rows (down columns) quickly
  143. for(int i = 0;i < num_rows;i++)
  144. {
  145. W[i][j] = Wraw[j*num_rows+i];
  146. }
  147. }
  148. }
  149. fclose(fp);
  150. return true;
  151. }
  152. #ifndef IGL_HEADER_ONLY
  153. // Explicit template specialization
  154. 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> >&);
  155. 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> > > >&);
  156. #endif