1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> 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 SparseMatrixType, typename DenseMatrix, bool IsRowMajor=SparseMatrixType::IsRowMajor> struct test_outer; 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseMatrixType, typename DenseMatrix> struct test_outer<SparseMatrixType,DenseMatrix,false> { 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) { 167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename SparseMatrixType::Index Index; 177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index c = internal::random<Index>(0,m2.cols()-1); 187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index c1 = internal::random<Index>(0,m2.cols()-1); 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2.col(c)*refMat2.col(c1).transpose(), refMat4=refMat2.col(c)*refMat2.col(c1).transpose()); 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.col(c).transpose(), refMat4=refMat2.col(c1)*refMat2.col(c).transpose()); 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseMatrixType, typename DenseMatrix> struct test_outer<SparseMatrixType,DenseMatrix,true> { 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) { 267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename SparseMatrixType::Index Index; 277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index r = internal::random<Index>(0,m2.rows()-1); 287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index c1 = internal::random<Index>(0,m2.cols()-1); 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2.row(r).transpose()*refMat2.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat2.col(c1).transpose()); 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.row(r), refMat4=refMat2.col(c1)*refMat2.row(r)); 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// (m2,m4,refMat2,refMat4,dv1); 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// VERIFY_IS_APPROX(m4=m2.innerVector(c)*dv1.transpose(), refMat4=refMat2.colVector(c)*dv1.transpose()); 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// VERIFY_IS_APPROX(m4=dv1*mcm.col(c).transpose(), refMat4=dv1*refMat2.col(c).transpose()); 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseMatrixType> void sparse_product() 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename SparseMatrixType::Index Index; 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index n = 100; 427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index rows = internal::random<Index>(1,n); 437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index cols = internal::random<Index>(1,n); 447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index depth = internal::random<Index>(1,n); 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename SparseMatrixType::Scalar Scalar; 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { Flags = SparseMatrixType::Flags }; 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez double density = (std::max)(8./(rows*cols), 0.1); 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix; 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Dynamic,1> DenseVector; 517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef Matrix<Scalar,1,Dynamic> RowDenseVector; 527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef SparseVector<Scalar,0,Index> ColSpVector; 537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef SparseVector<Scalar,RowMajor,Index> RowSpVector; 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar s1 = internal::random<Scalar>(); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar s2 = internal::random<Scalar>(); 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test matrix-matrix product 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat2 = DenseMatrix::Zero(rows, depth); 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat2t = DenseMatrix::Zero(depth, rows); 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat3 = DenseMatrix::Zero(depth, cols); 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat3t = DenseMatrix::Zero(cols, depth); 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat4 = DenseMatrix::Zero(rows, cols); 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat4t = DenseMatrix::Zero(cols, rows); 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat5 = DenseMatrix::Random(depth, cols); 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat6 = DenseMatrix::Random(rows, rows); 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix dm4 = DenseMatrix::Zero(rows, rows); 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// DenseVector dv1 = DenseVector::Random(rows); 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m2 (rows, depth); 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m2t(depth, rows); 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m3 (depth, cols); 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m3t(cols, depth); 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m4 (rows, cols); 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m4t(cols, rows); 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m6(rows, rows); 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat2, m2); 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat2t, m2t); 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat3, m3); 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat3t, m3t); 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat4, m4); 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat4t, m4t); 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse(density, refMat6, m6); 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// int c = internal::random<int>(0,depth-1); 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sparse * sparse 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2*m3, refMat4=refMat2*refMat3); 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3); 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose()); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4 = m2*m3/s1, refMat4 = refMat2*refMat3/s1); 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4 = m2*m3*s1, refMat4 = refMat2*refMat3*s1); 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4 = s2*m2*m3*s1, refMat4 = s2*refMat2*refMat3*s1); 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=(m2*m3).pruned(0), refMat4=refMat2*refMat3); 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=(m2t.transpose()*m3).pruned(0), refMat4=refMat2t.transpose()*refMat3); 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=(m2t.transpose()*m3t.transpose()).pruned(0), refMat4=refMat2t.transpose()*refMat3t.transpose()); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=(m2*m3t.transpose()).pruned(0), refMat4=refMat2*refMat3t.transpose()); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test aliasing 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m4 = m2; refMat4 = refMat2; 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m4*m3, refMat4=refMat4*refMat3); 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sparse * dense 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3); 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2*refMat3t.transpose(), refMat4=refMat2*refMat3t.transpose()); 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3, refMat4=refMat2t.transpose()*refMat3); 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2*(refMat3+refMat3), refMat4=refMat2*(refMat3+refMat3)); 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2t.transpose()*(refMat3+refMat5)*0.5, refMat4=refMat2t.transpose()*(refMat3+refMat5)*0.5); 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // dense * sparse 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3); 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose()); 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3); 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sparse * dense and dense * sparse outer product 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4); 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6); 1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // sparse matrix * sparse vector 1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ColSpVector cv0(cols), cv1; 1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseVector dcv0(cols), dcv1; 1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez initSparse(2*density,dcv0, cv0); 1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez RowSpVector rv0(depth), rv1; 1327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez RowDenseVector drv0(depth), drv1(rv1); 1337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez initSparse(2*density,drv0, rv0); 1347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3); 1367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(rv1=rv0*m3, drv1=drv0*refMat3); 1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0); 1387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(cv1=m3t.adjoint()*cv0, dcv1=refMat3t.adjoint()*dcv0); 1397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(rv1=m3*cv0, drv1=refMat3*dcv0); 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test matrix - diagonal product 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseMatrix refM2 = DenseMatrix::Zero(rows, cols); 1457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseMatrix refM3 = DenseMatrix::Zero(rows, cols); 1467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseMatrix d3 = DenseMatrix::Zero(rows, cols); 1477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DiagonalMatrix<Scalar,Dynamic> d1(DenseVector::Random(cols)); 1487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DiagonalMatrix<Scalar,Dynamic> d2(DenseVector::Random(rows)); 1497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrixType m2(rows, cols); 1507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrixType m3(rows, cols); 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refM2, m2); 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refM3, m3); 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=m2*d1, refM3=refM2*d1); 1547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=m2.transpose()*d2, refM3=refM2.transpose()*d2); 1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=d2*m2, refM3=d2*refM2); 1567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1*refM2.transpose()); 1577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // also check with a SparseWrapper: 1597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseVector v1 = DenseVector::Random(cols); 1607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez DenseVector v2 = DenseVector::Random(rows); 1617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=m2*v1.asDiagonal(), refM3=refM2*v1.asDiagonal()); 1627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=m2.transpose()*v2.asDiagonal(), refM3=refM2.transpose()*v2.asDiagonal()); 1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2, refM3=v2.asDiagonal()*refM2); 1647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=v1.asDiagonal()*m2.transpose(), refM3=v1.asDiagonal()*refM2.transpose()); 1657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2*v1.asDiagonal(), refM3=v2.asDiagonal()*refM2*v1.asDiagonal()); 1677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // evaluate to a dense matrix to check the .row() and .col() iterator functions 1697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(d3=m2*d1, refM3=refM2*d1); 1707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(d3=m2.transpose()*d2, refM3=refM2.transpose()*d2); 1717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(d3=d2*m2, refM3=d2*refM2); 1727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(d3=d1*m2.transpose(), refM3=d1*refM2.transpose()); 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test self adjoint products 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix b = DenseMatrix::Random(rows, rows); 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix x = DenseMatrix::Random(rows, rows); 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refX = DenseMatrix::Random(rows, rows); 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refUp = DenseMatrix::Zero(rows, rows); 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refLo = DenseMatrix::Zero(rows, rows); 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refS = DenseMatrix::Zero(rows, rows); 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mUp(rows, rows); 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mLo(rows, rows); 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mS(rows, rows); 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath do { 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refUp, mUp, ForceRealDiag|/*ForceNonZeroDiag|*/MakeUpperTriangular); 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } while (refUp.isZero()); 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refLo = refUp.adjoint(); 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mLo = mUp.adjoint(); 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refS = refUp + refLo; 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refS.diagonal() *= 0.5; 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mS = mUp + mLo; 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO be able to address the diagonal.... 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (int k=0; k<mS.outerSize(); ++k) 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (typename SparseMatrixType::InnerIterator it(mS,k); it; ++it) 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (it.index() == k) 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath it.valueRef() *= 0.5; 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(refS.adjoint(), refS); 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mS.adjoint(), mS); 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mS, refS); 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mS*b, refX=refS*b); 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mUp.template selfadjointView<Upper>()*b, refX=refS*b); 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mLo.template selfadjointView<Lower>()*b, refX=refS*b); 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mS.template selfadjointView<Upper|Lower>()*b, refX=refS*b); 2087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 2097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // sparse selfadjointView * sparse 2107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrixType mSres(rows,rows); 2117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(mSres = mLo.template selfadjointView<Lower>()*mS, 2127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez refX = refLo.template selfadjointView<Lower>()*refS); 2137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // sparse * sparse selfadjointview 2147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez VERIFY_IS_APPROX(mSres = mS * mLo.template selfadjointView<Lower>(), 2157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez refX = refS * refLo.template selfadjointView<Lower>()); 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 2177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// New test for Bug in SparseTimeDenseProduct 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename SparseMatrixType, typename DenseMatrixType> void sparse_product_regression_test() 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // This code does not compile with afflicted versions of the bug 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType sm1(3,2); 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrixType m2(2,2); 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath sm1.setZero(); 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m2.setZero(); 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrixType m3 = sm1*m2; 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // This code produces a segfault with afflicted versions of another SparseTimeDenseProduct 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // bug 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType sm2(20000,2); 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath sm2.setZero(); 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrixType m4(sm2*m2); 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX( m4(0,0), 0.0 ); 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_sparse_product() 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int i = 0; i < g_repeat; i++) { 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,ColMajor> >()) ); 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,RowMajor> >()) ); 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, ColMajor > >()) ); 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, RowMajor > >()) ); 2497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez CALL_SUBTEST_3( (sparse_product<SparseMatrix<float,ColMajor,long int> >()) ); 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_4( (sparse_product_regression_test<SparseMatrix<double,RowMajor>, Matrix<double, Dynamic, Dynamic, RowMajor> >()) ); 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 253