// This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // // Copyright (C) 2008 Gael Guennebaud // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_SPARSEMATRIXBASE_H #define EIGEN_SPARSEMATRIXBASE_H template class SparseMatrixBase : public MatrixBase { public: typedef MatrixBase Base; typedef typename Base::Scalar Scalar; typedef typename Base::RealScalar RealScalar; enum { Flags = Base::Flags, RowMajor = ei_traits::Flags&RowMajorBit ? 1 : 0 }; inline const Derived& derived() const { return *static_cast(this); } inline Derived& derived() { return *static_cast(this); } inline Derived& const_cast_derived() const { return *static_cast(const_cast(this)); } SparseMatrixBase() : m_isRValue(false) {} bool isRValue() const { return m_isRValue; } Derived& markAsRValue() { m_isRValue = true; return derived(); } inline Derived& operator=(const Derived& other) { // std::cout << "Derived& operator=(const Derived& other)\n"; if (other.isRValue()) derived().swap(other.const_cast_derived()); else this->operator=(other); return derived(); } template inline Derived& operator=(const MatrixBase& other) { // std::cout << "Derived& operator=(const MatrixBase& other)\n"; //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); ei_assert((!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit))) && "the transpose operation is supposed to be handled in SparseMatrix::operator="); const int outerSize = other.outerSize(); //typedef typename ei_meta_if, Derived>::ret TempType; // thanks to shallow copies, we always eval to a tempary Derived temp(other.rows(), other.cols()); temp.startFill(std::max(this->rows(),this->cols())*2); for (int j=0; j inline Derived& operator=(const SparseMatrixBase& other) { // std::cout << typeid(OtherDerived).name() << "\n"; // std::cout << Flags << " " << OtherDerived::Flags << "\n"; const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); // std::cout << "eval transpose = " << transpose << "\n"; const int outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); if ((!transpose) && other.isRValue()) { // eval without temporary derived().resize(other.rows(), other.cols()); derived().startFill(std::max(this->rows(),this->cols())*2); for (int j=0; joperator=(static_cast&>(other)); return derived(); } template inline Derived& operator=(const Product& product); friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) { if (Flags&RowMajorBit) { for (int row=0; row trans = m.derived(); s << trans; } } return s; } // template // Scalar dot(const MatrixBase& other) const // { // EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) // EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) // EIGEN_STATIC_ASSERT((ei_is_same_type::ret), // YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) // // ei_assert(derived().size() == other.size()); // // short version, but the assembly looks more complicated because // // of the CwiseBinaryOp iterator complexity // // return res = (derived().cwise() * other.derived().conjugate()).sum(); // // // optimized, generic version // typename Derived::InnerIterator i(derived(),0); // typename OtherDerived::InnerIterator j(other.derived(),0); // Scalar res = 0; // while (i && j) // { // if (i.index()==j.index()) // { // // std::cerr << i.value() << " * " << j.value() << "\n"; // res += i.value() * ei_conj(j.value()); // ++i; ++j; // } // else if (i.index()