10#ifndef EIGEN_RANDOMSETTER_H
11#define EIGEN_RANDOMSETTER_H
13#if defined(EIGEN_GOOGLEHASH_SUPPORT)
28 typedef std::map<KeyType,Scalar> Type;
33 static void setInvalidKey(Type&,
const KeyType&) {}
36#ifdef EIGEN_UNORDERED_MAP_SUPPORT
53template<
typename Scalar>
struct StdUnorderedMapTraits
56 typedef std::unordered_map<KeyType,Scalar> Type;
61 static void setInvalidKey(Type&,
const KeyType&) {}
65#if defined(EIGEN_GOOGLEHASH_SUPPORT)
71using namespace ::google;
73template<
typename KeyType,
typename Scalar>
75 typedef dense_hash_map<KeyType, Scalar> type;
78template<
typename KeyType,
typename Scalar>
80 typedef sparse_hash_map<KeyType, Scalar> type;
89template<
typename Scalar>
struct GoogleDenseHashMapTraits
92 typedef typename google::DenseHashMap<KeyType,Scalar>::type Type;
97 static void setInvalidKey(Type& map,
const KeyType& k)
98 { map.set_empty_key(k); }
105template<
typename Scalar>
struct GoogleSparseHashMapTraits
108 typedef typename google::SparseHashMap<KeyType,Scalar>::type Type;
113 static void setInvalidKey(Type&,
const KeyType&) {}
166template<
typename SparseMatrixType,
167 template <
typename T>
class MapTraits =
168#if defined(EIGEN_GOOGLEHASH_SUPPORT)
169 GoogleDenseHashMapTraits
170#elif defined(_HASH_MAP)
175 ,
int OuterPacketBits = 6>
178 typedef typename SparseMatrixType::Scalar Scalar;
179 typedef typename SparseMatrixType::StorageIndex StorageIndex;
183 ScalarWrapper() : value(0) {}
186 typedef typename MapTraits<ScalarWrapper>::KeyType KeyType;
187 typedef typename MapTraits<ScalarWrapper>::Type HashMapType;
188 static const int OuterPacketMask = (1 << OuterPacketBits) - 1;
190 SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,
191 TargetRowMajor = (SparseMatrixType::Flags &
RowMajorBit) ? 1 : 0,
192 SetterRowMajor = SwapStorage ? 1-TargetRowMajor : TargetRowMajor
206 const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize();
207 const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize();
208 m_outerPackets = outerSize >> OuterPacketBits;
209 if (outerSize&OuterPacketMask)
211 m_hashmaps =
new HashMapType[m_outerPackets];
213 Index aux = innerSize - 1;
220 KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset));
221 for (
Index k=0; k<m_outerPackets; ++k)
222 MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k],ik);
225 for (
Index j=0; j<mp_target->outerSize(); ++j)
226 for (
typename SparseMatrixType::InnerIterator it(*mp_target,j); it; ++it)
227 (*
this)(TargetRowMajor?j:it.index(), TargetRowMajor?it.index():j) = it.value();
233 KeyType keyBitsMask = (1<<m_keyBitsOffset)-1;
236 mp_target->setZero();
237 mp_target->makeCompressed();
239 Index prevOuter = -1;
240 for (
Index k=0; k<m_outerPackets; ++k)
242 const Index outerOffset = (1<<OuterPacketBits) * k;
243 typename HashMapType::iterator end = m_hashmaps[k].end();
244 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
246 const Index outer = (it->first >> m_keyBitsOffset) + outerOffset;
247 const Index inner = it->first & keyBitsMask;
248 if (prevOuter!=outer)
250 for (
Index j=prevOuter+1;j<=outer;++j)
251 mp_target->startVec(j);
254 mp_target->insertBackByOuterInner(outer, inner) = it->second.value;
257 mp_target->finalize();
261 VectorXi positions(mp_target->outerSize());
264 for (
Index k=0; k<m_outerPackets; ++k)
266 typename HashMapType::iterator end = m_hashmaps[k].end();
267 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
269 const Index outer = it->first & keyBitsMask;
274 StorageIndex count = 0;
275 for (
Index j=0; j<mp_target->outerSize(); ++j)
277 StorageIndex tmp = positions[j];
278 mp_target->outerIndexPtr()[j] = count;
279 positions[j] = count;
282 mp_target->makeCompressed();
283 mp_target->outerIndexPtr()[mp_target->outerSize()] = count;
284 mp_target->resizeNonZeros(count);
286 for (
Index k=0; k<m_outerPackets; ++k)
288 const Index outerOffset = (1<<OuterPacketBits) * k;
289 typename HashMapType::iterator end = m_hashmaps[k].end();
290 for (
typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
292 const Index inner = (it->first >> m_keyBitsOffset) + outerOffset;
293 const Index outer = it->first & keyBitsMask;
298 Index posStart = mp_target->outerIndexPtr()[outer];
299 Index i = (positions[outer]++) - 1;
300 while ( (i >= posStart) && (mp_target->innerIndexPtr()[i] > inner) )
302 mp_target->valuePtr()[i+1] = mp_target->valuePtr()[i];
303 mp_target->innerIndexPtr()[i+1] = mp_target->innerIndexPtr()[i];
306 mp_target->innerIndexPtr()[i+1] = internal::convert_index<StorageIndex>(inner);
307 mp_target->valuePtr()[i+1] = it->second.value;
317 const Index outer = SetterRowMajor ? row : col;
318 const Index inner = SetterRowMajor ? col : row;
319 const Index outerMajor = outer >> OuterPacketBits;
320 const Index outerMinor = outer & OuterPacketMask;
321 const KeyType key = internal::convert_index<KeyType>((outerMinor<<m_keyBitsOffset) | inner);
322 return m_hashmaps[outerMajor][key].value;
333 for (
Index k=0; k<m_outerPackets; ++k)
334 nz +=
static_cast<Index>(m_hashmaps[k].size());
341 HashMapType* m_hashmaps;
342 SparseMatrixType* mp_target;
343 Index m_outerPackets;
344 unsigned char m_keyBitsOffset;
The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access.
Definition: RandomSetter.h:177
~RandomSetter()
Definition: RandomSetter.h:231
RandomSetter(SparseMatrixType &target)
Definition: RandomSetter.h:203
Scalar & operator()(Index row, Index col)
Definition: RandomSetter.h:315
Index nonZeros() const
Definition: RandomSetter.h:330
const unsigned int RowMajorBit
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
Definition: RandomSetter.h:26