• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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