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)
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()) ;
74 template<
typename T,
int _Options,
typename _Index>
77 typedef gsEigen::SparseMatrix<T,_Options,_Index> SparseMatrix;
78 static const int IsRowMajor = SparseMatrix::IsRowMajor;
82 : m_values(NULL), m_indices(NULL),
83 m_end(NULL) , m_outer(0)
89 const _Index oind = mat.outerIndexPtr()[outer];
90 m_values = mat.valuePtr() + oind;
91 m_indices = mat.innerIndexPtr() + oind;
92 m_end = mat.isCompressed() ?
93 mat.innerIndexPtr() + mat.outerIndexPtr()[outer+1] :
94 mat.innerIndexPtr() + oind + mat.innerNonZeroPtr()[outer];
98 { ++m_values; ++m_indices;
return *
this; }
100 inline const T& value()
const {
return *m_values; }
101 inline T& valueRef() {
return const_cast<T&
>(*m_values); }
103 inline _Index index()
const {
return *m_indices; }
104 inline _Index outer()
const {
return m_outer; }
105 inline _Index row()
const {
return IsRowMajor ? m_outer : index(); }
106 inline _Index col()
const {
return IsRowMajor ? index() : m_outer; }
108 inline operator bool()
const {
return (m_indices < m_end); }
112 const _Index * m_indices;
113 const _Index * m_end;
139 template<
typename T,
int _Options,
typename _Index>
143 typedef gsEigen::SparseMatrix<T,_Options,_Index> Base;
148 typedef typename gsEigen::Block<Base> Block;
151 typedef typename gsEigen::Block<const Base> constBlock;
160 typedef memory::shared_ptr<gsSparseMatrix>
Ptr;
163 typedef memory::unique_ptr<gsSparseMatrix>
uPtr;
167 typedef typename gsEigen::SparseSelfAdjointView<Base, Lower>
fullView;
171 typedef typename gsEigen::SparseSelfAdjointView<const Base, Lower>
constFullView;
179 template<
typename OtherDerived>
183 template<
typename OtherDerived,
unsigned int UpLo>
188 template<
typename OtherDerived>
192 template<
typename OtherDerived>
193 gsSparseMatrix(
const gsEigen::SparseMatrixBase<OtherDerived>& other) : Base(other) { }
196 template<
typename OtherDerived>
197 gsSparseMatrix(
const gsEigen::ReturnByValue<OtherDerived>& other) : Base(other) { }
199 #if !EIGEN_HAS_RVALUE_REFERENCES
207 template<
typename OtherDerived,
int a>
208 gsSparseMatrix & operator=(
const gsEigen::SparseSymmetricPermutationProduct<OtherDerived, a>& other)
210 this->Base::operator=(other);
215 template <
class EigenExpr>
216 gsSparseMatrix& operator= (
const EigenExpr & other)
218 this->Base::operator=(other);
222 using Base::operator=;
227 gsSparseMatrix(
const gsSparseMatrix& other) : Base(other)
228 { Base::operator=(other); }
229 gsSparseMatrix& operator= (
const gsSparseMatrix & other)
230 { Base::operator=(other);
return *
this; }
232 gsSparseMatrix(gsSparseMatrix&& other)
233 { gsSparseMatrix::operator=(std::forward<gsSparseMatrix>(other)); }
235 gsSparseMatrix & operator=(gsSparseMatrix&& other)
263 this->data().squeeze();
266 std::pair<index_t,index_t> dim()
const
267 {
return std::make_pair(this->rows(), this->cols() ); }
269 void reservePerColumn(
const index_t nz)
271 Base::reserve(gsVector<index_t>::Constant(this->outerSize(), nz));
274 void setFrom( gsSparseEntries<T>
const & entries) ;
276 inline T at (_Index i, _Index j )
const {
return this->coeff(i,j); }
277 inline T & at (_Index i, _Index j ) {
return this->coeffRef(i,j); }
279 inline T operator () (_Index i, _Index j )
const {
return this->coeff(i,j); }
280 inline T & operator () (_Index i, _Index j ) {
return this->coeffRef(i,j); }
284 inline void addTo(_Index i, _Index j,
const T val)
286 if (0!=val) this->coeffRef(i,j) += val;
291 inline void insertTo(_Index i, _Index j,
const T val)
294 this->insert(i,j) = val;
301 return BlockView(*
this, rowSizes, colSizes);
316 if ( this->isCompressed() )
318 gsWarn<<
"nonZerosPerCol(): Uncompressing the gsSparseMatrix.\n";
324 std::string printSparsity()
const
326 std::ostringstream os;
327 os <<
"Sparsity: "<< std::fixed << std::setprecision(2)
328 <<(double)100*this->nonZeros()/this->size() <<
'%'<<
", nnz: "<<this->size() <<
"\n";
329 for (
index_t i = 0; i!=this->rows(); ++i)
331 for (
index_t j = 0; j!=this->cols(); ++j)
332 os<< ( 0 == this->coeff(i,j) ?
"\u00B7" :
"x");
343 template<
class container>
344 container
innerOf(
const container & outer)
const
346 std::vector<bool> v(this->innerSize(),
false);
348 for (
typename container::const_iterator k =
349 outer.begin(); k!=outer.end(); ++k )
350 for( mIt = this->
begin(*k); mIt; ++mIt)
351 v[mIt.index()] = (0!=mIt.value());
354 inner.reserve( std::count(v.begin(), v.end(),
true) );
355 std::vector<bool>::iterator it = std::find(v.begin(),v.end(),
true);
356 while (v.end() != it)
359 it = std::find(++it,v.end(),
true);
366 template<
class container>
368 const container & outer,
377 template<
class container>
379 const container & outer)
const
381 const index_t nr = inner.size();
382 const index_t nc = outer.size();
388 for (
index_t r=0; r!=nr && it;)
391 while(it && inner[r] > it.index()) ++it;
392 if (it)
while(r!=nr && inner[r] < it.index()) ++r;
395 result(r,c) = it.value();
405 upto = math::min(upto, this->outerSize());
408 for (
index_t i = 0; i != upto; ++i, ++v)
409 *v = this->innerVector(i).nonZeros();
416 const index_t r = this->rows(), c = this->cols();
417 const index_t ro = other.rows(), co = other.cols();
419 if (0 == result.size())
return result;
420 result.reserve(this->nonZerosPerInner()
421 .
kron(other.nonZerosPerInner()));
424 for (
index_t k1=0; k1 != (gsSparseMatrix::IsRowMajor?r:c); ++k1)
425 for (it1 = this->
begin(k1); it1; ++it1)
426 for (
index_t k2=0; k2 != (gsSparseMatrix::IsRowMajor?ro:co); ++k2)
427 for (it2 = other.
begin(k2); it2; ++it2)
429 const index_t i = it1.row() * ro + it2.row();
430 const index_t j = it1.col() * co + it2.col();
431 result.insert(i,j) = it1.value() * it2.value();
433 result.makeCompressed();
456 template<
typename T,
int _Options,
typename _Index>
inline
457 gsSparseMatrix<T, _Options, _Index>::gsSparseMatrix() : Base() { }
459 template<
typename T,
int _Options,
typename _Index>
inline
460 gsSparseMatrix<T, _Options, _Index>::gsSparseMatrix(_Index rows, _Index cols) : Base(rows,cols) { }
462 template<
typename T,
int _Options,
typename _Index>
inline
463 void gsSparseMatrix<T, _Options, _Index>::setFrom( gsSparseEntries<T>
const & entries)
464 { this->setFromTriplets(entries.begin(),entries.end() ); }
466 template<
typename T,
int _Options,
typename _Index>
void
467 gsSparseMatrix<T, _Options, _Index>::rrefInPlace()
469 gsMatrix<T,1,Dynamic> R;
471 const index_t nr = this->rows();
472 const index_t nc = this->cols();
474 gsVector<index_t> piv(nr);
476 for (
index_t i = 0; i!=nr; ++i)
484 R.tail(nc-c_j) -= R.at(c_j) * this->row(j).tail(nc-c_j);
488 c_i = 0;
while (c_i!= nc && 0 == R.at(c_i)) ++c_i;
490 if (c_i == nc )
continue;
491 R.tail(nc-c_i-1).array() /= R.at(c_i);
494 this->row(i) = R.sparseView();
505 for(
index_t i=0; i != c_j; i++)
506 if( piv[i] > piv[i+1] )
508 std::swap(piv[i], piv[i+1]);
518 for (
index_t i = 0; i!=nr; ++i)
523 if (c_i == nc )
break;
525 for (
index_t j = i+1; j!=nr; ++j)
528 if ( c_j == nc )
break;
529 R.tail(nc-c_j) -= R.at(c_j) * this->row(j).tail(nc-c_j);
532 this->row(i) = R.sparseView();
536 #ifdef GISMO_WITH_PYBIND11
541 namespace py = pybind11;
544 void pybind11_init_gsSparseMatrix(pybind11::module &m,
const std::string & typestr)
546 using Class = gsSparseMatrix<T>;
547 std::string pyclass_name = std::string(
"gsSparseMatrix") + typestr;
548 py::class_<Class>(m, pyclass_name.c_str(), py::buffer_protocol(), py::dynamic_attr())
551 .def(py::init<index_t, index_t>())
553 .def(
"size", &Class::size)
554 .def(
"rows", &Class::rows)
555 .def(
"cols", &Class::cols)
559 .def(
"toDense", &Class::toDense)
563 #endif // GISMO_WITH_PYBIND11
568 namespace gsEigen {
namespace internal {
569 template<
typename T,
int _Options,
typename _Index>
570 struct traits<gismo::gsSparseMatrix<T,_Options,_Index> >:
571 gsEigen::internal::traits<gsEigen::SparseMatrix<T,_Options,_Index> > { };
container innerOf(const container &outer) const
Definition: gsSparseMatrix.h:344
gsEigen::SparseSelfAdjointView< Base, Lower > fullView
Definition: gsSparseMatrix.h:167
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix...
Definition: gsSparseMatrix.h:33
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:298
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:258
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...
uPtr moveToPtr()
This function returns a smart pointer to the matrix. After calling it, the matrix object becomes empt...
Definition: gsSparseMatrix.h:249
memory::unique_ptr< gsSparseMatrix > uPtr
Unique pointer for gsSparseMatrix.
Definition: gsSparseMatrix.h:163
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:305
gsSparseMatrix(const gsEigen::SparseSelfAdjointView< OtherDerived, UpLo > &other)
This constructor allows constructing a gsSparseMatrix from a selfadjoint view.
Definition: gsSparseMatrix.h:184
#define index_t
Definition: gsConfig.h:32
gsSparseMatrix(const gsEigen::ReturnByValue< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition: gsSparseMatrix.h:197
gsSparseMatrix(const gsEigen::MatrixBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition: gsSparseMatrix.h:189
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition: gsSparseMatrix.h:140
gsAsConstVector< _Index > nonZerosPerCol()
Definition: gsSparseMatrix.h:314
gsEigen::SparseSelfAdjointView< const Base, Lower > constFullView
Definition: gsSparseMatrix.h:171
gsMatrix< T > multiplyBy(const container &inner, const container &outer, const gsMatrix< T > &other)
Definition: gsSparseMatrix.h:367
#define gsWarn
Definition: gsDebug.h:50
Iterator over the non-zero entries of a sparse matrix.
Definition: gsSparseMatrix.h:75
memory::shared_ptr< gsSparseMatrix > Ptr
Shared pointer for gsSparseMatrix.
Definition: gsSparseMatrix.h:160
void addTo(_Index i, _Index j, const T val)
Definition: gsSparseMatrix.h:284
Represents a block-view of the given matrix.
Definition: gsMatrixBlockView.h:31
gsSparseMatrix(const gsEigen::SparseMatrixBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from another sparse expression.
Definition: gsSparseMatrix.h:193
Creates a mapped object or data pointer to a const vector without copying data.
Definition: gsLinearAlgebra.h:130
gsSparseMatrix kron(const gsSparseMatrix &other) const
Returns the Kronecker product of this with other.
Definition: gsSparseMatrix.h:414
void insertTo(_Index i, _Index j, const T val)
Definition: gsSparseMatrix.h:291
gsMatrix< T > submatrix(const container &inner, const container &outer) const
Definition: gsSparseMatrix.h:378
gsSparseMatrix(const gsEigen::EigenBase< OtherDerived > &other)
This constructor allows constructing a gsSparseMatrix from Eigen expressions.
Definition: gsSparseMatrix.h:180