فهرست منبع

Merge branch 'reworkSparseRepmat' of https://github.com/paul0noah/libigl into paul0noah-reworkSparseRepmat

Alec Jacobson 3 سال پیش
والد
کامیت
c8dbedc77b
3فایلهای تغییر یافته به همراه77 افزوده شده و 11 حذف شده
  1. 15 10
      include/igl/repmat.cpp
  2. 1 1
      include/igl/repmat.h
  3. 61 0
      tests/include/igl/repmat.cpp

+ 15 - 10
include/igl/repmat.cpp

@@ -29,7 +29,7 @@ IGL_INLINE void igl::repmat(
   }
 }
 
-template <typename T>
+template <typename T, int majorType>
 IGL_INLINE void igl::repmat(
   const Eigen::SparseMatrix<T> & A,
   const int r,
@@ -38,24 +38,29 @@ IGL_INLINE void igl::repmat(
 {
   assert(r>0);
   assert(c>0);
-  B.resize(r*A.rows(),c*A.cols());
-  B.reserve(r*c*A.nonZeros());
-  for(int i = 0;i<r;i++)
+  B.resize(r*A.rows(), c*A.cols());
+  std::vector<Eigen::Triplet<T>> b;
+  b.reserve(r*c*A.nonZeros());
+
+  for(int i = 0; i < r; i++)
   {
-    for(int j = 0;j<c;j++)
+    for(int j = 0; j < c; j++)
     {
-      // Loop outer level
-      for (int k=0; k<A.outerSize(); ++k)
+      // loop outer level
+      for (int k = 0; k < A.outerSize(); ++k)
       {
         // loop inner level
-        for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it)
+        for (typename Eigen::SparseMatrix<T, majorType>::InnerIterator 
+          it(A,k); it; ++it)
         {
-          B.insert(i*A.rows()+it.row(),j*A.cols() + it.col()) = it.value();
+          Eigen::Triplet<T> triplet(i * A.rows() + it.row(), j * A.cols() 
+            + it.col(), it.value());
+          b.push_back(triplet);
         }
       }
     }
   }
-  B.finalize();
+    B.setFromTriplets(b.begin(), b.end());
 }
 
 #ifdef IGL_STATIC_LIBRARY

+ 1 - 1
include/igl/repmat.h

@@ -38,7 +38,7 @@ namespace igl
     const int r,
     const int c,
     Eigen::PlainObjectBase<DerivedB> & B);
-  template <typename T>
+  template <typename T, int majorType>
   IGL_INLINE void repmat(
     const Eigen::SparseMatrix<T> & A,
     const int r,

+ 61 - 0
tests/include/igl/repmat.cpp

@@ -0,0 +1,61 @@
+#include <test_common.h>
+#include <Eigen/Sparse>
+#include <igl/repmat.h>
+
+
+template <typename T, int majorType>
+void checkRepmat(
+  Eigen::SparseMatrix<T, majorType> &A,
+  Eigen::SparseMatrix<T, majorType> &B,
+  const int rows,
+  const int cols,
+  const int r,
+  const int c)
+{
+  for (int i = 0; i < rows; i++)
+  {
+    for (int j = 0; j < cols; j++)
+    {
+      for (int ii = 0; ii < r; ii++)
+      {
+        for (int jj = 0; jj < c; jj++)
+        {
+          REQUIRE (A.coeff(i, j) == B.coeff(i + ii * rows, j + jj * cols));
+        }
+      }
+    }
+  }
+}
+
+template <typename T, int majorType>
+void testRepmat(
+  const int rows,
+  const int cols,
+  const int r,
+  const int c)
+{
+  Eigen::SparseMatrix<T, majorType> A;
+  A = (Eigen::Matrix<T, Eigen::Dynamic,
+    Eigen::Dynamic>().setRandom(rows, cols).sparseView());
+  Eigen::SparseMatrix<T, majorType> B;
+  igl::repmat(A, r, c, B);
+
+  REQUIRE (B.rows() == r * rows);
+  REQUIRE (B.cols() == c * cols);
+  checkRepmat<T, majorType>(A, B, rows, cols, r, c);
+}
+
+TEST_CASE("repmat: sparse rowMajor", "[igl]")
+{
+  testRepmat<double, Eigen::RowMajor>(4,  5, 2, 4);
+  testRepmat<   int, Eigen::RowMajor>(2,  8, 3, 4);
+  testRepmat< float, Eigen::RowMajor>(6, 10, 2, 2);
+}
+
+TEST_CASE("repmat: sparse colMajor", "[igl]")
+{
+  testRepmat<double, Eigen::ColMajor>(4,  5, 3, 5);
+  testRepmat<   int, Eigen::ColMajor>(2,  8, 3, 5);
+  testRepmat< float, Eigen::ColMajor>(6, 10, 3, 5);
+}
+