cat.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "cat.h"
  2. // Sparse matrices need to be handled carefully. Because C++ does not
  3. // Template:
  4. // Scalar sparse matrix scalar type, e.g. double
  5. template <typename Scalar>
  6. IGL_INLINE void igl::cat(
  7. const int dim,
  8. const Eigen::SparseMatrix<Scalar> & A,
  9. const Eigen::SparseMatrix<Scalar> & B,
  10. Eigen::SparseMatrix<Scalar> & C)
  11. {
  12. assert(dim == 1 || dim == 2);
  13. using namespace Eigen;
  14. // Special case if B or A is empty
  15. if(A.size() == 0)
  16. {
  17. C = B;
  18. return;
  19. }
  20. if(B.size() == 0)
  21. {
  22. C = A;
  23. return;
  24. }
  25. DynamicSparseMatrix<Scalar, RowMajor> dyn_C;
  26. if(dim == 1)
  27. {
  28. assert(A.cols() == B.cols());
  29. dyn_C.resize(A.rows()+B.rows(),A.cols());
  30. }else if(dim == 2)
  31. {
  32. assert(A.rows() == B.rows());
  33. dyn_C.resize(A.rows(),A.cols()+B.cols());
  34. }else
  35. {
  36. fprintf(stderr,"cat.h: Error: Unsupported dimension %d\n",dim);
  37. }
  38. dyn_C.reserve(A.nonZeros()+B.nonZeros());
  39. // Iterate over outside of A
  40. for(int k=0; k<A.outerSize(); ++k)
  41. {
  42. // Iterate over inside
  43. for(typename SparseMatrix<Scalar>::InnerIterator it (A,k); it; ++it)
  44. {
  45. dyn_C.coeffRef(it.row(),it.col()) += it.value();
  46. }
  47. }
  48. // Iterate over outside of B
  49. for(int k=0; k<B.outerSize(); ++k)
  50. {
  51. // Iterate over inside
  52. for(typename SparseMatrix<Scalar>::InnerIterator it (B,k); it; ++it)
  53. {
  54. int r = (dim == 1 ? A.rows()+it.row() : it.row());
  55. int c = (dim == 2 ? A.cols()+it.col() : it.col());
  56. dyn_C.coeffRef(r,c) += it.value();
  57. }
  58. }
  59. C = SparseMatrix<Scalar>(dyn_C);
  60. }
  61. template <typename Derived, class MatC>
  62. IGL_INLINE void igl::cat(
  63. const int dim,
  64. const Eigen::MatrixBase<Derived> & A,
  65. const Eigen::MatrixBase<Derived> & B,
  66. MatC & C)
  67. {
  68. assert(dim == 1 || dim == 2);
  69. // Special case if B or A is empty
  70. if(A.size() == 0)
  71. {
  72. C = B;
  73. return;
  74. }
  75. if(B.size() == 0)
  76. {
  77. C = A;
  78. return;
  79. }
  80. if(dim == 1)
  81. {
  82. assert(A.cols() == B.cols());
  83. C.resize(A.rows()+B.rows(),A.cols());
  84. C << A,B;
  85. }else if(dim == 2)
  86. {
  87. assert(A.rows() == B.rows());
  88. C.resize(A.rows(),A.cols()+B.cols());
  89. C << A,B;
  90. }else
  91. {
  92. fprintf(stderr,"cat.h: Error: Unsupported dimension %d\n",dim);
  93. }
  94. }
  95. template <class Mat>
  96. IGL_INLINE Mat igl::cat(const int dim, const Mat & A, const Mat & B)
  97. {
  98. assert(dim == 1 || dim == 2);
  99. Mat C;
  100. igl::cat(dim,A,B,C);
  101. return C;
  102. }
  103. template <class Mat>
  104. IGL_INLINE void cat(const std::vector<std::vector< Mat > > & A, Mat & C)
  105. {
  106. using namespace igl;
  107. using namespace std;
  108. // Start with empty matrix
  109. C.resize(0,0);
  110. for(typename vector<vector< Mat > >::const_iterator rit = A.begin(); rit != A.end(); rit++)
  111. {
  112. // Concatenate each row horizontally
  113. // Start with empty matrix
  114. Mat row(0,0);
  115. for(typename vector<vector< Mat > >::iterator cit = A.begin(); rit != A.end(); rit++)
  116. {
  117. row = cat(2,row,*cit);
  118. }
  119. // Concatenate rows vertically
  120. C = cat(1,C,row);
  121. }
  122. }
  123. #ifndef IGL_HEADER_ONLY
  124. // Explicit template specialization
  125. // generated by autoexplicit.sh
  126. template Eigen::Matrix<double, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&);
  127. // generated by autoexplicit.sh
  128. template Eigen::SparseMatrix<double, 0, int> igl::cat<Eigen::SparseMatrix<double, 0, int> >(int, Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int> const&);
  129. // generated by autoexplicit.sh
  130. template Eigen::Matrix<int, -1, -1, 0, -1, -1> igl::cat<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(int, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&);
  131. #endif