10 #ifndef EIGEN_SPARSEMATRIX_H
11 #define EIGEN_SPARSEMATRIX_H
46 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
63 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int DiagIndex>
77 ColsAtCompileTime = 1,
79 MaxColsAtCompileTime = 1,
84 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int DiagIndex>
86 :
public traits<Diagonal<SparseMatrix<_Scalar, _Options, _StorageIndex>, DiagIndex> >
95 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
106 using Base::operator+=;
107 using Base::operator-=;
116 using Base::IsRowMajor;
215 eigen_assert(end>=start &&
"you probably called coeffRef on a non finalized matrix");
268 #ifdef EIGEN_PARSED_BY_DOXYGEN
281 template<
class SizesType>
282 inline void reserve(
const SizesType& reserveSizes);
284 template<
class SizesType>
285 inline void reserve(
const SizesType& reserveSizes,
const typename SizesType::value_type& enableif =
289 SizesType::value_type())
294 #endif // EIGEN_PARSED_BY_DOXYGEN
296 template<
class SizesType>
301 Index totalReserveSize = 0;
309 StorageIndex count = 0;
312 newOuterIndex[j] = count;
314 totalReserveSize += reserveSizes[j];
320 StorageIndex innerNNZ = previousOuterIndex -
m_outerIndex[j];
321 for(
Index i=innerNNZ-1; i>=0; --i)
336 StorageIndex* newOuterIndex =
static_cast<StorageIndex*
>(std::malloc((
m_outerSize+1)*
sizeof(StorageIndex)));
339 StorageIndex count = 0;
342 newOuterIndex[j] = count;
344 StorageIndex toReserve = std::max<StorageIndex>(reserveSizes[j], alreadyReserved);
356 for(
Index i=innerNNZ-1; i>=0; --i)
365 std::free(newOuterIndex);
426 StorageIndex
size = internal::convert_index<StorageIndex>(
m_data.
size());
442 template<
typename InputIterators>
443 void setFromTriplets(
const InputIterators& begin,
const InputIterators& end);
445 template<
typename InputIterators,
typename DupFunctor>
446 void setFromTriplets(
const InputIterators& begin,
const InputIterators& end, DupFunctor dup_func);
450 template<
typename DupFunctor>
486 oldStart = nextOldStart;
509 prune(default_prunning_func(reference,epsilon));
519 template<
typename KeepFunc>
520 void prune(
const KeepFunc& keep = KeepFunc())
531 for(
Index i=previousStart; i<end; ++i)
556 if (this->
rows() == rows && this->
cols() == cols)
return;
569 StorageIndex *newInnerNonZeros =
static_cast<StorageIndex*
>(std::realloc(
m_innerNonZeros, (
m_outerSize + outerChange) *
sizeof(StorageIndex)));
576 else if (innerChange < 0)
599 if (outerChange == 0)
602 StorageIndex *newOuterIndex =
static_cast<StorageIndex*
>(std::realloc(
m_outerIndex, (
m_outerSize + outerChange + 1) *
sizeof(StorageIndex)));
675 template<
typename OtherDerived>
680 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
687 #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
688 EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
695 template<
typename OtherDerived,
unsigned int UpLo>
700 Base::operator=(other);
708 *
this = other.derived();
712 template<
typename OtherDerived>
722 template<
typename OtherDerived>
756 if (other.isRValue())
758 swap(other.const_cast_derived());
760 else if(
this!=&other)
762 #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
763 EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
773 Base::operator=(other);
779 #ifndef EIGEN_PARSED_BY_DOXYGEN
780 template<
typename OtherDerived>
782 {
return Base::operator=(other.
derived()); }
783 #endif // EIGEN_PARSED_BY_DOXYGEN
785 template<
typename OtherDerived>
791 s <<
"Nonzero entries:\n";
794 for (Index i=0; i<m.nonZeros(); ++i)
795 s <<
"(" << m.m_data.value(i) <<
"," << m.m_data.index(i) <<
") ";
799 for (Index i=0; i<m.outerSize(); ++i)
801 Index p = m.m_outerIndex[i];
802 Index pe = m.m_outerIndex[i]+m.m_innerNonZeros[i];
805 s <<
"(" << m.m_data.value(k) <<
"," << m.m_data.index(k) <<
") ";
807 for (; k<m.m_outerIndex[i+1]; ++k) {
814 s <<
"Outer pointers:\n";
815 for (
Index i=0; i<m.outerSize(); ++i) {
816 s << m.m_outerIndex[i] <<
" ";
818 s <<
" $" << std::endl;
819 if(!m.isCompressed())
821 s <<
"Inner non zeros:\n";
822 for (Index i=0; i<m.outerSize(); ++i) {
823 s << m.m_innerNonZeros[i] <<
" ";
825 s <<
" $" << std::endl;
829 s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m);
836 std::free(m_outerIndex);
837 std::free(m_innerNonZeros);
843 # ifdef EIGEN_SPARSEMATRIX_PLUGIN
844 # include EIGEN_SPARSEMATRIX_PLUGIN
849 template<
typename Other>
852 resize(other.rows(), other.cols());
855 std::free(m_innerNonZeros);
892 eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer]));
894 Index p = m_outerIndex[outer] + m_innerNonZeros[outer]++;
919 template<
typename InputIterator,
typename SparseMatrixType,
typename DupFunctor>
920 void set_from_triplets(
const InputIterator& begin,
const InputIterator& end, SparseMatrixType&
mat, DupFunctor dup_func)
922 enum { IsRowMajor = SparseMatrixType::IsRowMajor };
924 typedef typename SparseMatrixType::StorageIndex StorageIndex;
930 typename SparseMatrixType::IndexVector wi(trMat.
outerSize());
932 for(InputIterator it(begin); it!=end; ++it)
934 eigen_assert(it->row()>=0 && it->row()<
mat.rows() && it->col()>=0 && it->col()<
mat.cols());
935 wi(IsRowMajor ? it->col() : it->row())++;
940 for(InputIterator it(begin); it!=end; ++it)
991 template<
typename Scalar,
int _Options,
typename _StorageIndex>
992 template<
typename InputIterators>
1007 template<
typename Scalar,
int _Options,
typename _StorageIndex>
1008 template<
typename InputIterators,
typename DupFunctor>
1011 internal::set_from_triplets<InputIterators, SparseMatrix<Scalar,_Options,_StorageIndex>, DupFunctor>(begin, end, *
this, dup_func);
1015 template<
typename Scalar,
int _Options,
typename _StorageIndex>
1016 template<
typename DupFunctor>
1023 StorageIndex count = 0;
1025 for(
Index j=0; j<outerSize(); ++j)
1027 StorageIndex start = count;
1028 Index oldEnd = m_outerIndex[j]+m_innerNonZeros[j];
1029 for(
Index k=m_outerIndex[j]; k<oldEnd; ++k)
1045 m_outerIndex[j] = start;
1047 m_outerIndex[m_outerSize] = count;
1050 std::free(m_innerNonZeros);
1051 m_innerNonZeros = 0;
1052 m_data.
resize(m_outerIndex[m_outerSize]);
1055 template<
typename Scalar,
int _Options,
typename _StorageIndex>
1056 template<
typename OtherDerived>
1060 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
1062 #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
1063 EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
1067 if (needToTranspose)
1069 #ifdef EIGEN_SPARSE_TRANSPOSED_COPY_PLUGIN
1070 EIGEN_SPARSE_TRANSPOSED_COPY_PLUGIN
1079 OtherCopy otherCopy(other.
derived());
1080 OtherCopyEval otherCopyEval(otherCopy);
1087 for (
Index j=0; j<otherCopy.outerSize(); ++j)
1088 for (
typename OtherCopyEval::InnerIterator it(otherCopyEval, j); it; ++it)
1092 StorageIndex count = 0;
1098 positions[j] = count;
1105 for (StorageIndex j=0; j<otherCopy.outerSize(); ++j)
1107 for (
typename OtherCopyEval::InnerIterator it(otherCopyEval, j); it; ++it)
1109 Index pos = positions[it.index()]++;
1121 initAssignment(other.
derived());
1124 return Base::operator=(other.
derived());
1128 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
1142 m_data.
reserve(2*m_innerSize);
1145 m_innerNonZeros =
static_cast<StorageIndex*
>(std::malloc(m_outerSize *
sizeof(StorageIndex)));
1148 memset(m_innerNonZeros, 0, (m_outerSize)*
sizeof(StorageIndex));
1153 for(
Index j=1; j<=m_outerSize; ++j)
1154 m_outerIndex[j] = end;
1159 m_innerNonZeros =
static_cast<StorageIndex*
>(std::malloc(m_outerSize *
sizeof(StorageIndex)));
1161 for(
Index j=0; j<m_outerSize; ++j)
1162 m_innerNonZeros[j] = m_outerIndex[j+1]-m_outerIndex[j];
1171 if(m_outerIndex[outer]==data_end)
1179 while(j>=0 && m_innerNonZeros[j]==0)
1180 m_outerIndex[j--] = p;
1183 ++m_innerNonZeros[outer];
1194 for(
Index k=outer+1; k<=m_outerSize; ++k)
1195 if(m_outerIndex[k]==data_end)
1196 m_outerIndex[k] = new_end;
1198 return m_data.
value(p);
1203 if(m_outerIndex[outer+1]==data_end && m_outerIndex[outer]+m_innerNonZeros[outer]==m_data.
size())
1208 ++m_innerNonZeros[outer];
1219 for(
Index k=outer+1; k<=m_outerSize; ++k)
1220 if(m_outerIndex[k]==data_end)
1221 m_outerIndex[k] = new_end;
1225 Index startId = m_outerIndex[outer];
1226 Index p = m_outerIndex[outer]+m_innerNonZeros[outer]-1;
1227 while ( (p > startId) && (m_data.
index(p-1) > inner) )
1235 return (m_data.
value(p) = 0);
1245 return insertUncompressed(
row,
col);
1248 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
1256 Index room = m_outerIndex[outer+1] - m_outerIndex[outer];
1257 StorageIndex innerNNZ = m_innerNonZeros[outer];
1261 reserve(SingletonVector(outer,std::max<StorageIndex>(2,innerNNZ)));
1264 Index startId = m_outerIndex[outer];
1265 Index p = startId + m_innerNonZeros[outer];
1266 while ( (p > startId) && (m_data.
index(p-1) > inner) )
1272 eigen_assert((p<=startId || m_data.
index(p-1)!=inner) &&
"you cannot insert an element that already exists, you must call coeffRef to this end");
1274 m_innerNonZeros[outer]++;
1276 m_data.
index(p) = inner;
1280 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
1288 Index previousOuter = outer;
1289 if (m_outerIndex[outer+1]==0)
1292 while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
1297 m_outerIndex[outer+1] = m_outerIndex[outer];
1303 bool isLastVec = (!(previousOuter==-1 && m_data.
size()!=0))
1304 && (std::size_t(m_outerIndex[outer+1]) == m_data.
size());
1306 std::size_t startId = m_outerIndex[outer];
1308 std::size_t p = m_outerIndex[outer+1];
1309 ++m_outerIndex[outer+1];
1311 double reallocRatio = 1;
1315 if (m_data.
size()==0)
1324 double nnzEstimate = double(m_outerIndex[outer])*double(m_outerSize)/double(outer+1);
1325 reallocRatio = (nnzEstimate-double(m_data.
size()))/
double(m_data.
size());
1336 if (previousOuter==-1)
1340 for (
Index k=0; k<=(outer+1); ++k)
1341 m_outerIndex[k] = 0;
1343 while(m_outerIndex[k]==0)
1344 m_outerIndex[k++] = 1;
1345 while (k<=m_outerSize && m_outerIndex[k]!=0)
1346 m_outerIndex[k++]++;
1349 k = m_outerIndex[k]-1;
1362 while (j<=m_outerSize && m_outerIndex[j]!=0)
1363 m_outerIndex[j++]++;
1366 Index k = m_outerIndex[j]-1;
1376 while ( (p > startId) && (m_data.
index(p-1) > inner) )
1383 m_data.
index(p) = inner;
1389 template<
typename _Scalar,
int _Options,
typename _StorageIndex>
1391 :
evaluator<SparseCompressedBase<SparseMatrix<_Scalar,_Options,_StorageIndex> > >
1403 #endif // EIGEN_SPARSEMATRIX_H