diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index aa094d703..d884e7df8 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -450,6 +450,12 @@ class SparseMatrix return *this; } + template + inline SparseMatrix& operator=(const SparseProduct& product) + { + return Base::operator=(product); + } + template EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other) { diff --git a/Eigen/src/Sparse/SparseProduct.h b/Eigen/src/Sparse/SparseProduct.h index 3a47df6aa..7aa81312e 100644 --- a/Eigen/src/Sparse/SparseProduct.h +++ b/Eigen/src/Sparse/SparseProduct.h @@ -147,13 +147,16 @@ static void ei_sparse_product_impl2(const Lhs& lhs, const Rhs& rhs, ResultType& ei_assert(lhs.outerSize() == rhs.innerSize()); std::vector mask(rows,false); + Matrix values(rows); + Matrix indices(rows); // estimate the number of non zero entries float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols())); float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols); float ratioRes = std::min(ratioLhs * avgNnzPerRhsColumn, 1.f); - float ratio; + int t200 = rows/(log2(200)*1.39); + int t = (rows*100)/139; res.resize(rows, cols); res.reserve(int(ratioRes*rows*cols)); @@ -162,6 +165,7 @@ static void ei_sparse_product_impl2(const Lhs& lhs, const Rhs& rhs, ResultType& { res.startVec(j); + int nnz = 0; for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt) { Scalar y = rhsIt.value(); @@ -173,42 +177,42 @@ static void ei_sparse_product_impl2(const Lhs& lhs, const Rhs& rhs, ResultType& if(!mask[i]) { mask[i] = true; - values[i] = x * y; - res.insertBackNoCheck(j,i); +// values[i] = x * y; +// indices[nnz] = i; + ++nnz; } else - res._valuePtr()[mask[i]] += x* y; + values[i] += x * y; } } + // FIXME reserve nnz non zeros + // FIXME implement fast sort algorithms for very small nnz // if the result is sparse enough => use a quick sort // otherwise => loop through the entire vector - SparseInnerVectorSet vec(res,j); - - int nnz = vec.nonZeros(); - if(rows/1.39 > nnz * log2(nnz)) - { - std::sort(vec._innerIndexPtr(), vec._innerIndexPtr()+vec.nonZeros()); - for (typename ResultType::InnerIterator it(res, j); it; ++it) - { - it.valueRef() = values[it.index()]; - mask[it.index()] = false; - } - } - else - { - // dense path - int count = 0; - for(int i=0; i1) std::sort(indices.data(),indices.data()+nnz); +// for(int k=0; k static void ei_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) { +// return ei_sparse_product_impl2(lhs,rhs,res); + typedef typename ei_traits::type>::Scalar Scalar; // make sure to call innerSize/outerSize since we fake the storage order. @@ -274,6 +280,7 @@ struct ei_sparse_product_selector static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) { +// std::cerr << __LINE__ << "\n"; typename ei_cleantype::type _res(res.rows(), res.cols()); ei_sparse_product_impl(lhs, rhs, _res); res.swap(_res); @@ -285,6 +292,7 @@ struct ei_sparse_product_selector { static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) { +// std::cerr << __LINE__ << "\n"; // we need a col-major matrix to hold the result typedef SparseMatrix SparseTemporaryType; SparseTemporaryType _res(res.rows(), res.cols()); @@ -298,6 +306,7 @@ struct ei_sparse_product_selector { static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) { +// std::cerr << __LINE__ << "\n"; // let's transpose the product to get a column x column product typename ei_cleantype::type _res(res.rows(), res.cols()); ei_sparse_product_impl(rhs, lhs, _res); @@ -310,11 +319,20 @@ struct ei_sparse_product_selector { static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) { +// std::cerr << "here...\n"; + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix colLhs(lhs); + ColMajorMatrix colRhs(rhs); +// std::cerr << "more...\n"; + ei_sparse_product_impl(colLhs, colRhs, res); +// std::cerr << "OK.\n"; + // let's transpose the product to get a column x column product - typedef SparseMatrix SparseTemporaryType; - SparseTemporaryType _res(res.cols(), res.rows()); - ei_sparse_product_impl(rhs, lhs, _res); - res = _res.transpose(); + +// typedef SparseMatrix SparseTemporaryType; +// SparseTemporaryType _res(res.cols(), res.rows()); +// ei_sparse_product_impl(rhs, lhs, _res); +// res = _res.transpose(); } }; @@ -327,6 +345,7 @@ template template inline Derived& SparseMatrixBase::operator=(const SparseProduct& product) { +// std::cerr << "there..." << typeid(Lhs).name() << " " << typeid(Lhs).name() << " " << (Derived::Flags&&RowMajorBit) << "\n"; ei_sparse_product_selector< typename ei_cleantype::type, typename ei_cleantype::type, @@ -348,7 +367,7 @@ struct ei_sparse_product_selector2(lhs, rhs, res, 0); + ei_sparse_product_impl2(lhs, rhs, res); } }; @@ -357,11 +376,11 @@ struct ei_sparse_product_selector2 RowMajorMatrix; - RowMajorMatrix rhsRow = rhs; - RowMajorMatrix resRow(res.rows(), res.cols()); - ei_sparse_product_impl2(rhsRow, lhs, resRow); - res = resRow; +// typedef SparseMatrix RowMajorMatrix; +// RowMajorMatrix rhsRow = rhs; +// RowMajorMatrix resRow(res.rows(), res.cols()); +// ei_sparse_product_impl2(rhsRow, lhs, resRow); +// res = resRow; } };