|
@@ -2,6 +2,7 @@
|
|
|
#include "sort.h"
|
|
|
#include "IndexComparison.h"
|
|
|
#include "SortableRow.h"
|
|
|
+#include "sortrows.h"
|
|
|
#include "list_to_matrix.h"
|
|
|
|
|
|
#include <algorithm>
|
|
@@ -43,7 +44,6 @@ IGL_INLINE void igl::unique(
|
|
|
IC[IM[i]] = j;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
C.resize(IA.size());
|
|
|
// Reindex IA according to IM
|
|
|
for(int i = 0;i<(int)IA.size();i++)
|
|
@@ -51,8 +51,95 @@ IGL_INLINE void igl::unique(
|
|
|
IA[i] = IM[IA[i]];
|
|
|
C[i] = A[IA[i]];
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+// Obsolete slow version converting to vectors
|
|
|
+// template <typename DerivedA, typename DerivedIA, typename DerivedIC>
|
|
|
+// IGL_INLINE void igl::unique_rows(
|
|
|
+// const Eigen::PlainObjectBase<DerivedA>& A,
|
|
|
+// Eigen::PlainObjectBase<DerivedA>& C,
|
|
|
+// Eigen::PlainObjectBase<DerivedIA>& IA,
|
|
|
+// Eigen::PlainObjectBase<DerivedIC>& IC)
|
|
|
+// {
|
|
|
+// using namespace std;
|
|
|
+//
|
|
|
+// typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
|
|
|
+// vector<SortableRow<RowVector> > rows;
|
|
|
+// rows.resize(A.rows());
|
|
|
+// // Loop over rows
|
|
|
+// for(int i = 0;i<A.rows();i++)
|
|
|
+// {
|
|
|
+// RowVector ri = A.row(i);
|
|
|
+// rows[i] = SortableRow<RowVector>(ri);
|
|
|
+// }
|
|
|
+// vector<SortableRow<RowVector> > vC;
|
|
|
+//
|
|
|
+// // unique on rows
|
|
|
+// vector<size_t> vIA;
|
|
|
+// vector<size_t> vIC;
|
|
|
+// unique(rows,vC,vIA,vIC);
|
|
|
+//
|
|
|
+// // Convert to eigen
|
|
|
+// C.resize(vC.size(),A.cols());
|
|
|
+// IA.resize(vIA.size(),1);
|
|
|
+// IC.resize(vIC.size(),1);
|
|
|
+// for(int i = 0;i<C.rows();i++)
|
|
|
+// {
|
|
|
+// C.row(i) = vC[i].data;
|
|
|
+// IA(i) = vIA[i];
|
|
|
+// }
|
|
|
+// for(int i = 0;i<A.rows();i++)
|
|
|
+// {
|
|
|
+// IC(i) = vIC[i];
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+// Obsolete
|
|
|
+// template <typename DerivedA, typename DerivedIA, typename DerivedIC>
|
|
|
+// IGL_INLINE void igl::unique_rows_many(
|
|
|
+// const Eigen::PlainObjectBase<DerivedA>& A,
|
|
|
+// Eigen::PlainObjectBase<DerivedA>& C,
|
|
|
+// Eigen::PlainObjectBase<DerivedIA>& IA,
|
|
|
+// Eigen::PlainObjectBase<DerivedIC>& IC)
|
|
|
+// {
|
|
|
+// using namespace std;
|
|
|
+// // frequency map
|
|
|
+// typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
|
|
|
+// IC.resize(A.rows(),1);
|
|
|
+// map<SortableRow<RowVector>, int> fm;
|
|
|
+// const int m = A.rows();
|
|
|
+// for(int i = 0;i<m;i++)
|
|
|
+// {
|
|
|
+// RowVector ri = A.row(i);
|
|
|
+// if(fm.count(SortableRow<RowVector>(ri)) == 0)
|
|
|
+// {
|
|
|
+// fm[SortableRow<RowVector>(ri)] = i;
|
|
|
+// }
|
|
|
+// IC(i) = fm[SortableRow<RowVector>(ri)];
|
|
|
+// }
|
|
|
+// IA.resize(fm.size(),1);
|
|
|
+// Eigen::VectorXi RIA(m);
|
|
|
+// C.resize(fm.size(),A.cols());
|
|
|
+// {
|
|
|
+// int i = 0;
|
|
|
+// for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
|
|
|
+// fit != fm.end();
|
|
|
+// fit++)
|
|
|
+// {
|
|
|
+// IA(i) = fit->second;
|
|
|
+// RIA(fit->second) = i;
|
|
|
+// C.row(i) = fit->first.data;
|
|
|
+// i++;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// // IC should index C
|
|
|
+// for(int i = 0;i<m;i++)
|
|
|
+// {
|
|
|
+// IC(i) = RIA(IC(i));
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
template <typename DerivedA, typename DerivedIA, typename DerivedIC>
|
|
|
IGL_INLINE void igl::unique_rows(
|
|
|
const Eigen::PlainObjectBase<DerivedA>& A,
|
|
@@ -61,79 +148,43 @@ IGL_INLINE void igl::unique_rows(
|
|
|
Eigen::PlainObjectBase<DerivedIC>& IC)
|
|
|
{
|
|
|
using namespace std;
|
|
|
+ using namespace igl;
|
|
|
+ using namespace Eigen;
|
|
|
+ VectorXi IM;
|
|
|
+ Eigen::PlainObjectBase<DerivedA> sortA;
|
|
|
+ sortrows(A,true,sortA,IM);
|
|
|
|
|
|
- typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
|
|
|
- vector<SortableRow<RowVector> > rows;
|
|
|
- rows.resize(A.rows());
|
|
|
- // Loop over rows
|
|
|
- for(int i = 0;i<A.rows();i++)
|
|
|
- {
|
|
|
- RowVector ri = A.row(i);
|
|
|
- rows[i] = SortableRow<RowVector>(ri);
|
|
|
- }
|
|
|
- vector<SortableRow<RowVector> > vC;
|
|
|
|
|
|
- // unique on rows
|
|
|
- vector<size_t> vIA;
|
|
|
- vector<size_t> vIC;
|
|
|
- unique(rows,vC,vIA,vIC);
|
|
|
-
|
|
|
- // Convert to eigen
|
|
|
- C.resize(vC.size(),A.cols());
|
|
|
- IA.resize(vIA.size(),1);
|
|
|
- IC.resize(vIC.size(),1);
|
|
|
- for(int i = 0;i<C.rows();i++)
|
|
|
+ vector<int> vIA(sortA.rows());
|
|
|
+ for(int i=0;i<(int)sortA.rows();i++)
|
|
|
{
|
|
|
- C.row(i) = vC[i].data;
|
|
|
- IA(i) = vIA[i];
|
|
|
+ vIA[i] = i;
|
|
|
}
|
|
|
- for(int i = 0;i<A.rows();i++)
|
|
|
- {
|
|
|
- IC(i) = vIC[i];
|
|
|
- }
|
|
|
-}
|
|
|
+ vIA.erase(
|
|
|
+ std::unique(
|
|
|
+ vIA.begin(),
|
|
|
+ vIA.end(),
|
|
|
+ igl::IndexRowEquals<const Eigen::PlainObjectBase<DerivedA> &>(sortA)),vIA.end());
|
|
|
|
|
|
-template <typename DerivedA, typename DerivedIA, typename DerivedIC>
|
|
|
-IGL_INLINE void igl::unique_rows_many(
|
|
|
- const Eigen::PlainObjectBase<DerivedA>& A,
|
|
|
- Eigen::PlainObjectBase<DerivedA>& C,
|
|
|
- Eigen::PlainObjectBase<DerivedIA>& IA,
|
|
|
- Eigen::PlainObjectBase<DerivedIC>& IC)
|
|
|
-{
|
|
|
- using namespace std;
|
|
|
- // frequency map
|
|
|
- typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
|
|
|
IC.resize(A.rows(),1);
|
|
|
- map<SortableRow<RowVector>, int> fm;
|
|
|
- const int m = A.rows();
|
|
|
- for(int i = 0;i<m;i++)
|
|
|
- {
|
|
|
- RowVector ri = A.row(i);
|
|
|
- if(fm.count(SortableRow<RowVector>(ri)) == 0)
|
|
|
- {
|
|
|
- fm[SortableRow<RowVector>(ri)] = i;
|
|
|
- }
|
|
|
- IC(i) = fm[SortableRow<RowVector>(ri)];
|
|
|
- }
|
|
|
- IA.resize(fm.size(),1);
|
|
|
- Eigen::VectorXi RIA(m);
|
|
|
- C.resize(fm.size(),A.cols());
|
|
|
{
|
|
|
- int i = 0;
|
|
|
- for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
|
|
|
- fit != fm.end();
|
|
|
- fit++)
|
|
|
+ int j = 0;
|
|
|
+ for(int i = 0;i<(int)sortA.rows();i++)
|
|
|
{
|
|
|
- IA(i) = fit->second;
|
|
|
- RIA(fit->second) = i;
|
|
|
- C.row(i) = fit->first.data;
|
|
|
- i++;
|
|
|
+ if(sortA.row(vIA[j]) != sortA.row(i))
|
|
|
+ {
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ IC(IM(i,0),0) = j;
|
|
|
}
|
|
|
}
|
|
|
- // IC should index C
|
|
|
- for(int i = 0;i<m;i++)
|
|
|
+ C.resize(vIA.size(),A.cols());
|
|
|
+ IA.resize(vIA.size(),1);
|
|
|
+ // Reindex IA according to IM
|
|
|
+ for(int i = 0;i<(int)vIA.size();i++)
|
|
|
{
|
|
|
- IC(i) = RIA(IC(i));
|
|
|
+ IA(i,0) = IM(vIA[i],0);
|
|
|
+ C.row(i) = A.row(IA(i,0));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -143,6 +194,4 @@ template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Mat
|
|
|
template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
|
template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
-template void igl::unique_rows_many<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
|
|
|
-template void igl::unique_rows_many<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
|
#endif
|