Exemple #1
0
// New test for Bug in SparseTimeDenseProduct
template<typename SparseMatrixType, typename DenseMatrixType> void sparse_product_regression_test()
{
  // This code does not compile with afflicted versions of the bug
  SparseMatrixType sm1(3,2);
  DenseMatrixType m2(2,2);
  sm1.setZero();
  m2.setZero();

  DenseMatrixType m3 = sm1*m2;


  // This code produces a segfault with afflicted versions of another SparseTimeDenseProduct
  // bug

  SparseMatrixType sm2(20000,2);
  sm2.setZero();
  DenseMatrixType m4(sm2*m2);

  VERIFY_IS_APPROX( m4(0,0), 0.0 );
}
Exemple #2
0
Int_t main(Int_t argc, Char_t *argv[])
{
   ROOT::Mpi::TEnvironment env(argc, argv);
   ROOT::Mpi::TIntraCommunicator world;
//    MpiInitTest(world, 2, ROOT::Mpi::GreaterIqual);
   TMatrixT<Double_t> mResult;
   TMatrixT<Double_t> m1(rowm1, colm1);
   TMatrixT<Double_t> m2(rowm2, colm2);

   TMatrixT<Double_t> m1square(side, side);
   TMatrixT<Double_t> m2square(side, side);

   for (Int_t i = 0; i < rowm1; i++)
      for (Int_t j = 0; j < colm1; j++)
         m1[i][j] = i + j;

   for (Int_t i = 0; i < rowm2; i++)
      for (Int_t j = 0; j < colm2; j++)
         m2[i][j] = j;

   for (Int_t i = 0; i < side; i++)
      for (Int_t j = 0; j < side; j++) {
         m1square[i][j] = j;
         m2square[i][j] = i;
      }

///////////////////////////////////////////////
//Testing methdos with results in single Rank//
///////////////////////////////////////////////
   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mul(m1);
   mul.Mult(m2, root);

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> add(m1square);
   add.Addition(m2square, root);

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> sub(m1square);
   sub.Subtraction(m2square, root);

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> trans(m2);
   trans.Transpose(root);

   if (world.Rank() == root) {
      mul.GetResult(mResult);
      MpiCompareTMatrixTest(mResult, m1 * m2, world.Rank(), "Matrix Multiplication Single");
      add.GetResult(mResult);
      MpiCompareTMatrixTest(mResult, m1square + m2square, world.Rank(), "Matrix Addition Single");
      sub.GetResult(mResult);
      MpiCompareTMatrixTest(mResult, m1square - m2square, world.Rank(), "Matrix Subtraction Single");
      trans.GetResult(mResult);
      MpiCompareTMatrixTest(mResult, TMatrixT<Double_t>(m2.GetNcols(), m2.GetNrows()).Transpose(m2), world.Rank(), "Matrix Transpose Single");
   }

///////////////////////////////////////////////
//Testing methdos with results in all ranks  //
///////////////////////////////////////////////

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulAll(m1);//return the results in all ranks
   mulAll.Mult(m2);
   mulAll.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, m1 * m2, world.Rank(), "Matrix Multiplication All");

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> addAll(m1square);
   addAll.Addition(m2square);

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> subAll(m1square);
   subAll.Subtraction(m2square);

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> transAll(m2);
   transAll.Transpose();
   addAll.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, m1square + m2square, world.Rank(), "Matrix Addition All");
   subAll.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, m1square - m2square, world.Rank(), "Matrix Subtraction All");
   transAll.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, TMatrixT<Double_t>(m2.GetNcols(), m2.GetNrows()).Transpose(m2), world.Rank(), "Matrix Transpose All");

