36    typedef gsEigen::Triplet<T,index_t> Triplet;
 
   37    typedef std::vector<gsEigen::Triplet<T,index_t> > Base;
 
   39    typedef typename Base::iterator       iterator;
 
   42    inline void add( 
int i, 
int j, T value )
 
   43    { this->push_back( Triplet(i,j,value) ); }
 
   45    inline void addSorted(
int i, 
int j, T value = 0)
 
   48        iterator pos = std::lower_bound(Base::begin(), Base::end(), t, compTriplet );
 
   49        if ( pos == Base::end() || (pos->row() != t.row() && pos->col() !=t.col()) )
 
   57        bool operator() (
const Triplet & left, 
const Triplet & right)
 
   59            return (left.col() < right.col()) ||
 
   60                    (left.col() == right.col() && left.row() < right.row()) ;
 
 
   72template<
typename T, 
int _Options, 
typename _Index>
 
   75    typedef gsEigen::SparseMatrix<T,_Options,_Index> SparseMatrix;
 
   76    static const int IsRowMajor = SparseMatrix::IsRowMajor;
 
   80    : m_values(NULL), m_indices(NULL),
 
   81      m_end(NULL)   , m_outer(0)
 
   87        const _Index oind = mat.outerIndexPtr()[outer];
 
   88        m_values  = mat.valuePtr()      + oind;
 
   89        m_indices = mat.innerIndexPtr() + oind;
 
   90        m_end = mat.isCompressed() ?
 
   91            mat.innerIndexPtr() + mat.outerIndexPtr()[outer+1] :
 
   92            mat.innerIndexPtr() + oind + mat.innerNonZeroPtr()[outer];
 
   96    { ++m_values; ++m_indices; 
return *
this; }
 
   98    inline const T& value()
 const { 
return *m_values; }
 
   99    inline T& valueRef() { 
return const_cast<T&
>(*m_values); }
 
  101    inline _Index index()
 const { 
return *m_indices; }
 
  102    inline _Index outer()
 const { 
return m_outer; }
 
  103    inline _Index row()
 const { 
return IsRowMajor ? m_outer : index(); }
 
  104    inline _Index col()
 const { 
return IsRowMajor ? index() : m_outer; }
 
  106    inline operator bool()
 const { 
return (m_indices < m_end); }
 
  110    const _Index * m_indices;
 
  111    const _Index * m_end;
 
 
  137template<
typename T, 
int _Options, 
typename _Index>
 
  141    typedef gsEigen::SparseMatrix<T,_Options,_Index> Base;
 
  146    typedef typename gsEigen::Block<Base> Block;
 
  149    typedef typename gsEigen::Block<const Base> constBlock;
 
  158    typedef memory::shared_ptr<gsSparseMatrix> 
Ptr;
 
  161    typedef memory::unique_ptr<gsSparseMatrix> 
uPtr;
 
  165    typedef typename gsEigen::SparseSelfAdjointView<Base, Lower> 
fullView;
 
  169    typedef typename gsEigen::SparseSelfAdjointView<const Base, Lower> 
constFullView;
 
  177    template<
typename OtherDerived>
 
  181    template<
typename OtherDerived, 
unsigned int UpLo>
 
  186    template<
typename OtherDerived>
 
  190    template<
typename OtherDerived>
 
  191    gsSparseMatrix(
const gsEigen::SparseMatrixBase<OtherDerived>& other)  : Base(other) { }
 
  194    template<
typename OtherDerived>
 
  195    gsSparseMatrix(
const gsEigen::ReturnByValue<OtherDerived>& other)  : Base(other) { }
 
  197#if !EIGEN_HAS_RVALUE_REFERENCES 
  205    template<
typename OtherDerived, 
int a>
 
  206    gsSparseMatrix & operator=(
const gsEigen::SparseSymmetricPermutationProduct<OtherDerived, a>& other)
 
  208        this->Base::operator=(other);
 
  213    template <
