transpose_blocks.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #ifndef IGL_TRANSPOSE_BLOCKS
  2. #define IGL_TRANSPOSE_BLOCKS
  3. #include <Eigen/Core>
  4. namespace igl
  5. {
  6. // Templates:
  7. // T should be a eigen matrix primitive type like int or double
  8. // Inputs:
  9. // A m*k by n (dim: 1) or m by n*k (dim: 2) eigen Matrix of type T values
  10. // k number of blocks
  11. // dim dimension in which to transpose
  12. // Output
  13. // B n*k by m (dim: 1) or n by m*k (dim: 2) eigen Matrix of type T values,
  14. // NOT allowed to be the same as A
  15. //
  16. // Example:
  17. // A = [
  18. // 1 2 3 4
  19. // 5 6 7 8
  20. // 101 102 103 104
  21. // 105 106 107 108
  22. // 201 202 203 204
  23. // 205 206 207 208];
  24. // transpose_blocks(A,1,3,B);
  25. // B -> [
  26. // 1 5
  27. // 2 6
  28. // 3 7
  29. // 4 8
  30. // 101 105
  31. // 102 106
  32. // 103 107
  33. // 104 108
  34. // 201 205
  35. // 202 206
  36. // 203 207
  37. // 204 208];
  38. //
  39. template <typename T>
  40. inline void transpose_blocks(
  41. const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  42. const size_t k,
  43. const size_t dim,
  44. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B);
  45. }
  46. // Implementation
  47. #include <cassert>
  48. template <typename T>
  49. inline void igl::transpose_blocks(
  50. const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  51. const size_t k,
  52. const size_t dim,
  53. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B)
  54. {
  55. // Eigen matrices must be 2d so dim must be only 1 or 2
  56. assert(dim == 1 || dim == 2);
  57. // Output is not allowed to be input
  58. assert(&A != &B);
  59. // block height, width, and number of blocks
  60. int m,n;
  61. if(dim == 1)
  62. {
  63. m = A.rows()/k;
  64. n = A.cols();
  65. }else// dim == 2
  66. {
  67. m = A.rows();
  68. n = A.cols()/k;
  69. }
  70. // resize output
  71. if(dim == 1)
  72. {
  73. B.resize(n*k,m);
  74. }else//dim ==2
  75. {
  76. B.resize(n,m*k);
  77. }
  78. // loop over blocks
  79. for(int b = 0;b<(int)k;b++)
  80. {
  81. if(dim == 1)
  82. {
  83. B.block(b*n,0,n,m) = A.block(b*m,0,m,n).transpose();
  84. }else//dim ==2
  85. {
  86. B.block(0,b*m,n,m) = A.block(0,b*n,m,n).transpose();
  87. }
  88. }
  89. }
  90. #endif