10 #ifndef EIGEN_RANDOMSETTER_H
11 #define EIGEN_RANDOMSETTER_H
13 #if defined(EIGEN_GOOGLEHASH_SUPPORT)
19 #include "./InternalHeaderCheck.h"
30 typedef std::map<KeyType,Scalar> Type;
35 static void setInvalidKey(Type&,
const KeyType&) {}
45 typedef std::unordered_map<KeyType,Scalar> Type;
50 static void setInvalidKey(Type&,
const KeyType&) {}
53 #if defined(EIGEN_GOOGLEHASH_SUPPORT)
59 using namespace ::google;
61 template<
typename KeyType,
typename Scalar>
63 typedef dense_hash_map<KeyType, Scalar> type;
66 template<
typename KeyType,
typename Scalar>
67 struct SparseHashMap {
68 typedef sparse_hash_map<KeyType, Scalar> type;
77 template<
typename Scalar>
struct GoogleDenseHashMapTraits
80 typedef typename google::DenseHashMap<KeyType,Scalar>::type Type;
85 static void setInvalidKey(Type& map,
const KeyType& k)
86 { map.set_empty_key(k); }
93 template<
typename Scalar>
struct GoogleSparseHashMapTraits
96 typedef typename google::SparseHashMap<KeyType,Scalar>::type Type;
101 static void setInvalidKey(Type&,
const KeyType&) {}
154 template<
typename SparseMatrixType,
155 template <
typename T>
class MapTraits =
156 #if defined(EIGEN_GOOGLEHASH_SUPPORT)
157 GoogleDenseHashMapTraits
159 StdUnorderedMapTraits
161 ,
int OuterPacketBits = 6>
164 typedef typename SparseMatrixType::Scalar Scalar;
165 typedef typename SparseMatrixType::StorageIndex StorageIndex;
169 ScalarWrapper() : value(0) {}
172 typedef typename MapTraits<ScalarWrapper>::KeyType KeyType;
173 typedef typename MapTraits<ScalarWrapper>::Type HashMapType;
174 static constexpr
int OuterPacketMask = (1 << OuterPacketBits) - 1;
176 SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,
177 TargetRowMajor = (SparseMatrixType::Flags &
RowMajorBit) ? 1 : 0,
178 SetterRowMajor = SwapStorage ? 1-TargetRowMajor : TargetRowMajor
192 const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize();
193 const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize();
194 m_outerPackets = outerSize >> OuterPacketBits;
195 if (outerSize&OuterPacketMask)
197 m_hashmaps =
new HashMapType[m_outerPackets];
199 Index aux = innerSize - 1;
206 KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset));
207 for (
Index k=0; k<m_outerPackets; ++k)
208 MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k],ik);
211 for (
Index j=0; j<mp_target->outerSize(); ++j)
212 for (
typename SparseMatrixType::InnerIterator it(*mp_target,j); it; ++it)
213 (*
this)(TargetRowMajor?j:it.index(), TargetRowMajor?it.index():j) = it.value();
219 KeyType keyBitsMask = (1<<m_keyBitsOffset)-1;
222 mp_target->setZero();
223 mp_target->makeCompressed();
225 Index prevOuter = -1;
226 for (
Index k=0; k<m_outerPackets; ++k)
228 const Index outerOffset = (1<<OuterPacketBits) * k;
229 typename HashMapType::iterator
end = m_hashmaps[k].end();
230 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=
end; ++it)
232 const Index outer = (it->first >> m_keyBitsOffset) + outerOffset;
233 const Index inner = it->first & keyBitsMask;
234 if (prevOuter!=outer)
236 for (
Index j=prevOuter+1;j<=outer;++j)
237 mp_target->startVec(j);
240 mp_target->insertBackByOuterInner(outer, inner) = it->second.value;
243 mp_target->finalize();
247 VectorXi positions(mp_target->outerSize());
250 for (
Index k=0; k<m_outerPackets; ++k)
252 typename HashMapType::iterator
end = m_hashmaps[k].end();
253 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=
end; ++it)
255 const Index outer = it->first & keyBitsMask;
260 StorageIndex count = 0;
261 for (
Index j=0; j<mp_target->outerSize(); ++j)
263 StorageIndex tmp = positions[j];
264 mp_target->outerIndexPtr()[j] = count;
265 positions[j] = count;
268 mp_target->makeCompressed();
269 mp_target->outerIndexPtr()[mp_target->outerSize()] = count;
270 mp_target->resizeNonZeros(count);
272 for (
Index k=0; k<m_outerPackets; ++k)
274 const Index outerOffset = (1<<OuterPacketBits) * k;
275 typename HashMapType::iterator
end = m_hashmaps[k].end();
276 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=
end; ++it)
278 const Index inner = (it->first >> m_keyBitsOffset) + outerOffset;
279 const Index outer = it->first & keyBitsMask;
284 Index posStart = mp_target->outerIndexPtr()[outer];
285 Index i = (positions[outer]++) - 1;
286 while ( (i >= posStart) && (mp_target->innerIndexPtr()[i] > inner) )
288 mp_target->valuePtr()[i+1] = mp_target->valuePtr()[i];
289 mp_target->innerIndexPtr()[i+1] = mp_target->innerIndexPtr()[i];
292 mp_target->innerIndexPtr()[i+1] = internal::convert_index<StorageIndex>(inner);
293 mp_target->valuePtr()[i+1] = it->second.value;
303 const Index outer = SetterRowMajor ? row : col;
304 const Index inner = SetterRowMajor ? col : row;
305 const Index outerMajor = outer >> OuterPacketBits;
306 const Index outerMinor = outer & OuterPacketMask;
307 const KeyType key = internal::convert_index<KeyType>((outerMinor<<m_keyBitsOffset) | inner);
308 return m_hashmaps[outerMajor][key].value;
319 for (
Index k=0; k<m_outerPackets; ++k)
320 nz +=
static_cast<Index>(m_hashmaps[k].size());
327 HashMapType* m_hashmaps;
328 SparseMatrixType* mp_target;
329 Index m_outerPackets;
330 unsigned char m_keyBitsOffset;
Matrix< Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_ > & setZero(Index size)
The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access.
Definition: RandomSetter.h:163
~RandomSetter()
Definition: RandomSetter.h:217
RandomSetter(SparseMatrixType &target)
Definition: RandomSetter.h:189
Scalar & operator()(Index row, Index col)
Definition: RandomSetter.h:301
Index nonZeros() const
Definition: RandomSetter.h:316
static const lastp1_t end
const unsigned int RowMajorBit
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
Definition: RandomSetter.h:28
Definition: RandomSetter.h:43