class EigenExpr>
 
  214    gsSparseMatrix& operator= (
const EigenExpr & other)
 
  216        this->Base::operator=(other);
 
  220    using Base::operator=;
 
  225    gsSparseMatrix(
const gsSparseMatrix& other) : Base(other)
 
  226    { Base::operator=(other); }
 
  227    gsSparseMatrix& operator= (
const gsSparseMatrix & other)
 
  228    { Base::operator=(other); 
return *
this; }
 
  230    gsSparseMatrix(gsSparseMatrix&& other)
 
  231    { gsSparseMatrix::operator=(std::forward<gsSparseMatrix>(other)); }
 
  233    gsSparseMatrix & operator=(gsSparseMatrix&& other)
 
  261        this->data().squeeze();
 
  264    std::pair<index_t,index_t> dim()
 const 
  265    { 
return std::make_pair(this->rows(), this->cols() ); }
 
  267    void reservePerColumn(
const index_t nz)
 
  269        Base::reserve(gsVector<index_t>::Constant(this->outerSize(), nz));
 
  272    void setFrom( gsSparseEntries<T> 
const & entries) ;
 
  274    inline T   at (_Index i, _Index j )
 const { 
return this->coeff(i,j); }
 
  275    inline T & at (_Index i, _Index j ) { 
return this->coeffRef(i,j); }
 
  277    inline T    operator () (_Index i, _Index j )
 const { 
return this->coeff(i,j); }
 
  278    inline T  & operator () (_Index i, _Index j ) { 
return this->coeffRef(i,j); }
 
  282    inline void addTo(_Index i, _Index j, 
const T val)
 
  284        if (0!=val) this->coeffRef(i,j) += val;
 
 
  289    inline void insertTo(_Index i, _Index j, 
const T val)
 
  292            this->insert(i,j) = val;
 
 
  295    inline bool isExplicitZero(_Index row, _Index col)
 const 
  297        const _Index outer = gsSparseMatrix::IsRowMajor ? row : col;
 
  298        const _Index inner = gsSparseMatrix::IsRowMajor ? col : row;
 
  299        const _Index end = this->m_innerNonZeros ?
 
  300            this->m_outerIndex[outer] + this->m_innerNonZeros[outer] : this->m_outerIndex[outer+1];
 
  301        const _Index 
id = this->m_data.searchLowerIndex(this->m_outerIndex[outer], end-1, inner);
 
  302        return !((
id<end) && ( this->m_data.index(
id)==inner));
 
  308        GISMO_ASSERT(row>=0 && row<this->rows() && col>=0 && col<this->cols(), 
"Invalid row/col index.");
 
  309        const _Index outer = gsSparseMatrix::IsRowMajor ? row : col;
 
  310        const _Index inner = gsSparseMatrix::IsRowMajor ? col : row;
 
  311        const _Index start = this->m_outerIndex[outer];
 
  312        const _Index end   = this->m_innerNonZeros ?
 
  313            this->m_outerIndex[outer] + this->m_innerNonZeros[outer] : this->m_outerIndex[outer+1];
 
  315        { this->insert(row,col); 
return; }
 
  316        const _Index p = this->m_data.searchLowerIndex(start,end-1,inner);
 
  317        if(! ((p<end) && (this->m_data.index(p)==inner)) )
 
  318            this->insert(row,col);
 
 
  321    inline T& coeffUpdate(_Index row, _Index col)
 
  323        GISMO_ASSERT(row>=0 && row<this->rows() && col>=0 && col<this->cols(), 
"Invalid row/col index.");
 
  324        const _Index outer = gsSparseMatrix::IsRowMajor ? row : col;
 
  325        _Index start = this->m_outerIndex[outer];
 
  326        _Index end = this->m_innerNonZeros ? this->m_outerIndex[outer] + this->m_innerNonZeros[outer]
 
  327            : this->m_outerIndex[outer+1];
 
  328        const _Index inner = gsSparseMatrix::IsRowMajor ? col : row;
 
  329        const _Index p = this->m_data.searchLowerIndex(start,end-1,inner);
 
  330        if((p<end) && (this->m_data.index(p)==inner))
 
  331            return this->m_data.value(p);
 
  332        GISMO_ERROR(
"(row,col) = ("<< row <<
","<<col<<
") is not in the matrix (sparsity pattern).");
 
  339        return BlockView(*
this, rowSizes, colSizes);
 
 
  354        if ( this->isCompressed() )
 
  356            gsWarn<<
"nonZerosPerCol(): Uncompressing the gsSparseMatrix.\n";
 
 
  362    std::string printSparsity()
 const 
  364        std::ostringstream os;
 
  365        os <<
"Sparsity: "<< std::fixed << std::setprecision(2)
 
  366           <<(double)100*this->nonZeros()/this->size() <<
'%'<<
", nnz: "<<this->size() <<
"\n";
 
  367        for (
index_t i = 0; i!=this->rows(); ++i)
 
  369            for (
index_t j = 0; j!=this->cols(); ++j)
 
  370                os << ( isExplicitZero(i,j) ? 
"\u00B7" :
 
  371                        ( 0 == this->coeff(i,j) ? 
"o" : 
"x") );
 
  386    template<
class container>
 
  387    container 
