Home | History | Annotate | Download | only in eigen2
      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 (at) 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