kronecker_product.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "kronecker_product.h"
  9. // Bug in unsupported/Eigen/SparseExtra needs iostream first
  10. #include <iostream>
  11. #include <unsupported/Eigen/SparseExtra>
  12. template <typename Scalar>
  13. IGL_INLINE Eigen::SparseMatrix<Scalar> igl::kronecker_product(
  14. const Eigen::SparseMatrix<Scalar> & A,
  15. const Eigen::SparseMatrix<Scalar> & B)
  16. {
  17. using namespace Eigen;
  18. using namespace std;
  19. // Convert B in triplets format
  20. MatrixXd B_triplets(B.nonZeros(),3);
  21. int count = 0;
  22. for (int k=0; k<B.outerSize(); ++k)
  23. for (SparseMatrix<double>::InnerIterator it(B,k); it; ++it)
  24. B_triplets.row(count++) << it.row(), it.col(), it.value();
  25. MatrixXd C_triplets(B_triplets.rows()*A.nonZeros(),3);
  26. count = 0;
  27. for (int k=0; k<A.outerSize(); ++k)
  28. for (SparseMatrix<double>::InnerIterator it(A,k); it; ++it)
  29. {
  30. int i = it.row();
  31. int j = it.col();
  32. double v = it.value();
  33. MatrixXd B_triplets_copy = B_triplets;
  34. B_triplets_copy.col(0) = B_triplets_copy.col(0).array() + double(B.rows()*i);
  35. B_triplets_copy.col(1) = B_triplets_copy.col(1).array() + double(B.cols()*j);
  36. B_triplets_copy.col(2) = B_triplets_copy.col(2).array() * v;
  37. C_triplets.block(count*B_triplets.rows(),0,
  38. B_triplets.rows(), B_triplets.cols()) = B_triplets_copy;
  39. count++;
  40. }
  41. typedef Eigen::Triplet<double> T;
  42. std::vector<T> triplets;
  43. triplets.reserve(C_triplets.rows());
  44. for(unsigned i=0; i<C_triplets.rows(); ++i)
  45. triplets.push_back(T(C_triplets(i,0),C_triplets(i,1),C_triplets(i,2)));
  46. SparseMatrix<Scalar> C(A.rows()*B.rows(),A.cols()*B.cols());
  47. C.setFromTriplets(triplets.begin(),triplets.end());
  48. return C;
  49. }
  50. #ifndef IGL_HEADER_ONLY
  51. // Explicit template specialization
  52. // generated by autoexplicit.sh
  53. #endif