Home | History | Annotate | Download | only in test
      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 (at) 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 
     10 #ifndef EIGEN_TESTSPARSE_H
     11 #define EIGEN_TESTSPARSE_H
     12 
     13 #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
     14 
     15 #include "main.h"
     16 
     17 #if EIGEN_GNUC_AT_LEAST(4,0) && !defined __ICC && !defined(__clang__)
     18 
     19 #ifdef min
     20 #undef min
     21 #endif
     22 
     23 #ifdef max
     24 #undef max
     25 #endif
     26 
     27 #include <tr1/unordered_map>
     28 #define EIGEN_UNORDERED_MAP_SUPPORT
     29 namespace std {
     30   using std::tr1::unordered_map;
     31 }
     32 #endif
     33 
     34 #ifdef EIGEN_GOOGLEHASH_SUPPORT
     35   #include <google/sparse_hash_map>
     36 #endif
     37 
     38 #include <Eigen/Cholesky>
     39 #include <Eigen/LU>
     40 #include <Eigen/Sparse>
     41 
     42 enum {
     43   ForceNonZeroDiag = 1,
     44   MakeLowerTriangular = 2,
     45   MakeUpperTriangular = 4,
     46   ForceRealDiag = 8
     47 };
     48 
     49 /* Initializes both a sparse and dense matrix with same random values,
     50  * and a ratio of \a density non zero entries.
     51  * \param flags is a union of ForceNonZeroDiag, MakeLowerTriangular and MakeUpperTriangular
     52  *        allowing to control the shape of the matrix.
     53  * \param zeroCoords and nonzeroCoords allows to get the coordinate lists of the non zero,
     54  *        and zero coefficients respectively.
     55  */
     56 template<typename Scalar,int Opt1,int Opt2,typename Index> void
     57 initSparse(double density,
     58            Matrix<Scalar,Dynamic,Dynamic,Opt1>& refMat,
     59            SparseMatrix<Scalar,Opt2,Index>& sparseMat,
     60            int flags = 0,
     61            std::vector<Matrix<Index,2,1> >* zeroCoords = 0,
     62            std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)
     63 {
     64   enum { IsRowMajor = SparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
     65   sparseMat.setZero();
     66   //sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
     67   sparseMat.reserve(VectorXi::Constant(IsRowMajor ? refMat.rows() : refMat.cols(), int((1.5*density)*(IsRowMajor?refMat.cols():refMat.rows()))));
     68 
     69   for(Index j=0; j<sparseMat.outerSize(); j++)
     70   {
     71     //sparseMat.startVec(j);
     72     for(Index i=0; i<sparseMat.innerSize(); i++)
     73     {
     74       int ai(i), aj(j);
     75       if(IsRowMajor)
     76         std::swap(ai,aj);
     77       Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
     78       if ((flags&ForceNonZeroDiag) && (i==j))
     79       {
     80         v = internal::random<Scalar>()*Scalar(3.);
     81         v = v*v + Scalar(5.);
     82       }
     83       if ((flags & MakeLowerTriangular) && aj>ai)
     84         v = Scalar(0);
     85       else if ((flags & MakeUpperTriangular) && aj<ai)
     86         v = Scalar(0);
     87 
     88       if ((flags&ForceRealDiag) && (i==j))
     89         v = numext::real(v);
     90 
     91       if (v!=Scalar(0))
     92       {
     93         //sparseMat.insertBackByOuterInner(j,i) = v;
     94         sparseMat.insertByOuterInner(j,i) = v;
     95         if (nonzeroCoords)
     96           nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
     97       }
     98       else if (zeroCoords)
     99       {
    100         zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
    101       }
    102       refMat(ai,aj) = v;
    103     }
    104   }
    105   //sparseMat.finalize();
    106 }
    107 
    108 template<typename Scalar,int Opt1,int Opt2,typename Index> void
    109 initSparse(double density,
    110            Matrix<Scalar,Dynamic,Dynamic, Opt1>& refMat,
    111            DynamicSparseMatrix<Scalar, Opt2, Index>& sparseMat,
    112            int flags = 0,
    113            std::vector<Matrix<Index,2,1> >* zeroCoords = 0,
    114            std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)
    115 {
    116   enum { IsRowMajor = DynamicSparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
    117   sparseMat.setZero();
    118   sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
    119   for(int j=0; j<sparseMat.outerSize(); j++)
    120   {
    121     sparseMat.startVec(j); // not needed for DynamicSparseMatrix
    122     for(int i=0; i<sparseMat.innerSize(); i++)
    123     {
    124       int ai(i), aj(j);
    125       if(IsRowMajor)
    126         std::swap(ai,aj);
    127       Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
    128       if ((flags&ForceNonZeroDiag) && (i==j))
    129       {
    130         v = internal::random<Scalar>()*Scalar(3.);
    131         v = v*v + Scalar(5.);
    132       }
    133       if ((flags & MakeLowerTriangular) && aj>ai)
    134         v = Scalar(0);
    135       else if ((flags & MakeUpperTriangular) && aj<ai)
    136         v = Scalar(0);
    137 
    138       if ((flags&ForceRealDiag) && (i==j))
    139         v = numext::real(v);
    140 
    141       if (v!=Scalar(0))
    142       {
    143         sparseMat.insertBackByOuterInner(j,i) = v;
    144         if (nonzeroCoords)
    145           nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
    146       }
    147       else if (zeroCoords)
    148       {
    149         zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
    150       }
    151       refMat(ai,aj) = v;
    152     }
    153   }
    154   sparseMat.finalize();
    155 }
    156 
    157 template<typename Scalar,int Options,typename Index> void
    158 initSparse(double density,
    159            Matrix<Scalar,Dynamic,1>& refVec,
    160            SparseVector<Scalar,Options,Index>& sparseVec,
    161            std::vector<int>* zeroCoords = 0,
    162            std::vector<int>* nonzeroCoords = 0)
    163 {
    164   sparseVec.reserve(int(refVec.size()*density));
    165   sparseVec.setZero();
    166   for(Index i=0; i<refVec.size(); i++)
    167   {
    168     Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
    169     if (v!=Scalar(0))
    170     {
    171       sparseVec.insertBack(i) = v;
    172       if (nonzeroCoords)
    173         nonzeroCoords->push_back(i);
    174     }
    175     else if (zeroCoords)
    176         zeroCoords->push_back(i);
    177     refVec[i] = v;
    178   }
    179 }
    180 
    181 template<typename Scalar,int Options,typename Index> void
    182 initSparse(double density,
    183            Matrix<Scalar,1,Dynamic>& refVec,
    184            SparseVector<Scalar,Options,Index>& sparseVec,
    185            std::vector<int>* zeroCoords = 0,
    186            std::vector<int>* nonzeroCoords = 0)
    187 {
    188   sparseVec.reserve(int(refVec.size()*density));
    189   sparseVec.setZero();
    190   for(int i=0; i<refVec.size(); i++)
    191   {
    192     Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);
    193     if (v!=Scalar(0))
    194     {
    195       sparseVec.insertBack(i) = v;
    196       if (nonzeroCoords)
    197         nonzeroCoords->push_back(i);
    198     }
    199     else if (zeroCoords)
    200         zeroCoords->push_back(i);
    201     refVec[i] = v;
    202   }
    203 }
    204 
    205 
    206 #include <unsupported/Eigen/SparseExtra>
    207 #endif // EIGEN_TESTSPARSE_H
    208