ConservativeSparseSparseProduct.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
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#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Lhs>::type::Scalar Scalar; 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Lhs>::type::Index Index; 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // make sure to call innerSize/outerSize since we fake the storage order. 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows = lhs.innerSize(); 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols = rhs.outerSize(); 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(lhs.outerSize() == rhs.innerSize()); 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::vector<bool> mask(rows,false); 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix<Scalar,Dynamic,1> values(rows); 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix<Index,Dynamic,1> indices(rows); 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // estimate the number of non zero entries 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // given a rhs column containing Y non zeros, we assume that the respective Y columns 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // of the lhs differs in average of one non zeros, thus the number of non zeros for 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // the product of a rhs column with the lhs is X+Y where X is the average number of non zero 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // per column of the lhs. 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.setZero(); 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.reserve(Index(estimated_nnz_prod)); 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // we compute each column of the result, one after the other 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index j=0; j<cols; ++j) 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.startVec(j); 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index nnz = 0; 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar y = rhsIt.value(); 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = rhsIt.index(); 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (typename Lhs::InnerIterator lhsIt(lhs, k); lhsIt; ++lhsIt) 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index i = lhsIt.index(); 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar x = lhsIt.value(); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!mask[i]) 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mask[i] = true; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath values[i] = x * y; 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath indices[nnz] = i; 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++nnz; 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath values[i] += x * y; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // unordered insertion 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int k=0; k<nnz; ++k) 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int i = indices[k]; 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.insertBackByOuterInnerUnordered(j,i) = values[i]; 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mask[i] = false; 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#if 0 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // alternative ordered insertion code: 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int t200 = rows/(log2(200)*1.39); 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int t = (rows*100)/139; 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME reserve nnz non zeros 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME implement fast sort algorithms for very small nnz 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // if the result is sparse enough => use a quick sort 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // otherwise => loop through the entire vector 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // In order to avoid to perform an expensive log2 when the 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // result is clearly very sparse we use a linear bound up to 200. 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //if((nnz<200 && nnz<t200) || nnz * log2(nnz) < t) 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //res.startVec(j); 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(true) 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(nnz>1) std::sort(indices.data(),indices.data()+nnz); 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int k=0; k<nnz; ++k) 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int i = indices[k]; 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.insertBackByOuterInner(j,i) = values[i]; 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mask[i] = false; 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // dense path 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(int i=0; i<rows; ++i) 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(mask[i]) 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mask[i] = false; 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.insertBackByOuterInner(j,i) = values[i]; 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.finalize(); 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType, 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit, 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int RhsStorageOrder = traits<Rhs>::Flags&RowMajorBit, 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int ResStorageOrder = traits<ResultType>::Flags&RowMajorBit> 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector; 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor> 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Lhs>::type LhsCleaned; 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename LhsCleaned::Scalar Scalar; 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix resCol(lhs.rows(),rhs.cols()); 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol); 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sort the non zeros: 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix resRow(resCol); 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resRow; 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,ColMajor> 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix rhsRow = rhs; 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix resRow(lhs.rows(), rhs.cols()); 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<RowMajorMatrix,Lhs,RowMajorMatrix>(rhsRow, lhs, resRow); 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resRow; 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,ColMajor> 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix lhsRow = lhs; 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix resRow(lhs.rows(), rhs.cols()); 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorMatrix,RowMajorMatrix>(rhs, lhsRow, resRow); 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resRow; 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix resRow(lhs.rows(), rhs.cols()); 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow); 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resRow; 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor> 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix resCol(lhs.rows(), rhs.cols()); 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol); 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resCol; 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,RowMajor> 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix lhsCol = lhs; 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix resCol(lhs.rows(), rhs.cols()); 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<ColMajorMatrix,Rhs,ColMajorMatrix>(lhsCol, rhs, resCol); 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resCol; 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,RowMajor> 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix rhsCol = rhs; 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix resCol(lhs.rows(), rhs.cols()); 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorMatrix,ColMajorMatrix>(lhs, rhsCol, resCol); 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resCol; 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,RowMajor> 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,RowMajor> RowMajorMatrix; 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<typename ResultType::Scalar,ColMajor> ColMajorMatrix; 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajorMatrix resRow(lhs.rows(),rhs.cols()); 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // sort the non zeros: 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajorMatrix resCol(resRow); 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res = resCol; 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H 246