partition.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include "partition.h"
  2. #include "mat_min.h"
  3. IGL_INLINE void igl::partition(
  4. const Eigen::MatrixXd & W,
  5. const int k,
  6. Eigen::Matrix<int,Eigen::Dynamic,1> & G,
  7. Eigen::Matrix<int,Eigen::Dynamic,1> & S,
  8. Eigen::Matrix<double,Eigen::Dynamic,1> & D)
  9. {
  10. // number of mesh vertices
  11. int n = W.rows();
  12. // Resize output
  13. G.resize(n);
  14. S.resize(k);
  15. // "Randomly" choose first seed
  16. // Pick a vertex farthest from 0
  17. int s;
  18. (W.array().square().matrix()).rowwise().sum().maxCoeff(&s);
  19. S(0) = s;
  20. // Initialize distance to closest seed
  21. D = ((W.rowwise() - W.row(s)).array().square()).matrix().rowwise().sum();
  22. G.setZero();
  23. // greedily choose the remaining k-1 seeds
  24. for(int i = 1;i<k;i++)
  25. {
  26. // Find maximum in D
  27. D.maxCoeff(&s);
  28. S(i) = s;
  29. // distance to this seed
  30. Eigen::Matrix<double,Eigen::Dynamic,1> Ds =
  31. ((W.rowwise() - W.row(s)).array().square()).matrix().rowwise().sum();
  32. // Concatenation of D and Ds: DDs = [D Ds];
  33. Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> DDs;
  34. // Make space for two columns
  35. DDs.resize(D.rows(),2);
  36. DDs.col(0) = D;
  37. DDs.col(1) = Ds;
  38. // Update D
  39. // get minimum of old D and distance to this seed, C == 1 if new distance
  40. // was smaller
  41. Eigen::Matrix<int,Eigen::Dynamic,1> C;
  42. igl::mat_min(DDs,2,D,C);
  43. G = (C.array() ==0).select(G,i);
  44. }
  45. }