innerOf(
const container & outer)
 const 
  389        std::vector<bool> v(this->innerSize(), 
false);
 
  391        for (
typename container::const_iterator k =
 
  392                 outer.begin(); k!=outer.end(); ++k )
 
  393            for( mIt = this->
begin(*k); mIt; ++mIt)
 
  394                v[mIt.index()] = (0!=mIt.value());
 
  397        inner.reserve( std::count(v.begin(), v.end(), 
true) );
 
  398        std::vector<bool>::iterator it = std::find(v.begin(),v.end(), 
true);
 
  399        while (v.end() != it)
 
  401            inner.push_back(std::distance(v.begin(),it));
 
  402            it = std::find(++it,v.end(), 
true);
 
 
  409    template<
class container>
 
  411                           const container & outer,
 
 
  420    template<
class container>
 
  422                          const container & outer)
 const 
  424        const index_t nr = inner.size();
 
  425        const index_t nc = outer.size();
 
  431            for (
index_t r=0; r!=nr && it;)
 
  434                while(it && inner[r] > it.index()) ++it;
 
  435                if (it) 
while(r!=nr && inner[r] < it.index()) ++r;
 
  438                    result(r,c) = it.value();
 
 
  448        upto = math::min(upto, this->outerSize());
 
  451        for (
index_t i = 0; i != upto; ++i, ++v)
 
  452            *v = this->innerVector(i).nonZeros();
 
  459        const index_t r  = this->rows(), c = this->cols();
 
  460        const index_t ro = other.rows(), co = other.cols();
 
  462        if (0 == result.size()) 
return result;
 
  463        result.reserve(this->nonZerosPerInner()
 
  464                       .
kron(other.nonZerosPerInner()));
 
  467        for (
index_t k1=0; k1 != (gsSparseMatrix::IsRowMajor?r:c); ++k1)
 
  468            for (it1 = this->
begin(k1); it1; ++it1)
 
  469                for (
index_t k2=0; k2 != (gsSparseMatrix::IsRowMajor?ro:co); ++k2)
 
  470                    for (it2 = other.
begin(k2); it2; ++it2)
 
  472                        const index_t i = it1.row() * ro + it2.row();
 
  473                        const index_t j = it1.col() * co + it2.col();
 
  474                        result.insert(i,j) = it1.value() * it2.value();
 
  476        result.makeCompressed();
 
 
  499template<
typename T, 
int _Options, 
typename _Index> 
inline 
  500gsSparseMatrix<T, _Options, _Index>::gsSparseMatrix() : Base() { }
 
  502template<
typename T, 
int _Options, 
typename _Index> 
inline 
  503gsSparseMatrix<T, _Options, _Index>::gsSparseMatrix(_Index rows, _Index cols) : Base(rows,cols) { }
 
  505template<
typename T, 
int _Options, 
typename _Index> 
inline 
  506void gsSparseMatrix<T, _Options, _Index>::setFrom( gsSparseEntries<T> 
const & entries)
 
  507{ this->setFromTriplets(entries.begin(),entries.end() ); }
 
  509template<
typename T, 
int _Options, 
typename _Index> 
void 
  514    const index_t nr = this->rows();
 
  515    const index_t nc = this->cols();
 
  519    for (
index_t i = 0; i!=nr; ++i)
 
  527                R.tail(nc-c_j) -= R.
at(c_j) * this->row(j).tail(nc-c_j);
 
  531            c_i = 0; 
while (c_i!= nc && 0 == R.
at(c_i)) ++c_i;
 
  533            if (c_i == nc ) 
continue;
 
  534            R.tail(nc-c_i-1).array() /= R.
at(c_i);
 
  537            this->row(i) = R.sparseView();
 
  548            for( 
index_t i=0; i != c_j; i++)
 
  549                if( piv[i] > piv[i+1] )
 
  551                    std::swap(piv[i], piv[i+1]);
 
  561        for (
index_t i = 0; i!=nr; ++i)
 
  566            if (c_i == nc ) 
break;
 
  568            for (
index_t j = i+1; j!=nr; ++j) 
 
  571                if ( c_j == nc ) 
break;
 
  572                R.tail(nc-c_j) -= R.
