1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. Eigen itself is part of the KDE project.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "sparse.h"
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SetterType,typename DenseType, typename Scalar, int Options>
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathbool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef SparseMatrix<Scalar,Options> SparseType;
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    sm.setZero();
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SetterType w(sm);
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    std::vector<Vector2i> remaining = nonzeroCoords;
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    while(!remaining.empty())
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      int i = ei_random<int>(0,remaining.size()-1);
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      remaining[i] = remaining.back();
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      remaining.pop_back();
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return sm.isApprox(ref);
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SetterType,typename DenseType, typename T>
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathbool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  sm.setZero();
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  std::vector<Vector2i> remaining = nonzeroCoords;
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  while(!remaining.empty())
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int i = ei_random<int>(0,remaining.size()-1);
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    remaining[i] = remaining.back();
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    remaining.pop_back();
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return sm.isApprox(ref);
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const int rows = ref.rows();
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const int cols = ref.cols();
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename SparseMatrixType::Scalar Scalar;
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { Flags = SparseMatrixType::Flags };
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  double density = std::max(8./(rows*cols), 0.01);
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar,Dynamic,1> DenseVector;
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar eps = 1e-6;
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  SparseMatrixType m(rows, cols);
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  DenseVector vec1 = DenseVector::Random(rows);
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar s1 = ei_random<Scalar>();
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  std::vector<Vector2i> zeroCoords;
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  std::vector<Vector2i> nonzeroCoords;
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return;
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test coeff and coeffRef
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int i=0; i<(int)zeroCoords.size(); ++i)
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(ei_is_same_type<SparseMatrixType,SparseMatrix<Scalar,Flags> >::ret)
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m, refMat);
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  VERIFY_IS_APPROX(m, refMat);
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  /*
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test InnerIterators and Block expressions
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for (int t=0; t<10; ++t)
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int j = ei_random<int>(0,cols-1);
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int i = ei_random<int>(0,rows-1);
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int w = ei_random<int>(1,cols-j-1);
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int h = ei_random<int>(1,rows-i-1);
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int c=0; c<w; c++)
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(int r=0; r<h; r++)
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//         VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     for(int r=0; r<h; r++)
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     {
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       for(int c=0; c<w; c++)
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       {
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//         VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       }
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     }
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int c=0; c<cols; c++)
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int r=0; r<rows; r++)
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test SparseSetters
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // coherent setter
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // TODO extend the MatrixSetter
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   {
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     m.setZero();
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     VERIFY_IS_NOT_APPROX(m, refMat);
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     SparseSetter<SparseMatrixType, FullyCoherentAccessPattern> w(m);
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     for (int i=0; i<nonzeroCoords.size(); ++i)
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     {
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       w->coeffRef(nonzeroCoords[i].x(),nonzeroCoords[i].y()) = refMat.coeff(nonzeroCoords[i].x(),nonzeroCoords[i].y());
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     }
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   }
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   VERIFY_IS_APPROX(m, refMat);
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // random setter
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   {
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     m.setZero();
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     VERIFY_IS_NOT_APPROX(m, refMat);
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     SparseSetter<SparseMatrixType, RandomAccessPattern> w(m);
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     std::vector<Vector2i> remaining = nonzeroCoords;
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     while(!remaining.empty())
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     {
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       int i = ei_random<int>(0,remaining.size()-1);
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       w->coeffRef(remaining[i].x(),remaining[i].y()) = refMat.coeff(remaining[i].x(),remaining[i].y());
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       remaining[i] = remaining.back();
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//       remaining.pop_back();
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     }
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   }
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   VERIFY_IS_APPROX(m, refMat);
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdMapTraits> >(m,refMat,nonzeroCoords) ));
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef EIGEN_UNORDERED_MAP_SUPPORT
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdUnorderedMapTraits> >(m,refMat,nonzeroCoords) ));
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef _DENSE_HASH_MAP_H_
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleDenseHashMapTraits> >(m,refMat,nonzeroCoords) ));
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef _SPARSE_HASH_MAP_H_
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleSparseHashMapTraits> >(m,refMat,nonzeroCoords) ));
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // test fillrand
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      DenseMatrix m1(rows,cols);
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m1.setZero();
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      SparseMatrixType m2(rows,cols);
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m2.startFill();
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int j=0; j<cols; ++j)
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for (int k=0; k<rows/2; ++k)
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          int i = ei_random<int>(0,rows-1);
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          if (m1.coeff(i,j)==Scalar(0))
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            m2.fillrand(i,j) = m1(i,j) = ei_random<Scalar>();
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m2.endFill();
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      VERIFY_IS_APPROX(m2,m1);
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test RandomSetter
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  /*{
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m1(rows,cols), m2(rows,cols);
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refM1, m1);
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Eigen::RandomSetter<SparseMatrixType > setter(m2);
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int j=0; j<m1.outerSize(); ++j)
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for (typename SparseMatrixType::InnerIterator i(m1,j); i; ++i)
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          setter(i.index(), j) = i.value();
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1, m2);
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }*/
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << m.transpose() << "\n\n"  << refMat.transpose() << "\n\n";
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   VERIFY_IS_APPROX(m, refMat);
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test basic computations
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m1(rows, rows);
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m2(rows, rows);
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m3(rows, rows);
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m4(rows, rows);
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refM1, m1);
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refM2, m2);
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refM3, m3);
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refM4, m4);
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1+m2, refM1+refM2);
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m3.cwise()*(m1+m2), refM3.cwise()*(refM1+refM2));
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1*=s1, refM1*=s1);
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1/=s1, refM1/=s1);
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m1.col(0).eigen2_dot(refM2.row(0)), refM1.col(0).eigen2_dot(refM2.row(0)));
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    refM4.setRandom();
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // sparse cwise* dense
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m3.cwise()*refM4, refM3.cwise()*refM4);
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test innerVector()
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m2(rows, rows);
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refMat2, m2);
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int j0 = ei_random(0,rows-1);
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int j1 = ei_random(0,rows-1);
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //m2.innerVector(j0) = 2*m2.innerVector(j1);
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //refMat2.col(j0) = 2*refMat2.col(j1);
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //VERIFY_IS_APPROX(m2, refMat2);
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test innerVectors()
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m2(rows, rows);
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refMat2, m2);
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int j0 = ei_random(0,rows-2);
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int j1 = ei_random(0,rows-2);
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int n0 = ei_random<int>(1,rows-std::max(j0,j1));
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                     refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    //refMat2.block(0,j0,rows,n0) = refMat2.block(0,j0,rows,n0) + refMat2.block(0,j1,rows,n0);
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test transpose
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m2(rows, rows);
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    initSparse<Scalar>(density, refMat2, m2);
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // test prune
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseMatrixType m2(rows, rows);
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrix refM2(rows, rows);
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    refM2.setZero();
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int countFalseNonZero = 0;
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int countTrueNonZero = 0;
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m2.startFill();
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (int j=0; j<m2.outerSize(); ++j)
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (int i=0; i<m2.innerSize(); ++i)
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        float x = ei_random<float>(0,1);
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (x<0.1)
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          // do nothing
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else if (x<0.5)
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          countFalseNonZero++;
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          m2.fill(i,j) = Scalar(0);
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        {
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          countTrueNonZero++;
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          m2.fill(i,j) = refM2(i,j) = Scalar(1);
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        }
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m2.endFill();
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2, refM2);
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m2.prune(1);
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY(countTrueNonZero==m2.nonZeros());
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    VERIFY_IS_APPROX(m2, refM2);
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_eigen2_sparse_basic()
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i = 0; i < g_repeat; i++) {
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(8, 8)) );
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_2( sparse_basic(SparseMatrix<std::complex<double> >(16, 16)) );
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(33, 33)) );
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CALL_SUBTEST_3( sparse_basic(DynamicSparseMatrix<double>(8, 8)) );
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
318