//////////////////////////////////////////////////
//Testing methdos with multiple matrices types  //
//////////////////////////////////////////////////

   THilbertMatrixT<Double_t> him(side, side);
   TMatrixTSparse<Double_t>  sm1(rowm1, colm1);
   TMatrixTSparse<Double_t>  sm2(rowm2, colm2);
   TMatrixTFlat<Double_t>    fm1(m1);
   TMatrixTFlat<Double_t>    fm2(m2);
   TMatrixTSparse<Double_t>  smResult;

   for (Int_t i = 0; i < rowm1; i++)
      for (Int_t j = 0; j < colm1; j++) {
         sm1[i][j] = i * j;
      }
   for (Int_t i = 0; i < rowm2; i++)
      for (Int_t j = 0; j < colm2; j++) {
         sm2[i][j] = i * j;
      }



   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulHim(m1square);//return the results in all ranks
   mulHim.Mult(him);
   mulHim.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, m1square * TMatrixT<Double_t>(him), world.Rank(), "Matrix Multiplication HilbertMatrix");

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulHim2(him);//return the results in all ranks
   mulHim2.Mult(m1square);
   mulHim2.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, TMatrixT<Double_t>(him)*m1square, world.Rank(), "Matrix Multiplication HilbertMatrix In Constructor");

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulSm(m1);//return the results in all ranks
   mulSm.Mult(sm2);
   mulSm.GetResult(smResult);
   MpiCompareTMatrixTest(smResult, m1 * sm2, world.Rank(), "Matrix Multiplication SparseMatrix");

   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulSm2(sm1);//return the results in all ranks
   mulSm2.Mult(m2);
   mulSm2.GetResult(smResult);
   MpiCompareTMatrixTest(smResult, sm1 * m2, world.Rank(), "Matrix Multiplication SparseMatrix In Constructor");

   //
   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulFm(m1);//return the results in all ranks
   mulFm.Mult(fm2);
   mulFm.GetResult(mResult);
   MpiCompareTMatrixTest(mResult, m1 * TMatrixT<Double_t>(fm2.GetMatrix()->GetNrows(), fm2.GetMatrix()->GetNcols(), fm2.GetMatrix()->GetMatrixArray()), world.Rank(), "Matrix Multiplication FlatMatrix");


   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulFm2(fm1);//return the results in all ranks
   mulFm2.Mult(m2);
   mulFm2.GetResult(mResult);
   //NOTE fm matrix have data from m2, is the same tell m1*m2, just change the representation in memory
   MpiCompareTMatrixTest(mResult, m1 * m2, world.Rank(), "Matrix Multiplication FlatMatrix In Constructor");


   TVectorT<Double_t>        vec(rowv);
   for (Int_t i = 0; i < rowv; i++) vec[i] = i;
   ROOT::Mpi::Math::TMatrixTWrapper<Double_t> mulVec(m1);//return the results in all ranks
   mulVec.Mult(vec);
   mulVec.GetResult(mResult);
   TMatrixT<Double_t> mr((m1 * vec).GetNrows(), 1, (m1 * vec).GetMatrixArray());
