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 SparseMatrixType> void sparse_product(const SparseMatrixType& ref) 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const int rows = ref.rows(); 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const int cols = ref.cols(); 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename SparseMatrixType::Scalar Scalar; 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { Flags = SparseMatrixType::Flags }; 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath double density = std::max(8./(rows*cols), 0.01); 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix; 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar,Dynamic,1> DenseVector; 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test matrix-matrix product 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows); 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat3 = DenseMatrix::Zero(rows, rows); 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refMat4 = DenseMatrix::Zero(rows, rows); 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix dm4 = DenseMatrix::Zero(rows, rows); 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m2(rows, rows); 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m3(rows, rows); 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m4(rows, rows); 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refMat2, m2); 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refMat3, m3); 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refMat4, m4); 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2*m3, refMat4=refMat2*refMat3); 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2.transpose()*m3, refMat4=refMat2.transpose()*refMat3); 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2.transpose()*m3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose()); 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m4=m2*m3.transpose(), refMat4=refMat2*refMat3.transpose()); 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sparse * dense 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3); 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2*refMat3.transpose(), refMat4=refMat2*refMat3.transpose()); 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2.transpose()*refMat3, refMat4=refMat2.transpose()*refMat3); 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=m2.transpose()*refMat3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose()); 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // dense * sparse 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3); 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2*m3.transpose(), refMat4=refMat2*refMat3.transpose()); 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2.transpose()*m3, refMat4=refMat2.transpose()*refMat3); 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(dm4=refMat2.transpose()*m3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose()); 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=m3*m3, refMat3=refMat3*refMat3); 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test matrix - diagonal product 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(false) // it compiles, but the precision is terrible. probably doesn't matter in this branch.... 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refM2 = DenseMatrix::Zero(rows, rows); 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refM3 = DenseMatrix::Zero(rows, rows); 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DiagonalMatrix<DenseVector> d1(DenseVector::Random(rows)); 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m2(rows, rows); 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m3(rows, rows); 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refM2, m2); 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refM3, m3); 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=m2*d1, refM3=refM2*d1); 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=m2.transpose()*d1, refM3=refM2.transpose()*d1); 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=d1*m2, refM3=d1*refM2); 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1 * refM2.transpose()); 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // test self adjoint products 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix b = DenseMatrix::Random(rows, rows); 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix x = DenseMatrix::Random(rows, rows); 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refX = DenseMatrix::Random(rows, rows); 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refUp = DenseMatrix::Zero(rows, rows); 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refLo = DenseMatrix::Zero(rows, rows); 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DenseMatrix refS = DenseMatrix::Zero(rows, rows); 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mUp(rows, rows); 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mLo(rows, rows); 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType mS(rows, rows); 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath do { 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initSparse<Scalar>(density, refUp, mUp, ForceRealDiag|/*ForceNonZeroDiag|*/MakeUpperTriangular); 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } while (refUp.isZero()); 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refLo = refUp.transpose().conjugate(); 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mLo = mUp.transpose().conjugate(); 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refS = refUp + refLo; 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath refS.diagonal() *= 0.5; 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mS = mUp + mLo; 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (int k=0; k<mS.outerSize(); ++k) 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (typename SparseMatrixType::InnerIterator it(mS,k); it; ++it) 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (it.index() == k) 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath it.valueRef() *= 0.5; 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(refS.adjoint(), refS); 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mS.transpose().conjugate(), mS); 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(mS, refS); 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mS*b, refX=refS*b); 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mUp.template marked<UpperTriangular|SelfAdjoint>()*b, refX=refS*b); 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mLo.template marked<LowerTriangular|SelfAdjoint>()*b, refX=refS*b); 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath VERIFY_IS_APPROX(x=mS.template marked<SelfAdjoint>()*b, refX=refS*b); 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid test_eigen2_sparse_product() 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int i = 0; i < g_repeat; i++) { 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( sparse_product(SparseMatrix<double>(8, 8)) ); 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_2( sparse_product(SparseMatrix<std::complex<double> >(16, 16)) ); 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_1( sparse_product(SparseMatrix<double>(33, 33)) ); 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CALL_SUBTEST_3( sparse_product(DynamicSparseMatrix<double>(8, 8)) ); 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 116