2008-06-26 23:22:26 +00:00
// 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 <g.gael@free.fr>
//
// 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 <http://www.gnu.org/licenses/>.
# ifndef EIGEN_SPARSEMATRIXBASE_H
# define EIGEN_SPARSEMATRIXBASE_H
template < typename Derived >
class SparseMatrixBase : public MatrixBase < Derived >
{
public :
typedef MatrixBase < Derived > Base ;
typedef typename Base : : Scalar Scalar ;
2009-01-02 08:47:09 +00:00
typedef typename Base : : RealScalar RealScalar ;
2008-06-26 23:22:26 +00:00
enum {
Flags = Base : : Flags ,
RowMajor = ei_traits < Derived > : : Flags & RowMajorBit ? 1 : 0
} ;
inline const Derived & derived ( ) const { return * static_cast < const Derived * > ( this ) ; }
inline Derived & derived ( ) { return * static_cast < Derived * > ( this ) ; }
inline Derived & const_cast_derived ( ) const
{ return * static_cast < Derived * > ( const_cast < SparseMatrixBase * > ( this ) ) ; }
SparseMatrixBase ( )
2008-06-29 21:29:12 +00:00
: m_isRValue ( false )
2008-06-26 23:22:26 +00:00
{ }
bool isRValue ( ) const { return m_isRValue ; }
2008-06-29 21:29:12 +00:00
Derived & markAsRValue ( ) { m_isRValue = true ; return derived ( ) ; }
2008-06-26 23:22:26 +00:00
inline Derived & operator = ( const Derived & other )
{
2008-10-04 14:23:00 +00:00
// std::cout << "Derived& operator=(const Derived& other)\n";
2008-06-26 23:22:26 +00:00
if ( other . isRValue ( ) )
2008-06-29 21:29:12 +00:00
derived ( ) . swap ( other . const_cast_derived ( ) ) ;
2008-06-26 23:22:26 +00:00
else
this - > operator = < Derived > ( other ) ;
return derived ( ) ;
}
template < typename OtherDerived >
inline Derived & operator = ( const MatrixBase < OtherDerived > & other )
{
2008-10-04 14:23:00 +00:00
// std::cout << "Derived& operator=(const MatrixBase<OtherDerived>& other)\n";
2008-12-11 18:26:24 +00:00
//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= " ) ;
2008-06-28 23:07:14 +00:00
const int outerSize = other . outerSize ( ) ;
2008-10-21 13:35:04 +00:00
//typedef typename ei_meta_if<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::ret TempType;
// thanks to shallow copies, we always eval to a tempary
Derived temp ( other . rows ( ) , other . cols ( ) ) ;
2008-06-26 23:22:26 +00:00
temp . startFill ( std : : max ( this - > rows ( ) , this - > cols ( ) ) * 2 ) ;
for ( int j = 0 ; j < outerSize ; + + j )
{
for ( typename OtherDerived : : InnerIterator it ( other . derived ( ) , j ) ; it ; + + it )
{
Scalar v = it . value ( ) ;
if ( v ! = Scalar ( 0 ) )
2008-08-22 01:19:53 +00:00
{
2008-06-28 23:07:14 +00:00
if ( OtherDerived : : Flags & RowMajorBit ) temp . fill ( j , it . index ( ) ) = v ;
2008-06-26 23:22:26 +00:00
else temp . fill ( it . index ( ) , j ) = v ;
2008-08-22 01:19:53 +00:00
}
2008-06-26 23:22:26 +00:00
}
}
temp . endFill ( ) ;
2008-06-28 23:07:14 +00:00
2008-06-29 21:29:12 +00:00
derived ( ) = temp . markAsRValue ( ) ;
2008-06-26 23:22:26 +00:00
return derived ( ) ;
}
template < typename OtherDerived >
inline Derived & operator = ( const SparseMatrixBase < OtherDerived > & other )
{
2008-10-04 14:23:00 +00:00
// std::cout << typeid(OtherDerived).name() << "\n";
// std::cout << Flags << " " << OtherDerived::Flags << "\n";
2008-06-26 23:22:26 +00:00
const bool transpose = ( Flags & RowMajorBit ) ! = ( OtherDerived : : Flags & RowMajorBit ) ;
2008-06-28 23:07:14 +00:00
// std::cout << "eval transpose = " << transpose << "\n";
2008-06-26 23:22:26 +00:00
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 ; j < outerSize ; + + j )
{
for ( typename OtherDerived : : InnerIterator it ( other . derived ( ) , j ) ; it ; + + it )
{
Scalar v = it . value ( ) ;
if ( v ! = Scalar ( 0 ) )
2008-08-22 01:19:53 +00:00
{
2008-06-26 23:22:26 +00:00
if ( RowMajor ) derived ( ) . fill ( j , it . index ( ) ) = v ;
else derived ( ) . fill ( it . index ( ) , j ) = v ;
2008-08-22 01:19:53 +00:00
}
2008-06-26 23:22:26 +00:00
}
}
derived ( ) . endFill ( ) ;
}
else
this - > operator = < OtherDerived > ( static_cast < const MatrixBase < OtherDerived > & > ( other ) ) ;
return derived ( ) ;
}
2008-06-28 23:07:14 +00:00
template < typename Lhs , typename Rhs >
inline Derived & operator = ( const Product < Lhs , Rhs , SparseProduct > & product ) ;
2008-06-26 23:22:26 +00:00
friend std : : ostream & operator < < ( std : : ostream & s , const SparseMatrixBase & m )
{
if ( Flags & RowMajorBit )
{
2008-06-28 23:07:14 +00:00
for ( int row = 0 ; row < m . outerSize ( ) ; + + row )
2008-06-26 23:22:26 +00:00
{
int col = 0 ;
for ( typename Derived : : InnerIterator it ( m . derived ( ) , row ) ; it ; + + it )
{
for ( ; col < it . index ( ) ; + + col )
s < < " 0 " ;
2008-08-21 18:40:56 +00:00
s < < it . value ( ) < < " " ;
2008-06-29 21:29:12 +00:00
+ + col ;
2008-06-26 23:22:26 +00:00
}
for ( ; col < m . cols ( ) ; + + col )
s < < " 0 " ;
s < < std : : endl ;
}
}
else
{
2008-09-02 15:28:49 +00:00
if ( m . cols ( ) = = 1 ) {
int row = 0 ;
for ( typename Derived : : InnerIterator it ( m . derived ( ) , 0 ) ; it ; + + it )
{
for ( ; row < it . index ( ) ; + + row )
s < < " 0 " < < std : : endl ;
s < < it . value ( ) < < std : : endl ;
+ + row ;
}
for ( ; row < m . rows ( ) ; + + row )
s < < " 0 " < < std : : endl ;
}
else
{
2008-11-05 13:47:55 +00:00
SparseMatrix < Scalar , RowMajorBit > trans = m . derived ( ) ;
2008-09-02 15:28:49 +00:00
s < < trans ;
}
2008-06-26 23:22:26 +00:00
}
return s ;
}
protected :
bool m_isRValue ;
} ;
# endif // EIGEN_SPARSEMATRIXBASE_H