Exemplo n.º 1
0
template<typename Scalar> void
initSPD(double density,
        Matrix<Scalar,Dynamic,Dynamic>& refMat,
        SparseMatrix<Scalar>& sparseMat)
{
  Matrix<Scalar,Dynamic,Dynamic> aux(refMat.rows(),refMat.cols());
  initSparse(density,refMat,sparseMat);
  refMat = refMat * refMat.adjoint();
  for (int k=0; k<2; ++k)
  {
    initSparse(density,aux,sparseMat,ForceNonZeroDiag);
    refMat += aux * aux.adjoint();
  }
  sparseMat.setZero();
  for (int j=0 ; j<sparseMat.cols(); ++j)
    for (int i=j ; i<sparseMat.rows(); ++i)
      if (refMat(i,j)!=Scalar(0))
        sparseMat.insert(i,j) = refMat(i,j);
  sparseMat.finalize();
}
Exemplo n.º 2
0
void test_kronecker_product()
{
  // DM = dense matrix; SM = sparse matrix

  Matrix<double, 2, 3> DM_a;
  SparseMatrix<double> SM_a(2,3);
  SM_a.insert(0,0) = DM_a.coeffRef(0,0) = -0.4461540300782201;
  SM_a.insert(0,1) = DM_a.coeffRef(0,1) = -0.8057364375283049;
  SM_a.insert(0,2) = DM_a.coeffRef(0,2) =  0.3896572459516341;
  SM_a.insert(1,0) = DM_a.coeffRef(1,0) = -0.9076572187376921;
  SM_a.insert(1,1) = DM_a.coeffRef(1,1) =  0.6469156566545853;
  SM_a.insert(1,2) = DM_a.coeffRef(1,2) = -0.3658010398782789;
 
  MatrixXd             DM_b(3,2);
  SparseMatrix<double> SM_b(3,2);
  SM_b.insert(0,0) = DM_b.coeffRef(0,0) =  0.9004440976767099;
  SM_b.insert(0,1) = DM_b.coeffRef(0,1) = -0.2368830858139832;
  SM_b.insert(1,0) = DM_b.coeffRef(1,0) = -0.9311078389941825;
  SM_b.insert(1,1) = DM_b.coeffRef(1,1) =  0.5310335762980047;
  SM_b.insert(2,0) = DM_b.coeffRef(2,0) = -0.1225112806872035;
  SM_b.insert(2,1) = DM_b.coeffRef(2,1) =  0.5903998022741264;

  SparseMatrix<double,RowMajor> SM_row_a(SM_a), SM_row_b(SM_b);

  // test DM_fixedSize = kroneckerProduct(DM_block,DM)
  Matrix<double, 6, 6> DM_fix_ab = kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b);

  CALL_SUBTEST(check_kronecker_product(DM_fix_ab));
  CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b)));

  for(int i=0;i<DM_fix_ab.rows();++i)
    for(int j=0;j<DM_fix_ab.cols();++j)
       VERIFY_IS_APPROX(kroneckerProduct(DM_a,DM_b).coeff(i,j), DM_fix_ab(i,j));

  // test DM_block = kroneckerProduct(DM,DM)
  MatrixXd DM_block_ab(10,15);
  DM_block_ab.block<6,6>(2,5) = kroneckerProduct(DM_a,DM_b);
  CALL_SUBTEST(check_kronecker_product(DM_block_ab.block<6,6>(2,5)));

  // test DM = kroneckerProduct(DM,DM)
  MatrixXd DM_ab = kroneckerProduct(DM_a,DM_b);
  CALL_SUBTEST(check_kronecker_product(DM_ab));
  CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a,DM_b)));

  // test SM = kroneckerProduct(SM,DM)
  SparseMatrix<double> SM_ab = kroneckerProduct(SM_a,DM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab));
  SparseMatrix<double,RowMajor> SM_ab2 = kroneckerProduct(SM_a,DM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab2));
  CALL_SUBTEST(check_kronecker_product(kroneckerProduct(SM_a,DM_b)));

  // test SM = kroneckerProduct(DM,SM)
  SM_ab.setZero();
  SM_ab.insert(0,0)=37.0;
  SM_ab = kroneckerProduct(DM_a,SM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab));
  SM_ab2.setZero();
  SM_ab2.insert(0,0)=37.0;
  SM_ab2 = kroneckerProduct(DM_a,SM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab2));
  CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a,SM_b)));

  // test SM = kroneckerProduct(SM,SM)
  SM_ab.resize(2,33);
  SM_ab.insert(0,0)=37.0;
  SM_ab = kroneckerProduct(SM_a,SM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab));
  SM_ab2.resize(5,11);
  SM_ab2.insert(0,0)=37.0;
  SM_ab2 = kroneckerProduct(SM_a,SM_b);
  CALL_SUBTEST(check_kronecker_product(SM_ab2));
  CALL_SUBTEST(check_kronecker_product(kroneckerProduct(SM_a,SM_b)));

  // test SM = kroneckerProduct(SM,SM) with sparse pattern
  SM_a.resize(4,5);
  SM_b.resize(3,2);
  SM_a.resizeNonZeros(0);
  SM_b.resizeNonZeros(0);
  SM_a.insert(1,0) = -0.1;
  SM_a.insert(0,3) = -0.2;
  SM_a.insert(2,4) =  0.3;
  SM_a.finalize();
  
  SM_b.insert(0,0) =  0.4;
  SM_b.insert(2,1) = -0.5;
  SM_b.finalize();
  SM_ab.resize(1,1);
  SM_ab.insert(0,0)=37.0;
  SM_ab = kroneckerProduct(SM_a,SM_b);
  CALL_SUBTEST(check_sparse_kronecker_product(SM_ab));

  // test dimension of result of DM = kroneckerProduct(DM,DM)
  MatrixXd DM_a2(2,1);
  MatrixXd DM_b2(5,4);
  MatrixXd DM_ab2 = kroneckerProduct(DM_a2,DM_b2);
  CALL_SUBTEST(check_dimension(DM_ab2,2*5,1*4));
  DM_a2.resize(10,9);
  DM_b2.resize(4,8);
  DM_ab2 = kroneckerProduct(DM_a2,DM_b2);
  CALL_SUBTEST(check_dimension(DM_ab2,10*4,9*8));
  
  for(int i = 0; i < g_repeat; i++)
  {
    double density = Eigen::internal::random<double>(0.01,0.5);
    int ra = Eigen::internal::random<int>(1,50);
    int ca = Eigen::internal::random<int>(1,50);
    int rb = Eigen::internal::random<int>(1,50);
    int cb = Eigen::internal::random<int>(1,50);
    SparseMatrix<float,ColMajor> sA(ra,ca), sB(rb,cb), sC;
    SparseMatrix<float,RowMajor> sC2;
    MatrixXf dA(ra,ca), dB(rb,cb), dC;
    initSparse(density, dA, sA);
    initSparse(density, dB, sB);
    
    sC = kroneckerProduct(sA,sB);
    dC = kroneckerProduct(dA,dB);
    VERIFY_IS_APPROX(MatrixXf(sC),dC);
    
    sC = kroneckerProduct(sA.transpose(),sB);
    dC = kroneckerProduct(dA.transpose(),dB);
    VERIFY_IS_APPROX(MatrixXf(sC),dC);
    
    sC = kroneckerProduct(sA.transpose(),sB.transpose());
    dC = kroneckerProduct(dA.transpose(),dB.transpose());
    VERIFY_IS_APPROX(MatrixXf(sC),dC);
    
    sC = kroneckerProduct(sA,sB.transpose());
    dC = kroneckerProduct(dA,dB.transpose());
    VERIFY_IS_APPROX(MatrixXf(sC),dC);
    
    sC2 = kroneckerProduct(sA,sB);
    dC = kroneckerProduct(dA,dB);
    VERIFY_IS_APPROX(MatrixXf(sC2),dC);
  }
}
Exemplo n.º 3
0
template<typename SparseMatrixType> void sparse_product()
{
  typedef typename SparseMatrixType::Index Index;
  Index n = 100;
  const Index rows  = internal::random<int>(1,n);
  const Index cols  = internal::random<int>(1,n);
  const Index depth = internal::random<int>(1,n);
  typedef typename SparseMatrixType::Scalar Scalar;
  enum { Flags = SparseMatrixType::Flags };

  double density = (std::max)(8./(rows*cols), 0.1);
  typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
  typedef Matrix<Scalar,Dynamic,1> DenseVector;

  Scalar s1 = internal::random<Scalar>();
  Scalar s2 = internal::random<Scalar>();

  // test matrix-matrix product
  {
    DenseMatrix refMat2  = DenseMatrix::Zero(rows, depth);
    DenseMatrix refMat2t = DenseMatrix::Zero(depth, rows);
    DenseMatrix refMat3  = DenseMatrix::Zero(depth, cols);
    DenseMatrix refMat3t = DenseMatrix::Zero(cols, depth);
    DenseMatrix refMat4  = DenseMatrix::Zero(rows, cols);
    DenseMatrix refMat4t = DenseMatrix::Zero(cols, rows);
    DenseMatrix refMat5  = DenseMatrix::Random(depth, cols);
    DenseMatrix refMat6  = DenseMatrix::Random(rows, rows);
    DenseMatrix dm4 = DenseMatrix::Zero(rows, rows);
//     DenseVector dv1 = DenseVector::Random(rows);
    SparseMatrixType m2 (rows, depth);
    SparseMatrixType m2t(depth, rows);
    SparseMatrixType m3 (depth, cols);
    SparseMatrixType m3t(cols, depth);
    SparseMatrixType m4 (rows, cols);
    SparseMatrixType m4t(cols, rows);
    SparseMatrixType m6(rows, rows);
    initSparse(density, refMat2,  m2);
    initSparse(density, refMat2t, m2t);
    initSparse(density, refMat3,  m3);
    initSparse(density, refMat3t, m3t);
    initSparse(density, refMat4,  m4);
    initSparse(density, refMat4t, m4t);
    initSparse(density, refMat6, m6);

//     int c = internal::random<int>(0,depth-1);

    // sparse * sparse
    VERIFY_IS_APPROX(m4=m2*m3, refMat4=refMat2*refMat3);
    VERIFY_IS_APPROX(m4=m2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3);
    VERIFY_IS_APPROX(m4=m2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());
    VERIFY_IS_APPROX(m4=m2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose());

    VERIFY_IS_APPROX(m4 = m2*m3/s1, refMat4 = refMat2*refMat3/s1);
    VERIFY_IS_APPROX(m4 = m2*m3*s1, refMat4 = refMat2*refMat3*s1);
    VERIFY_IS_APPROX(m4 = s2*m2*m3*s1, refMat4 = s2*refMat2*refMat3*s1);

    VERIFY_IS_APPROX(m4=(m2*m3).pruned(0), refMat4=refMat2*refMat3);
    VERIFY_IS_APPROX(m4=(m2t.transpose()*m3).pruned(0), refMat4=refMat2t.transpose()*refMat3);
    VERIFY_IS_APPROX(m4=(m2t.transpose()*m3t.transpose()).pruned(0), refMat4=refMat2t.transpose()*refMat3t.transpose());
    VERIFY_IS_APPROX(m4=(m2*m3t.transpose()).pruned(0), refMat4=refMat2*refMat3t.transpose());

    // test aliasing
    m4 = m2; refMat4 = refMat2;
    VERIFY_IS_APPROX(m4=m4*m3, refMat4=refMat4*refMat3);

    // sparse * dense
    VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3);
    VERIFY_IS_APPROX(dm4=m2*refMat3t.transpose(), refMat4=refMat2*refMat3t.transpose());
    VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3, refMat4=refMat2t.transpose()*refMat3);
    VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());

    VERIFY_IS_APPROX(dm4=m2*(refMat3+refMat3), refMat4=refMat2*(refMat3+refMat3));
    VERIFY_IS_APPROX(dm4=m2t.transpose()*(refMat3+refMat5)*0.5, refMat4=refMat2t.transpose()*(refMat3+refMat5)*0.5);

    // dense * sparse
    VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3);
    VERIFY_IS_APPROX(dm4=refMat2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose());
    VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3);
    VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());

    // sparse * dense and dense * sparse outer product
    test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4);

    VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6);
  }

  // test matrix - diagonal product
  {
    DenseMatrix refM2 = DenseMatrix::Zero(rows, cols);
    DenseMatrix refM3 = DenseMatrix::Zero(rows, cols);
    DenseMatrix d3 = DenseMatrix::Zero(rows, cols);
    DiagonalMatrix<Scalar,Dynamic> d1(DenseVector::Random(cols));
    DiagonalMatrix<Scalar,Dynamic> d2(DenseVector::Random(rows));
    SparseMatrixType m2(rows, cols);
    SparseMatrixType m3(rows, cols);
    initSparse<Scalar>(density, refM2, m2);
    initSparse<Scalar>(density, refM3, m3);
    VERIFY_IS_APPROX(m3=m2*d1, refM3=refM2*d1);
    VERIFY_IS_APPROX(m3=m2.transpose()*d2, refM3=refM2.transpose()*d2);
    VERIFY_IS_APPROX(m3=d2*m2, refM3=d2*refM2);
    VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1*refM2.transpose());
    
    // evaluate to a dense matrix to check the .row() and .col() iterator functions
    VERIFY_IS_APPROX(d3=m2*d1, refM3=refM2*d1);
    VERIFY_IS_APPROX(d3=m2.transpose()*d2, refM3=refM2.transpose()*d2);
    VERIFY_IS_APPROX(d3=d2*m2, refM3=d2*refM2);
    VERIFY_IS_APPROX(d3=d1*m2.transpose(), refM3=d1*refM2.transpose());
  }

  // test self adjoint products
  {
    DenseMatrix b = DenseMatrix::Random(rows, rows);
    DenseMatrix x = DenseMatrix::Random(rows, rows);
    DenseMatrix refX = DenseMatrix::Random(rows, rows);
    DenseMatrix refUp = DenseMatrix::Zero(rows, rows);
    DenseMatrix refLo = DenseMatrix::Zero(rows, rows);
    DenseMatrix refS = DenseMatrix::Zero(rows, rows);
    SparseMatrixType mUp(rows, rows);
    SparseMatrixType mLo(rows, rows);
    SparseMatrixType mS(rows, rows);
    do {
      initSparse<Scalar>(density, refUp, mUp, ForceRealDiag|/*ForceNonZeroDiag|*/MakeUpperTriangular);
    } while (refUp.isZero());
    refLo = refUp.adjoint();
    mLo = mUp.adjoint();
    refS = refUp + refLo;
    refS.diagonal() *= 0.5;
    mS = mUp + mLo;
    // TODO be able to address the diagonal....
    for (int k=0; k<mS.outerSize(); ++k)
      for (typename SparseMatrixType::InnerIterator it(mS,k); it; ++it)
        if (it.index() == k)
          it.valueRef() *= 0.5;

    VERIFY_IS_APPROX(refS.adjoint(), refS);
    VERIFY_IS_APPROX(mS.adjoint(), mS);
    VERIFY_IS_APPROX(mS, refS);
    VERIFY_IS_APPROX(x=mS*b, refX=refS*b);

    VERIFY_IS_APPROX(x=mUp.template selfadjointView<Upper>()*b, refX=refS*b);
    VERIFY_IS_APPROX(x=mLo.template selfadjointView<Lower>()*b, refX=refS*b);
    VERIFY_IS_APPROX(x=mS.template selfadjointView<Upper|Lower>()*b, refX=refS*b);
  }
}