sparse.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
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
17namespace 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
30enum {
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 */
44template<typename Scalar> void
45initSparse(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
87template<typename Scalar> void
88initSparse(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
130template<typename Scalar> void
131initSparse(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