Browse Source

slice into

Former-commit-id: 696c6779eb1833e753b4d19611ce223958edc92d
jalec 13 years ago
parent
commit
8302a36e26
1 changed files with 115 additions and 0 deletions
  1. 115 0
      slice_into.h

+ 115 - 0
slice_into.h

@@ -0,0 +1,115 @@
+#ifndef IGL_SLICE_INTO_H
+#define IGL_SLICE_INTO_H
+namespace igl
+{
+  // Act like the matlab Y(row_indices,col_indices) = X
+  // 
+  // Inputs:
+  //   X  xm by xn rhs matrix
+  //   R  list of row indices
+  //   C  list of column indices
+  //   Y  ym by yn lhs matrix
+  // Output:
+  //   Y  ym by yn lhs matrix, same as input but Y(R,C) = X
+  template <typename T>
+  inline void slice_into(
+    const Eigen::SparseMatrix<T>& X,
+    const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+    const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
+    Eigen::SparseMatrix<T>& Y);
+
+  template <typename T, const int W, const int H>
+  inline void slice_into(
+    const Eigen::Matrix<T,W,H> & X,
+    const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+    const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
+    Eigen::Matrix<T,W,H> & Y);
+
+  template <typename T>
+  inline void slice_into(
+    const Eigen::Matrix<T,Eigen::Dynamic,1> & X,
+    const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+    Eigen::Matrix<T,Eigen::Dynamic,1> & Y);
+}
+
+// Implementation
+
+template <typename T>
+inline void igl::slice_into(
+  const Eigen::SparseMatrix<T>& X,
+  const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+  const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
+  Eigen::SparseMatrix<T>& Y)
+{
+
+  int xm = X.rows();
+  int xn = X.cols();
+  assert(R.size() == xm);
+  assert(C.size() == xn);
+  int ym = Y.size();
+  int yn = Y.size();
+  assert(R.minCoeff() >= 0);
+  assert(R.maxCoeff() < ym);
+  assert(C.minCoeff() >= 0);
+  assert(C.maxCoeff() < yn);
+  // create temporary dynamic sparse matrix
+  Eigen::DynamicSparseMatrix<T, Eigen::RowMajor>  dyn_Y(Y);
+  // Iterate over outside
+  for(int k=0; k<X.outerSize(); ++k)
+  {
+    // Iterate over inside
+    for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
+    {
+      dyn_Y.coeffRef(R(it.row()),C(it.col())) = it.value();
+    }
+  }
+  Y = Eigen::SparseMatrix<T>(dyn_Y);
+}
+
+template <typename T, const int W, const int H>
+inline void igl::slice_into(
+  const Eigen::Matrix<T,W,H> & X,
+  const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+  const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
+  Eigen::Matrix<T,W,H> & Y)
+{
+
+  int xm = X.rows();
+  int xn = X.cols();
+  assert(R.size() == xm);
+  assert(C.size() == xn);
+  int ym = Y.size();
+  int yn = Y.size();
+  assert(R.minCoeff() >= 0);
+  assert(R.maxCoeff() < ym);
+  assert(C.minCoeff() >= 0);
+  assert(C.maxCoeff() < yn);
+
+  // Build reindexing maps for columns and rows, -1 means not in map
+  Eigen::Matrix<int,Eigen::Dynamic,1> RI;
+  RI.resize(xm);
+  for(int i = 0;i<xm;i++)
+  {
+    for(int j = 0;j<xn;j++)
+    {
+      Y(R(i),C(j)) = X(i,j);
+    }
+  }
+}
+
+template <typename T>
+inline void igl::slice_into(
+  const Eigen::Matrix<T,Eigen::Dynamic,1> & X,
+  const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
+  Eigen::Matrix<T,Eigen::Dynamic,1> & Y)
+{
+  // phony column indices
+  Eigen::Matrix<int,Eigen::Dynamic,1> C;
+  C.resize(1);
+  C(0) = 0;
+  return igl::slice_into(X,R,C,Y);
+}
+
+#endif
+
+