at(c_j) * this->row(j).tail(nc-c_j);
 
  575            this->row(i) = R.sparseView();
 
 
 
  579#ifdef GISMO_WITH_PYBIND11 
  585  void pybind11_init_gsSparseMatrix(pybind11::module &m, 
const std::string & typestr)
 
  588    std::string pyclass_name = std::string(
"gsSparseMatrix") + typestr;
 
  589    pybind11::class_<Class>(m, pyclass_name.c_str(), pybind11::buffer_protocol(), pybind11::dynamic_attr())
 
  591    .def(pybind11::init<>())
 
  592    .def(pybind11::init<index_t, index_t>())
 
  594    .def(
"size",      &Class::size)
 
  595    .def(
"rows",      &Class::rows)
 
  596    .def(
"cols",      &Class::cols)
 
  600    .def(
"toDense",   &Class::toDense)
 
  609namespace gsEigen { 
namespace internal {
 
  610template<
typename T, 
int _Options, 
typename _Index>
 
  611struct traits<
gismo::gsSparseMatrix<T,_Options,_Index> >:
 
  612gsEigen::internal::traits<gsEigen::SparseMatrix<T,_Options,_Index> > { };
 
 
Creates a mapped object or data pointer to a const vector without copying data.
Definition gsAsMatrix.h:285
 
Represents a block-view of the given matrix.
Definition gsMatrixBlockView.h:32
 
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
 
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition gsMatrix.h:211
 
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix.
Definition gsSparseMatrix.h:34
 
Iterator over the non-zero entries of a sparse matrix.
Definition gsSparseMatrix.h:74
 
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
 
gsSparseMatrix kron(const gsSparseMatrix &other) const
Returns the Kronecker product of this with other.
Definition gsSparseMatrix.h:457
 
gsSparseMatrix(const gsEigen::MatrixBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition gsSparseMatrix.h:187
 
uPtr moveToPtr()
This function returns a smart pointer to the matrix. After calling it, the matrix object becomes empt...
Definition gsSparseMatrix.h:247
 
gsMatrix< T > multiplyBy(const container &inner, const container &outer, const gsMatrix< T > &other)
Definition gsSparseMatrix.h:410
 
gsAsConstVector< _Index > nonZerosPerCol()
Definition gsSparseMatrix.h:352
 
gsSparseMatrix(const gsEigen::ReturnByValue< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition gsSparseMatrix.h:195
 
memory::shared_ptr< gsSparseMatrix > Ptr
Shared pointer for gsSparseMatrix.
Definition gsSparseMatrix.h:158
 
constBlockView blockView(const gsVector< index_t > &rowSizes, const gsVector< index_t > &colSizes) const
Return a const block view of the matrix with rowSizes and colSizes.
Definition gsSparseMatrix.h:343
 
gsMatrix< T > submatrix(const container &inner, const container &outer) const
Definition gsSparseMatrix.h:421
 
memory::unique_ptr< gsSparseMatrix > uPtr
Unique pointer for gsSparseMatrix.
Definition gsSparseMatrix.h:161
 
iterator begin(const index_t outer) const
Returns an iterator to the first non-zero elemenent of column \ a outer (or row outer if the matrix i...
Definition gsSparseMatrix.h:256
 
void insertExplicitZero(_Index row, _Index col)
Adds an explicit zero, only if (row,col) is not in the matrix.
Definition gsSparseMatrix.h:306
 
void addTo(_Index i, _Index j, const T val)
Definition gsSparseMatrix.h:282
 
void rrefInPlace()
Allocates the sparsity pattern.
Definition gsSparseMatrix.h:510
 
gsEigen::SparseSelfAdjointView< Base, Lower > fullView
Definition gsSparseMatrix.h:165
 
gsSparseMatrix(const gsEigen::SparseSelfAdjointView< OtherDerived, UpLo > &other)
This constructor allows constructing a gsSparseMatrix from a selfadjoint view.
Definition gsSparseMatrix.h:182
 
gsSparseMatrix(const gsEigen::SparseMatrixBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from another sparse expression.
Definition gsSparseMatrix.h:191
 
container innerOf(const container &outer) const
Definition gsSparseMatrix.h:387
 
BlockView blockView(const gsVector< index_t > &rowSizes, const gsVector< index_t > &colSizes)
Return a block view of the matrix with rowSizes and colSizes.
Definition gsSparseMatrix.h:336
 
gsEigen::SparseSelfAdjointView< const Base, Lower > constFullView
Definition gsSparseMatrix.h:169
 
void insertTo(_Index i, _Index j, const T val)
Definition gsSparseMatrix.h:289
 
gsSparseMatrix(const gsEigen::EigenBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition gsSparseMatrix.h:178
 
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
 
#define index_t
Definition gsConfig.h:32
 
#define GISMO_ERROR(message)
Definition gsDebug.h:118
 
#define gsWarn
Definition gsDebug.h:50
 
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
 
The G+Smo namespace, containing all definitions for the library.