sparse.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 StorageIndex> void
  46. initSparse(double density,
  47. Matrix<Scalar,Dynamic,Dynamic,Opt1>& refMat,
  48. SparseMatrix<Scalar,Opt2,StorageIndex>& sparseMat,
  49. int flags = 0,
  50. std::vector<Matrix<StorageIndex,2,1> >* zeroCoords = 0,
  51. std::vector<Matrix<StorageIndex,2,1> >* nonzeroCoords = 0)
  52. {
  53. enum { IsRowMajor = SparseMatrix<Scalar,Opt2,StorageIndex>::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(Index j=0; j<sparseMat.outerSize(); j++)
  58. {
  59. //sparseMat.startVec(j);
  60. for(Index i=0; i<sparseMat.innerSize(); i++)
  61. {
  62. Index 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. // FIXME: the following is too conservative
  69. v = internal::random<Scalar>()*Scalar(3.);
  70. v = v*v;
  71. if(numext::real(v)>0) v += Scalar(5);
  72. else v -= Scalar(5);
  73. }
  74. if ((flags & MakeLowerTriangular) && aj>ai)
  75. v = Scalar(0);
  76. else if ((flags & MakeUpperTriangular) && aj<ai)
  77. v = Scalar(0);
  78. if ((flags&ForceRealDiag) && (i==j))
  79. v = numext::real(v);
  80. if (v!=Scalar(0))
  81. {
  82. //sparseMat.insertBackByOuterInner(j,i) = v;
  83. sparseMat.insertByOuterInner(j,i) = v;
  84. if (nonzeroCoords)
  85. nonzeroCoords->push_back(Matrix<StorageIndex,2,1> (ai,aj));
  86. }
  87. else if (zeroCoords)
  88. {
  89. zeroCoords->push_back(Matrix<StorageIndex,2,1> (ai,aj));
  90. }
  91. refMat(ai,aj) = v;
  92. }
  93. }
  94. //sparseMat.finalize();
  95. }
  96. template<typename Scalar,int Opt1,int Opt2,typename Index> void
  97. initSparse(double density,
  98. Matrix<Scalar,Dynamic,Dynamic, Opt1>& refMat,
  99. DynamicSparseMatrix<Scalar, Opt2, Index>& sparseMat,
  100. int flags = 0,
  101. std::vector<Matrix<Index,2,1> >* zeroCoords = 0,
  102. std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)
  103. {
  104. enum { IsRowMajor = DynamicSparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
  105. sparseMat.setZero();
  106. sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
  107. for(int j=0; j<sparseMat.outerSize(); j++)
  108. {
  109. sparseMat.startVec(j); // not needed for DynamicSparseMatrix
  110. for(int i=0; i<sparseMat.innerSize(); i++)
  111. {
  112. int ai(i), aj(j);
  113. if(IsRowMajor)
  114. std::swap(ai,aj);
  115. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  116. if ((flags&ForceNonZeroDiag) && (i==j))
  117. {
  118. v = internal::random<Scalar>()*Scalar(3.);
  119. v = v*v + Scalar(5.);
  120. }
  121. if ((flags & MakeLowerTriangular) && aj>ai)
  122. v = Scalar(0);
  123. else if ((flags & MakeUpperTriangular) && aj<ai)
  124. v = Scalar(0);
  125. if ((flags&ForceRealDiag) && (i==j))
  126. v = numext::real(v);
  127. if (v!=Scalar(0))
  128. {
  129. sparseMat.insertBackByOuterInner(j,i) = v;
  130. if (nonzeroCoords)
  131. nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
  132. }
  133. else if (zeroCoords)
  134. {
  135. zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
  136. }
  137. refMat(ai,aj) = v;
  138. }
  139. }
  140. sparseMat.finalize();
  141. }
  142. template<typename Scalar,int Options,typename Index> void
  143. initSparse(double density,
  144. Matrix<Scalar,Dynamic,1>& refVec,
  145. SparseVector<Scalar,Options,Index>& sparseVec,
  146. std::vector<int>* zeroCoords = 0,
  147. std::vector<int>* nonzeroCoords = 0)
  148. {
  149. sparseVec.reserve(int(refVec.size()*density));
  150. sparseVec.setZero();
  151. for(int i=0; i<refVec.size(); i++)
  152. {
  153. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  154. if (v!=Scalar(0))
  155. {
  156. sparseVec.insertBack(i) = v;
  157. if (nonzeroCoords)
  158. nonzeroCoords->push_back(i);
  159. }
  160. else if (zeroCoords)
  161. zeroCoords->push_back(i);
  162. refVec[i] = v;
  163. }
  164. }
  165. template<typename Scalar,int Options,typename Index> void
  166. initSparse(double density,
  167. Matrix<Scalar,1,Dynamic>& refVec,
  168. SparseVector<Scalar,Options,Index>& sparseVec,
  169. std::vector<int>* zeroCoords = 0,
  170. std::vector<int>* nonzeroCoords = 0)
  171. {
  172. sparseVec.reserve(int(refVec.size()*density));
  173. sparseVec.setZero();
  174. for(int i=0; i<refVec.size(); i++)
  175. {
  176. Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
  177. if (v!=Scalar(0))
  178. {
  179. sparseVec.insertBack(i) = v;
  180. if (nonzeroCoords)
  181. nonzeroCoords->push_back(i);
  182. }
  183. else if (zeroCoords)
  184. zeroCoords->push_back(i);
  185. refVec[i] = v;
  186. }
  187. }
  188. #include <unsupported/Eigen/SparseExtra>
  189. #endif // EIGEN_TESTSPARSE_H