You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
5.3 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #ifndef EIGEN_TESTSPARSE_H
  10. #define EIGEN_TESTSPARSE_H
  11. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  12. #include "main.h"
  13. #if EIGEN_GNUC_AT_LEAST(4,0) && !defined __ICC && !defined(__clang__)
  14. #ifdef min
  15. #undef min
  16. #endif
  17. #ifdef max
  18. #undef max
  19. #endif
  20. #include <tr1/unordered_map>
  21. #define EIGEN_UNORDERED_MAP_SUPPORT
  22. namespace std {
  23. using std::tr1::unordered_map;
  24. }
  25. #endif
  26. #ifdef EIGEN_GOOGLEHASH_SUPPORT
  27. #include <google/sparse_hash_map>
  28. #endif
  29. #include <Eigen/Cholesky>
  30. #include <Eigen/LU>
  31. #include <Eigen/Sparse>
  32. enum {
  33. ForceNonZeroDiag = 1,
  34. MakeLowerTriangular = 2,
  35. MakeUpperTriangular = 4,
  36. ForceRealDiag = 8
  37. };
  38. /* Initializes both a sparse and dense matrix with same random values,
  39. * and a ratio of \a density non zero entries.
  40. * \param flags is a union of ForceNonZeroDiag, MakeLowerTriangular and MakeUpperTriangular
  41. * allowing to control the shape of the matrix.
  42. * \param zeroCoords and nonzeroCoords allows to get the coordinate lists of the non zero,
  43. * and zero coefficients respectively.
  44. */
  45. template<typename Scalar,int Opt1,int Opt2,typename Index> void
  46. initSparse(double density,
  47. Matrix<Scalar,Dynamic,Dynamic,Opt1>& refMat,
  48. SparseMatrix<Scalar,Opt2,Index>& sparseMat,
  49. int flags = 0,
  50. std::vector<Vector2i>* zeroCoords = 0,
  51. std::vector<Vector2i>* nonzeroCoords = 0)
  52. {
  53. enum { IsRowMajor = SparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
  54. sparseMat.setZero();
  55. //sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
  56. sparseMat.reserve(VectorXi::Constant(IsRowMajor ? refMat.rows() : refMat.cols(), int((1.5*density)*(IsRowMajor?refMat.cols():refMat.rows()))));
  57. for(int j=0; j<sparseMat.outerSize(); j++)
  58. {
  59. //sparseMat.startVec(j);
  60. for(int i=0; i<sparseMat.innerSize(); i++)
  61. {
  62. int ai(i), aj(j);
  63. if(IsRowMajor)
  64. std::swap(ai,aj);
  65. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  66. if ((flags&ForceNonZeroDiag) && (i==j))
  67. {
  68. v = internal::random<Scalar>()*Scalar(3.);
  69. v = v*v + Scalar(5.);
  70. }
  71. if ((flags & MakeLowerTriangular) && aj>ai)
  72. v = Scalar(0);
  73. else if ((flags & MakeUpperTriangular) && aj<ai)
  74. v = Scalar(0);
  75. if ((flags&ForceRealDiag) && (i==j))
  76. v = internal::real(v);
  77. if (v!=Scalar(0))
  78. {
  79. //sparseMat.insertBackByOuterInner(j,i) = v;
  80. sparseMat.insertByOuterInner(j,i) = v;
  81. if (nonzeroCoords)
  82. nonzeroCoords->push_back(Vector2i(ai,aj));
  83. }
  84. else if (zeroCoords)
  85. {
  86. zeroCoords->push_back(Vector2i(ai,aj));
  87. }
  88. refMat(ai,aj) = v;
  89. }
  90. }
  91. //sparseMat.finalize();
  92. }
  93. template<typename Scalar,int Opt1,int Opt2,typename Index> void
  94. initSparse(double density,
  95. Matrix<Scalar,Dynamic,Dynamic, Opt1>& refMat,
  96. DynamicSparseMatrix<Scalar, Opt2, Index>& sparseMat,
  97. int flags = 0,
  98. std::vector<Vector2i>* zeroCoords = 0,
  99. std::vector<Vector2i>* nonzeroCoords = 0)
  100. {
  101. enum { IsRowMajor = DynamicSparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
  102. sparseMat.setZero();
  103. sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
  104. for(int j=0; j<sparseMat.outerSize(); j++)
  105. {
  106. sparseMat.startVec(j); // not needed for DynamicSparseMatrix
  107. for(int i=0; i<sparseMat.innerSize(); i++)
  108. {
  109. int ai(i), aj(j);
  110. if(IsRowMajor)
  111. std::swap(ai,aj);
  112. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  113. if ((flags&ForceNonZeroDiag) && (i==j))
  114. {
  115. v = internal::random<Scalar>()*Scalar(3.);
  116. v = v*v + Scalar(5.);
  117. }
  118. if ((flags & MakeLowerTriangular) && aj>ai)
  119. v = Scalar(0);
  120. else if ((flags & MakeUpperTriangular) && aj<ai)
  121. v = Scalar(0);
  122. if ((flags&ForceRealDiag) && (i==j))
  123. v = internal::real(v);
  124. if (v!=Scalar(0))
  125. {
  126. sparseMat.insertBackByOuterInner(j,i) = v;
  127. if (nonzeroCoords)
  128. nonzeroCoords->push_back(Vector2i(ai,aj));
  129. }
  130. else if (zeroCoords)
  131. {
  132. zeroCoords->push_back(Vector2i(ai,aj));
  133. }
  134. refMat(ai,aj) = v;
  135. }
  136. }
  137. sparseMat.finalize();
  138. }
  139. template<typename Scalar> void
  140. initSparse(double density,
  141. Matrix<Scalar,Dynamic,1>& refVec,
  142. SparseVector<Scalar>& sparseVec,
  143. std::vector<int>* zeroCoords = 0,
  144. std::vector<int>* nonzeroCoords = 0)
  145. {
  146. sparseVec.reserve(int(refVec.size()*density));
  147. sparseVec.setZero();
  148. for(int i=0; i<refVec.size(); i++)
  149. {
  150. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  151. if (v!=Scalar(0))
  152. {
  153. sparseVec.insertBack(i) = v;
  154. if (nonzeroCoords)
  155. nonzeroCoords->push_back(i);
  156. }
  157. else if (zeroCoords)
  158. zeroCoords->push_back(i);
  159. refVec[i] = v;
  160. }
  161. }
  162. #include <unsupported/Eigen/SparseExtra>
  163. #endif // EIGEN_TESTSPARSE_H