1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. Eigen itself is part of the KDE project. 3 // 4 // Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com> 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 10 #ifndef EIGEN_TESTSPARSE_H 11 12 #include "main.h" 13 14 #if EIGEN_GNUC_AT_LEAST(4,0) && !defined __ICC 15 #include <tr1/unordered_map> 16 #define EIGEN_UNORDERED_MAP_SUPPORT 17 namespace std { 18 using std::tr1::unordered_map; 19 } 20 #endif 21 22 #ifdef EIGEN_GOOGLEHASH_SUPPORT 23 #include <google/sparse_hash_map> 24 #endif 25 26 #include <Eigen/Cholesky> 27 #include <Eigen/LU> 28 #include <Eigen/Sparse> 29 30 enum { 31 ForceNonZeroDiag = 1, 32 MakeLowerTriangular = 2, 33 MakeUpperTriangular = 4, 34 ForceRealDiag = 8 35 }; 36 37 /* Initializes both a sparse and dense matrix with same random values, 38 * and a ratio of \a density non zero entries. 39 * \param flags is a union of ForceNonZeroDiag, MakeLowerTriangular and MakeUpperTriangular 40 * allowing to control the shape of the matrix. 41 * \param zeroCoords and nonzeroCoords allows to get the coordinate lists of the non zero, 42 * and zero coefficients respectively. 43 */ 44 template<typename Scalar> void 45 initSparse(double density, 46 Matrix<Scalar,Dynamic,Dynamic>& refMat, 47 SparseMatrix<Scalar>& sparseMat, 48 int flags = 0, 49 std::vector<Vector2i>* zeroCoords = 0, 50 std::vector<Vector2i>* nonzeroCoords = 0) 51 { 52 sparseMat.startFill(int(refMat.rows()*refMat.cols()*density)); 53 for(int j=0; j<refMat.cols(); j++) 54 { 55 for(int i=0; i<refMat.rows(); i++) 56 { 57 Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0); 58 if ((flags&ForceNonZeroDiag) && (i==j)) 59 { 60 v = ei_random<Scalar>()*Scalar(3.); 61 v = v*v + Scalar(5.); 62 } 63 if ((flags & MakeLowerTriangular) && j>i) 64 v = Scalar(0); 65 else if ((flags & MakeUpperTriangular) && j<i) 66 v = Scalar(0); 67 68 if ((flags&ForceRealDiag) && (i==j)) 69 v = ei_real(v); 70 71 if (v!=Scalar(0)) 72 { 73 sparseMat.fill(i,j) = v; 74 if (nonzeroCoords) 75 nonzeroCoords->push_back(Vector2i(i,j)); 76 } 77 else if (zeroCoords) 78 { 79 zeroCoords->push_back(Vector2i(i,j)); 80 } 81 refMat(i,j) = v; 82 } 83 } 84 sparseMat.endFill(); 85 } 86 87 template<typename Scalar> void 88 initSparse(double density, 89 Matrix<Scalar,Dynamic,Dynamic>& refMat, 90 DynamicSparseMatrix<Scalar>& sparseMat, 91 int flags = 0, 92 std::vector<Vector2i>* zeroCoords = 0, 93 std::vector<Vector2i>* nonzeroCoords = 0) 94 { 95 sparseMat.startFill(int(refMat.rows()*refMat.cols()*density)); 96 for(int j=0; j<refMat.cols(); j++) 97 { 98 for(int i=0; i<refMat.rows(); i++) 99 { 100 Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0); 101 if ((flags&ForceNonZeroDiag) && (i==j)) 102 { 103 v = ei_random<Scalar>()*Scalar(3.); 104 v = v*v + Scalar(5.); 105 } 106 if ((flags & MakeLowerTriangular) && j>i) 107 v = Scalar(0); 108 else if ((flags & MakeUpperTriangular) && j<i) 109 v = Scalar(0); 110 111 if ((flags&ForceRealDiag) && (i==j)) 112 v = ei_real(v); 113 114 if (v!=Scalar(0)) 115 { 116 sparseMat.fill(i,j) = v; 117 if (nonzeroCoords) 118 nonzeroCoords->push_back(Vector2i(i,j)); 119 } 120 else if (zeroCoords) 121 { 122 zeroCoords->push_back(Vector2i(i,j)); 123 } 124 refMat(i,j) = v; 125 } 126 } 127 sparseMat.endFill(); 128 } 129 130 template<typename Scalar> void 131 initSparse(double density, 132 Matrix<Scalar,Dynamic,1>& refVec, 133 SparseVector<Scalar>& sparseVec, 134 std::vector<int>* zeroCoords = 0, 135 std::vector<int>* nonzeroCoords = 0) 136 { 137 sparseVec.reserve(int(refVec.size()*density)); 138 sparseVec.setZero(); 139 for(int i=0; i<refVec.size(); i++) 140 { 141 Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0); 142 if (v!=Scalar(0)) 143 { 144 sparseVec.fill(i) = v; 145 if (nonzeroCoords) 146 nonzeroCoords->push_back(i); 147 } 148 else if (zeroCoords) 149 zeroCoords->push_back(i); 150 refVec[i] = v; 151 } 152 } 153 154 #endif // EIGEN_TESTSPARSE_H 155