diff --git a/Eigen/Sparse b/Eigen/Sparse index 0e5da9c3a..2364c6fe4 100644 --- a/Eigen/Sparse +++ b/Eigen/Sparse @@ -67,6 +67,7 @@ namespace Eigen { #include "src/Sparse/SparseMatrixBase.h" #include "src/Sparse/SparseArray.h" #include "src/Sparse/AmbiVector.h" +#include "src/Sparse/RandomSetter.h" #include "src/Sparse/SparseBlock.h" #include "src/Sparse/SparseMatrix.h" #include "src/Sparse/HashMatrix.h" diff --git a/Eigen/src/Sparse/RandomSetter.h b/Eigen/src/Sparse/RandomSetter.h new file mode 100644 index 000000000..efe8ba2db --- /dev/null +++ b/Eigen/src/Sparse/RandomSetter.h @@ -0,0 +1,125 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_RANDOMSETTER_H +#define EIGEN_RANDOMSETTER_H + +template struct StdMapTraits +{ + typedef int KeyType; + typedef std::map Type; + + static void setInvalidKey(Type&, const KeyType&) {} +}; + +#ifdef _HASH_MAP +template struct GnuHashMapTraits +{ + typedef int KeyType; + typedef __gnu_cxx::hash_map Type; + + static void setInvalidKey(Type&, const KeyType&) {} +}; +#endif + +#ifdef _DENSE_HASH_MAP_H_ +template struct GoogleDenseHashMapTraits +{ + typedef int KeyType; + typedef google::dense_hash_map Type; + + static void setInvalidKey(Type& map, const KeyType& k) + { map.set_empty_key(k); } +}; +#endif + +#ifdef _SPARSE_HASH_MAP_H_ +template struct GoogleSparseHashMapTraits +{ + typedef int KeyType; + typedef google::sparse_hash_map Type; + + static void setInvalidKey(Type&, const KeyType&) {} +}; +#endif + +/** \class RandomSetter + * + */ +template class HashMapTraits = StdMapTraits, + int OuterPacketBits = 6> +class RandomSetter +{ + typedef typename ei_traits::Scalar Scalar; + struct ScalarWrapper + { + ScalarWrapper() : value(0) {} + Scalar value; + }; + typedef typename HashMapTraits::KeyType KeyType; + typedef typename HashMapTraits::Type HashMapType; + static const int OuterPacketMask = (1 << OuterPacketBits) - 1; + enum { + RowMajor = SparseMatrixType::Flags & RowMajorBit + }; + + public: + + inline RandomSetter(SparseMatrixType& target) + : mp_target(&target) + { + int outerPackets = target.outerSize() >> OuterPacketBits; + if (target.outerSize()&OuterPacketMask) + outerPackets += 1; + m_hashmaps = new HashMapType[outerPackets]; + KeyType ik = (1<innerSize()+1; + for (int k=0; k::setInvalidKey(m_hashmaps[k],ik); + } + + ~RandomSetter() + { + delete[] m_hashmaps; + } + + Scalar& operator() (int row, int col) + { + const int outer = RowMajor ? row : col; + const int inner = RowMajor ? col : row; + const int outerMajor = outer >> OuterPacketBits; + const int outerMinor = outer & OuterPacketMask; + const KeyType key = inner + outerMinor * mp_target->innerSize(); + + return m_hashmaps[outerMajor][key].value; + } + + + protected: + + HashMapType* m_hashmaps; + SparseMatrixType* mp_target; +}; + +#endif // EIGEN_RANDOMSETTER_H