10 #ifndef EIGEN_RANDOMSETTER_H 11 #define EIGEN_RANDOMSETTER_H 13 #if defined(EIGEN_GOOGLEHASH_SUPPORT) 20 #include "./InternalHeaderCheck.h" 28 template <
typename Scalar>
31 typedef std::map<KeyType, Scalar> Type;
32 enum { IsSorted = 1 };
34 static void setInvalidKey(Type&,
const KeyType&) {}
40 template <
typename Scalar>
43 typedef std::unordered_map<KeyType, Scalar> Type;
44 enum { IsSorted = 0 };
46 static void setInvalidKey(Type&,
const KeyType&) {}
49 #if defined(EIGEN_GOOGLEHASH_SUPPORT) 55 using namespace ::google;
57 template <
typename KeyType,
typename Scalar>
59 typedef dense_hash_map<KeyType, Scalar> type;
62 template <
typename KeyType,
typename Scalar>
63 struct SparseHashMap {
64 typedef sparse_hash_map<KeyType, Scalar> type;
73 template <
typename Scalar>
74 struct GoogleDenseHashMapTraits {
76 typedef typename google::DenseHashMap<KeyType, Scalar>::type Type;
77 enum { IsSorted = 0 };
79 static void setInvalidKey(Type& map,
const KeyType& k) { map.set_empty_key(k); }
86 template <
typename Scalar>
87 struct GoogleSparseHashMapTraits {
89 typedef typename google::SparseHashMap<KeyType, Scalar>::type Type;
90 enum { IsSorted = 0 };
92 static void setInvalidKey(Type&,
const KeyType&) {}
147 template <
typename SparseMatrixType,
148 template <
typename T>
class MapTraits =
149 #if defined(EIGEN_GOOGLEHASH_SUPPORT) 150 GoogleDenseHashMapTraits
152 StdUnorderedMapTraits
155 int OuterPacketBits = 6>
157 typedef typename SparseMatrixType::Scalar Scalar;
158 typedef typename SparseMatrixType::StorageIndex StorageIndex;
160 struct ScalarWrapper {
161 ScalarWrapper() : value(0) {}
164 typedef typename MapTraits<ScalarWrapper>::KeyType KeyType;
165 typedef typename MapTraits<ScalarWrapper>::Type HashMapType;
166 static constexpr
int OuterPacketMask = (1 << OuterPacketBits) - 1;
168 SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,
169 TargetRowMajor = (SparseMatrixType::Flags &
RowMajorBit) ? 1 : 0,
170 SetterRowMajor = SwapStorage ? 1 - TargetRowMajor : TargetRowMajor
181 const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize();
182 const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize();
183 m_outerPackets = outerSize >> OuterPacketBits;
184 if (outerSize & OuterPacketMask) m_outerPackets += 1;
185 m_hashmaps =
new HashMapType[m_outerPackets];
187 Index aux = innerSize - 1;
193 KeyType ik = (1 << (OuterPacketBits + m_keyBitsOffset));
194 for (
Index k = 0; k < m_outerPackets; ++k) MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k], ik);
197 for (
Index j = 0; j < mp_target->outerSize(); ++j)
198 for (
typename SparseMatrixType::InnerIterator it(*mp_target, j); it; ++it)
199 (*
this)(TargetRowMajor ? j : it.index(), TargetRowMajor ? it.index() : j) = it.value();
204 KeyType keyBitsMask = (1 << m_keyBitsOffset) - 1;
207 mp_target->setZero();
208 mp_target->makeCompressed();
210 Index prevOuter = -1;
211 for (
Index k = 0; k < m_outerPackets; ++k) {
212 const Index outerOffset = (1 << OuterPacketBits) * k;
213 typename HashMapType::iterator
end = m_hashmaps[k].end();
214 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it !=
end; ++it) {
215 const Index outer = (it->first >> m_keyBitsOffset) + outerOffset;
216 const Index inner = it->first & keyBitsMask;
217 if (prevOuter != outer) {
218 for (
Index j = prevOuter + 1; j <= outer; ++j) mp_target->startVec(j);
221 mp_target->insertBackByOuterInner(outer, inner) = it->second.value;
224 mp_target->finalize();
226 VectorXi positions(mp_target->outerSize());
229 for (
Index k = 0; k < m_outerPackets; ++k) {
230 typename HashMapType::iterator
end = m_hashmaps[k].end();
231 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it !=
end; ++it) {
232 const Index outer = it->first & keyBitsMask;
237 StorageIndex count = 0;
238 for (
Index j = 0; j < mp_target->outerSize(); ++j) {
239 StorageIndex tmp = positions[j];
240 mp_target->outerIndexPtr()[j] = count;
241 positions[j] = count;
244 mp_target->makeCompressed();
245 mp_target->outerIndexPtr()[mp_target->outerSize()] = count;
246 mp_target->resizeNonZeros(count);
248 for (
Index k = 0; k < m_outerPackets; ++k) {
249 const Index outerOffset = (1 << OuterPacketBits) * k;
250 typename HashMapType::iterator
end = m_hashmaps[k].end();
251 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it !=
end; ++it) {
252 const Index inner = (it->first >> m_keyBitsOffset) + outerOffset;
253 const Index outer = it->first & keyBitsMask;
258 Index posStart = mp_target->outerIndexPtr()[outer];
259 Index i = (positions[outer]++) - 1;
260 while ((i >= posStart) && (mp_target->innerIndexPtr()[i] > inner)) {
261 mp_target->valuePtr()[i + 1] = mp_target->valuePtr()[i];
262 mp_target->innerIndexPtr()[i + 1] = mp_target->innerIndexPtr()[i];
265 mp_target->innerIndexPtr()[i + 1] = internal::convert_index<StorageIndex>(inner);
266 mp_target->valuePtr()[i + 1] = it->second.value;
275 const Index outer = SetterRowMajor ? row : col;
276 const Index inner = SetterRowMajor ? col : row;
277 const Index outerMajor = outer >> OuterPacketBits;
278 const Index outerMinor = outer & OuterPacketMask;
279 const KeyType key = internal::convert_index<KeyType>((outerMinor << m_keyBitsOffset) | inner);
280 return m_hashmaps[outerMajor][key].value;
290 for (
Index k = 0; k < m_outerPackets; ++k) nz += static_cast<Index>(m_hashmaps[k].size());
295 HashMapType* m_hashmaps;
296 SparseMatrixType* mp_target;
297 Index m_outerPackets;
298 unsigned char m_keyBitsOffset;
303 #endif // EIGEN_RANDOMSETTER_H static constexpr lastp1_t end
Scalar & operator()(Index row, Index col)
Definition: RandomSetter.h:274
RandomSetter(SparseMatrixType &target)
Definition: RandomSetter.h:180
Definition: RandomSetter.h:29
Namespace containing all symbols from the Eigen library.
Index nonZeros() const
Definition: RandomSetter.h:288
const unsigned int RowMajorBit
Matrix< Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_ > & setZero(Index size)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access...
Definition: RandomSetter.h:156
~RandomSetter()
Definition: RandomSetter.h:203
Definition: RandomSetter.h:41