//    mResult.Print();
//    mr.Print();
   MpiCompareTMatrixTest(mResult, mr, world.Rank(), "Matrix Multiplication with Vector");

   return 0;
}
template<typename MatrixType> void basicStuff(const MatrixType& m)
{
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;

  Index rows = m.rows();
  Index cols = m.cols();

  // this test relies a lot on Random.h, and there's not much more that we can do
  // to test it, hence I consider that we will have tested Random.h
  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);
  SquareMatrixType sm1 = SquareMatrixType::Random(rows,rows), sm2(rows,rows);

  Scalar x = 0;
  while(x == Scalar(0)) x = internal::random<Scalar>();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  m1.coeffRef(r,c) = x;
  VERIFY_IS_APPROX(x, m1.coeff(r,c));
  m1(r,c) = x;
  VERIFY_IS_APPROX(x, m1(r,c));
  v1.coeffRef(r) = x;
  VERIFY_IS_APPROX(x, v1.coeff(r));
  v1(r) = x;
  VERIFY_IS_APPROX(x, v1(r));
  v1[r] = x;
  VERIFY_IS_APPROX(x, v1[r]);

  VERIFY_IS_APPROX(               v1,    v1);
  VERIFY_IS_NOT_APPROX(           v1,    2*v1);
  VERIFY_IS_MUCH_SMALLER_THAN(    vzero, v1);
  VERIFY_IS_MUCH_SMALLER_THAN(  vzero, v1.squaredNorm());
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1,    v1);
  VERIFY_IS_APPROX(               vzero, v1-v1);
  VERIFY_IS_APPROX(               m1,    m1);
  VERIFY_IS_NOT_APPROX(           m1,    2*m1);
  VERIFY_IS_MUCH_SMALLER_THAN(    mzero, m1);
  VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1,    m1);
  VERIFY_IS_APPROX(               mzero, m1-m1);

  // always test operator() on each read-only expression class,
  // in order to check const-qualifiers.
  // indeed, if an expression class (here Zero) is meant to be read-only,
  // hence has no _write() method, the corresponding MatrixBase method (here zero())
  // should return a const-qualified object so that it is the const-qualified
  // operator() that gets called, which in turn calls _read().
  VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));

  // now test copying a row-vector into a (column-)vector and conversely.
  square.col(r) = square.row(r).eval();
  Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);
  Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);
  rv = square.row(r);
  cv = square.col(r);
  
  VERIFY_IS_APPROX(rv, cv.transpose());

  if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)
  {
    VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));
  }

  if(cols!=1 && rows!=1)
  {
    VERIFY_RAISES_ASSERT(m1[0]);
    VERIFY_RAISES_ASSERT((m1+m1)[0]);
  }

  VERIFY_IS_APPROX(m3 = m1,m1);
  MatrixType m4;
  VERIFY_IS_APPROX(m4 = m1,m1);

  m3.real() = m1.real();
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());

  // check == / != operators
  VERIFY(m1==m1);
  VERIFY(m1!=m2);
  VERIFY(!(m1==m2));
  VERIFY(!(m1!=m1));
  m1 = m2;
  VERIFY(m1==m2);
  VERIFY(!(m1!=m2));
  
  // check automatic transposition
  sm2.setZero();
  for(typename MatrixType::Index i=0;i<rows;++i)
    sm2.col(i) = sm1.row(i);
  VERIFY_IS_APPROX(sm2,sm1.transpose());
  
  sm2.setZero();
  for(typename MatrixType::Index i=0;i<rows;++i)
    sm2.col(i).noalias() = sm1.row(i);
  VERIFY_IS_APPROX(sm2,sm1.transpose());
  
  sm2.setZero();
  for(typename MatrixType::Index i=0;i<rows;++i)
    sm2.col(i).noalias() += sm1.row(i);
  VERIFY_IS_APPROX(sm2,sm1.transpose());
  
  sm2.setZero();
  for(typename MatrixType::Index i=0;i<rows;++i)
    sm2.col(i).noalias() -= sm1.row(i);
  VERIFY_IS_APPROX(sm2,-sm1.transpose());
  
  // check ternary usage
  {
    bool b = internal::random<int>(0,10)>5;
    m3 = b ? m1 : m2;
    if(b) VERIFY_IS_APPROX(m3,m1);
    else  VERIFY_IS_APPROX(m3,m2);
    m3 = b ? -m1 : m2;
    if(b) VERIFY_IS_APPROX(m3,-m1);
    else  VERIFY_IS_APPROX(m3,m2);
    m3 = b ? m1 : -m2;
    if(b) VERIFY_IS_APPROX(m3,m1);
    else  VERIFY_IS_APPROX(m3,-m2);
  }
}
Exemple #4
0
int main(int argc, char *argv[])
{
//   bench_sort();

  int rows = SIZE;
  int cols = SIZE;
  float density = DENSITY;

  EigenSparseMatrix sm1(rows,cols), sm2(rows,cols), sm3(rows,cols), sm4(rows,cols);

  BenchTimer timer;
  for (int nnzPerCol = NNZPERCOL; nnzPerCol>1; nnzPerCol/=1.1)
  {
    sm1.setZero();
    sm2.setZero();
    fillMatrix2(nnzPerCol, rows, cols, sm1);
    fillMatrix2(nnzPerCol, rows, cols, sm2);
//     std::cerr << "filling OK\n";

    // dense matrices
    #ifdef DENSEMATRIX
    {
      std::cout << "Eigen Dense\t" << nnzPerCol << "%\n";
      DenseMatrix m1(rows,cols), m2(rows,cols), m3(rows,cols);
      eiToDense(sm1, m1);
      eiToDense(sm2, m2);

      timer.reset();
      timer.start();
      for (int k=0; k<REPEAT; ++k)
        m3 = m1 * m2;
      timer.stop();
      std::cout << "   a * b:\t" << timer.value() << endl;

      timer.reset();
      timer.start();
      for (int k=0; k<REPEAT; ++k)
        m3 = m1.transpose() * m2;
      timer.stop();
      std::cout << "   a' * b:\t" << timer.value() << endl;

      timer.reset();
      timer.start();
      for (int k=0; k<REPEAT; ++k)
        m3 = m1.transpose() * m2.transpose();
      timer.stop();
      std::cout << "   a' * b':\t" << timer.value() << endl;

      timer.reset();
      timer.start();
      for (int k=0; k<REPEAT; ++k)
        m3 = m1 * m2.transpose();
      timer.stop();
      std::cout << "   a * b':\t" << timer.value() << endl;
    }
    #endif

    // eigen sparse matrices
    {
      std::cout << "Eigen sparse\t" << sm1.nonZeros()/(float(sm1.rows())*float(sm1.cols()))*100 << "% * "
                << sm2.nonZeros()/(float(sm2.rows())*float(sm2.cols()))*100 << "%\n";

      BENCH(sm3 = sm1 * sm2; )
      std::cout << "   a * b:\t" << timer.value() << endl;

//       BENCH(sm3 = sm1.transpose() * sm2; )
//       std::cout << "   a' * b:\t" << timer.value() << endl;
// //
//       BENCH(sm3 = sm1.transpose() * sm2.transpose(); )
//       std::cout << "   a' * b':\t" << timer.value() << endl;
// //
//       BENCH(sm3 = sm1 * sm2.transpose(); )
//       std::cout << "   a * b' :\t" << timer.value() << endl;


//       std::cout << "\n";
//
//       BENCH( sm3._experimentalNewProduct(sm1, sm2); )
//       std::cout << "   a * b:\t" << timer.value() << endl;
//
//       BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2); )
//       std::cout << "   a' * b:\t" << timer.value() << endl;
// //
//       BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2.transpose()); )
//       std::cout << "   a' * b':\t" << timer.value() << endl;
// //
//       BENCH(sm3._experimentalNewProduct(sm1, sm2.transpose());)
//       std::cout << "   a * b' :\t" << timer.value() << endl;
    }

    // eigen dyn-sparse matrices
    /*{
      DynamicSparseMatrix<Scalar> m1(sm1), m2(sm2), m3(sm3);
      std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/(float(m1.rows())*float(m1.cols()))*100 << "% * "
                << m2.nonZeros()/(float(m2.rows())*float(m2.cols()))*100 << "%\n";

//       timer.reset();
//       timer.start();
      BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1 * m2;)
//       timer.stop();
      std::cout << "   a * b:\t" << timer.value() << endl;
//       std::cout << sm3 << "\n";

      timer.reset();
      timer.start();
//       std::cerr << "transpose...\n";
//       EigenSparseMatrix sm4 = sm1.transpose();
//       std::cout << sm4.nonZeros() << " == " << sm1.nonZeros() << "\n";
//       exit(1);
//       std::cerr << "transpose OK\n";
//       std::cout << sm1 << "\n\n" << sm1.transpose() << "\n\n" << sm4.transpose() << "\n\n";
      BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2;)
//       timer.stop();
      std::cout << "   a' * b:\t" << timer.value() << endl;

//       timer.reset();
//       timer.start();
      BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2.transpose(); )
//       timer.stop();
      std::cout << "   a' * b':\t" << timer.value() << endl;

//       timer.reset();
//       timer.start();
      BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1 * m2.transpose(); )
//       timer.stop();
      std::cout << "   a * b' :\t" << timer.value() << endl;
    }*/

    // CSparse
    #ifdef CSPARSE
    {
      std::cout << "CSparse \t" << nnzPerCol << "%\n";
      cs *m1, *m2, *m3;
      eiToCSparse(sm1, m1);
      eiToCSparse(sm2, m2);

//       timer.reset();
//       timer.start();
//       for (int k=0; k<REPEAT; ++k)
      BENCH(
      {
        m3 = cs_sorted_multiply(m1, m2);
        if (!m3)
        {
          std::cerr << "cs_multiply failed\n";
//           break;
        }
//         cs_print(m3, 0);
        cs_spfree(m3);
      }
      );
//       timer.stop();
      std::cout << "   a * b:\t" << timer.value() << endl;

//       BENCH( { m3 = cs_sorted_multiply2(m1, m2); cs_spfree(m3); } );
//       std::cout << "   a * b:\t" << timer.value() << endl;
    }