25 #ifndef EIGEN_SPARSEMATRIX_H
26 #define EIGEN_SPARSEMATRIX_H
57 template<
typename _Scalar,
int _Options,
typename _Index>
58 struct traits<SparseMatrix<_Scalar, _Options, _Index> >
60 typedef _Scalar Scalar;
62 typedef Sparse StorageKind;
63 typedef MatrixXpr XprKind;
75 template<
typename _Scalar,
int _Options,
typename _Index,
int DiagIndex>
76 struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
78 typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType;
79 typedef typename nested<MatrixType>::type MatrixTypeNested;
80 typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
82 typedef _Scalar Scalar;
83 typedef Dense StorageKind;
85 typedef MatrixXpr XprKind;
89 ColsAtCompileTime = 1,
91 MaxColsAtCompileTime = 1,
93 CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10
99 template<
typename _Scalar,
int _Options,
typename _Index>
209 eigen_assert(end>=start &&
"you probably called coeffRef on a non finalized matrix");
212 const Index p =
m_data.searchLowerIndex(start,end-1,inner);
213 if((p<end) && (
m_data.index(p)==inner))
243 class ReverseInnerIterator;
268 m_data.reserve(reserveSize);
271 #ifdef EIGEN_PARSED_BY_DOXYGEN
275 template<
class SizesType>
276 inline void reserve(
const SizesType& reserveSizes);
278 template<
class SizesType>
279 inline void reserve(
const SizesType& reserveSizes,
const typename SizesType::value_type& enableif =
typename SizesType::value_type())
284 template<
class SizesType>
285 inline void reserve(
const SizesType& reserveSizes,
const typename SizesType::Scalar& enableif =
typename SizesType::Scalar())
290 #endif // EIGEN_PARSED_BY_DOXYGEN
292 template<
class SizesType>
298 std::size_t totalReserveSize = 0;
308 newOuterIndex[j] = count;
310 totalReserveSize += reserveSizes[j];
312 m_data.reserve(totalReserveSize);
314 for(std::ptrdiff_t j=m_outerSize-1; j>=0; --j)
316 ptrdiff_t innerNNZ = previousOuterIndex -
m_outerIndex[j];
317 for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i)
319 m_data.index(newOuterIndex[j]+i) =
m_data.index(m_outerIndex[j]+i);
320 m_data.value(newOuterIndex[j]+i) =
m_data.value(m_outerIndex[j]+i);
322 previousOuterIndex = m_outerIndex[j];
323 m_outerIndex[j] = newOuterIndex[j];
336 newOuterIndex[j] = count;
338 Index toReserve = std::max<std::ptrdiff_t>(reserveSizes[j], alreadyReserved);
344 for(ptrdiff_t j=m_outerSize-1; j>=0; --j)
346 std::ptrdiff_t offset = newOuterIndex[j] -
m_outerIndex[j];
350 for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i)
352 m_data.index(newOuterIndex[j]+i) =
m_data.index(m_outerIndex[j]+i);
353 m_data.value(newOuterIndex[j]+i) =
m_data.value(m_outerIndex[j]+i);
359 delete[] newOuterIndex;
436 template<
typename InputIterators>
437 void setFromTriplets(
const InputIterators& begin,
const InputIterators& end);
467 m_data.index(m_outerIndex[j]+k) =
m_data.index(oldStart+k);
468 m_data.value(m_outerIndex[j]+k) =
m_data.value(oldStart+k);
472 oldStart = nextOldStart;
483 prune(default_prunning_func(reference,epsilon));
493 template<
typename KeepFunc>
494 void prune(
const KeepFunc& keep = KeepFunc())
506 for(
Index i=previousStart; i<end; ++i)
557 check_template_parameters();
565 check_template_parameters();
570 template<
typename OtherDerived>
574 check_template_parameters();
582 check_template_parameters();
620 #ifndef EIGEN_PARSED_BY_DOXYGEN
621 template<
typename Lhs,
typename Rhs>
625 template<
typename OtherDerived>
629 template<
typename OtherDerived>
634 template<
typename OtherDerived>
645 typedef typename internal::nested<OtherDerived,2>::type OtherCopy;
646 typedef typename internal::remove_all<OtherCopy>::type _OtherCopy;
647 OtherCopy otherCopy(other.
derived());
652 for (
Index j=0; j<otherCopy.outerSize(); ++j)
653 for (
typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
654 ++m_outerIndex[it.index()];
661 Index tmp = m_outerIndex[j];
662 m_outerIndex[j] = count;
663 positions[j] = count;
670 for (
Index j=0; j<otherCopy.outerSize(); ++j)
672 for (
typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
674 Index pos = positions[it.index()]++;
676 m_data.value(pos) = it.value();
691 s <<
"Nonzero entries:\n";
694 s <<
"(" << m.
m_data.value(i) <<
"," << m.
m_data.index(i) <<
") ";
702 s <<
"(" << m.
m_data.value(k) <<
"," << m.
m_data.index(k) <<
") ";
708 s <<
"Outer pointers:\n";
711 s <<
" $" << std::endl;
714 s <<
"Inner non zeros:\n";
717 s <<
" $" << std::endl;
721 s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m);
732 #ifndef EIGEN_PARSED_BY_DOXYGEN
737 # ifdef EIGEN_SPARSEMATRIX_PLUGIN
738 # include EIGEN_SPARSEMATRIX_PLUGIN
743 template<
typename Other>
746 resize(other.rows(), other.cols());
763 Index previousOuter = outer;
767 while (previousOuter>=0 &&
m_outerIndex[previousOuter]==0)
778 bool isLastVec = (!(previousOuter==-1 &&
m_data.size()!=0))
786 float reallocRatio = 1;
800 reallocRatio = (nnzEstimate-float(
m_data.size()))/float(
m_data.size());
804 reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f);
811 if (previousOuter==-1)
815 for (
Index k=0; k<=(outer+1); ++k)
851 while ( (p > startId) && (
m_data.index(p-1) > inner) )
859 return (
m_data.value(p) = 0);
871 : m_index(i), m_value(v)
891 reserve(SingletonVector(outer,std::max<std::ptrdiff_t>(2,innerNNZ)));
894 Index startId = m_outerIndex[outer];
896 while ( (p > startId) && (
m_data.index(p-1) > inner) )
903 m_innerNonZeros[outer]++;
906 return (
m_data.value(p) = 0);
921 m_innerNonZeros[outer]++;
923 return (
m_data.value(p) = 0);
927 static void check_template_parameters()
932 struct default_prunning_func {
933 default_prunning_func(
Scalar ref, RealScalar eps) : reference(ref), epsilon(eps) {}
934 inline bool operator() (
const Index&,
const Index&,
const Scalar& value)
const
943 template<
typename Scalar,
int _Options,
typename _Index>
944 class SparseMatrix<Scalar,_Options,_Index>::InnerIterator
950 if(mat.isCompressed())
951 m_end = mat.m_outerIndex[outer+1];
953 m_end = m_id + mat.m_innerNonZeros[outer];
956 inline InnerIterator& operator++() { m_id++;
return *
this; }
958 inline const Scalar& value()
const {
return m_values[m_id]; }
959 inline Scalar& valueRef() {
return const_cast<Scalar&
>(m_values[m_id]); }
961 inline Index index()
const {
return m_indices[m_id]; }
962 inline Index outer()
const {
return m_outer; }
966 inline operator bool()
const {
return (m_id < m_end); }
970 const Index* m_indices;
976 template<
typename Scalar,
int _Options,
typename _Index>
977 class SparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator
983 if(mat.isCompressed())
984 m_id = mat.m_outerIndex[outer+1];
986 m_id = m_start + mat.m_innerNonZeros[outer];
989 inline ReverseInnerIterator& operator--() { --m_id;
return *
this; }
991 inline const Scalar& value()
const {
return m_values[m_id-1]; }
992 inline Scalar& valueRef() {
return const_cast<Scalar&
>(m_values[m_id-1]); }
994 inline Index index()
const {
return m_indices[m_id-1]; }
995 inline Index outer()
const {
return m_outer; }
999 inline operator bool()
const {
return (m_id > m_start); }
1003 const Index* m_indices;
1004 const Index m_outer;
1006 const Index m_start;
1009 namespace internal {
1011 template<
typename InputIterator,
typename SparseMatrixType>
1012 void set_from_triplets(
const InputIterator& begin,
const InputIterator& end, SparseMatrixType& mat,
int Options = 0)
1015 enum { IsRowMajor = SparseMatrixType::IsRowMajor };
1016 typedef typename SparseMatrixType::Scalar Scalar;
1017 typedef typename SparseMatrixType::Index Index;
1023 for(InputIterator it(begin); it!=end; ++it)
1024 wi(IsRowMajor ? it->col() : it->row())++;
1028 for(InputIterator it(begin); it!=end; ++it)
1029 trMat.insertBackUncompressed(it->row(),it->col()) = it->value();
1032 trMat.sumupDuplicates();
1078 template<
typename Scalar,
int _Options,
typename _Index>
1079 template<
typename InputIterators>
1086 template<
typename Scalar,
int _Options,
typename _Index>
1095 for(
int j=0; j<outerSize(); ++j)
1097 Index start = count;
1098 Index oldEnd = m_outerIndex[j]+m_innerNonZeros[j];
1099 for(Index k=m_outerIndex[j]; k<oldEnd; ++k)
1101 Index i = m_data.index(k);
1105 m_data.value(wi(i)) += m_data.value(k);
1109 m_data.value(count) = m_data.value(k);
1110 m_data.index(count) = m_data.index(k);
1115 m_outerIndex[j] = start;
1117 m_outerIndex[m_outerSize] = count;
1120 delete[] m_innerNonZeros;
1121 m_innerNonZeros = 0;
1122 m_data.
resize(m_outerIndex[m_outerSize]);
1127 #endif // EIGEN_SPARSEMATRIX_H