@@ -3233,49 +3233,86 @@ template <typename T> bool IsSymmetricMatrix(MyMatrix<T> const &M) {
32333233 return true ;
32343234}
32353235
3236+ template <typename T>
3237+ size_t hash_matrix_sizes (MyMatrix<T> const & M, size_t const & seed) {
3238+ size_t ret_hash = seed;
3239+ size_t hash_nrow = std::hash<int >{}(M.rows ());
3240+ size_t hash_ncol = std::hash<int >{}(M.cols ());
3241+ hash_utils::hash_combine (ret_hash, hash_nrow);
3242+ hash_utils::hash_combine (ret_hash, hash_ncol);
3243+ return ret_hash;
3244+ }
3245+
3246+ template <typename T>
3247+ size_t hash_vector_size (MyVector<T> const & V, size_t const & seed) {
3248+ size_t ret_hash = seed;
3249+ size_t hash_size = std::hash<int >{}(V.size ());
3250+ hash_utils::hash_combine (ret_hash, hash_size);
3251+ return ret_hash;
3252+ }
3253+
3254+
3255+
32363256template <typename T>
32373257inline typename std::enable_if<!std::is_arithmetic<T>::value, size_t >::type
32383258Matrix_Hash (MyMatrix<T> const &M, size_t const &seed) {
3239- if (M.size () == 0 ) return seed;
3259+ size_t ret_hash = hash_matrix_sizes (M, seed);
3260+ int nbRow = M.rows ();
3261+ int nbCol = M.cols ();
32403262
3241- size_t result = seed;
3263+ for (int iRow = 0 ; iRow < nbRow; iRow++) {
3264+ for (int iCol = 0 ; iCol < nbCol; iCol++) {
3265+ size_t hash_elem = std::hash<T>{}(M (iRow, iCol));
3266+ hash_utils::hash_combine (ret_hash, hash_elem);
3267+ }
3268+ }
3269+ return ret_hash;
3270+ }
3271+
3272+ // The type independent hash.
3273+ // That is if a matrix can be represented in in16_t, int32_t, int64_t, mpz_class
3274+ // then it has the same hash however it is represented.
3275+ // In practice this is done via writing to a string.
3276+ template <typename T>
3277+ size_t matrix_type_independent_hash (MyMatrix<T> const & M, size_t const & seed) {
3278+ size_t ret_hash = hash_matrix_sizes (M, seed);
32423279 int nbRow = M.rows ();
32433280 int nbCol = M.cols ();
3244-
3281+ std::stringstream s;
32453282 for (int iRow = 0 ; iRow < nbRow; iRow++) {
32463283 for (int iCol = 0 ; iCol < nbCol; iCol++) {
3247- size_t elem_hash = std::hash<T>{}(M (iRow, iCol));
3248- hash_utils::hash_combine (result, elem_hash);
3284+ s << " " << M (iRow,iCol);
32493285 }
32503286 }
3251- return result;
3287+ std::string stro = s.str ();
3288+ size_t hash_stro = std::hash<std::string>()(stro);
3289+ hash_utils::hash_combine (ret_hash, hash_stro);
3290+ return ret_hash;
32523291}
32533292
32543293template <typename T>
32553294inline typename std::enable_if<std::is_arithmetic<T>::value, size_t >::type
32563295Matrix_Hash (MyMatrix<T> const &M, size_t const &seed) {
3257- if (M. size () == 0 ) return seed;
3258- return hash_utils::hash_arithmetic_array (M.data (), M.size (), seed );
3296+ size_t ret_hash = hash_matrix_sizes (M, seed) ;
3297+ return hash_utils::hash_arithmetic_array (M.data (), M.size (), ret_hash );
32593298}
32603299
32613300template <typename T>
32623301inline typename std::enable_if<!std::is_arithmetic<T>::value, size_t >::type
32633302Vector_Hash (MyVector<T> const &V, size_t const &seed) {
3264- if (V.size () == 0 ) return seed;
3265-
3266- size_t result = seed;
3303+ size_t ret_hash = hash_vector_size (V, seed);
32673304 for (int i = 0 ; i < V.size (); i++) {
32683305 size_t elem_hash = std::hash<T>{}(V (i));
3269- hash_utils::hash_combine (result , elem_hash);
3306+ hash_utils::hash_combine (ret_hash , elem_hash);
32703307 }
3271- return result ;
3308+ return ret_hash ;
32723309}
32733310
32743311template <typename T>
32753312inline typename std::enable_if<std::is_arithmetic<T>::value, size_t >::type
32763313Vector_Hash (MyVector<T> const &V, size_t const &seed) {
3277- if (V. size () == 0 ) return seed;
3278- return hash_utils::hash_arithmetic_array (V.data (), V.size (), seed );
3314+ size_t ret_hash = hash_vector_size (V, seed) ;
3315+ return hash_utils::hash_arithmetic_array (V.data (), V.size (), ret_hash );
32793316}
32803317
32813318namespace std {
@@ -3285,12 +3322,14 @@ template <typename T> struct hash<MyVector<T>> {
32853322 return Vector_Hash (e_val, seed);
32863323 }
32873324};
3325+
32883326template <typename T> struct hash <MyMatrix<T>> {
3289- std::size_t operator ()(const MyMatrix<T> &e_val) const {
3327+ std::size_t operator ()(const MyMatrix<T> &e_val) const {
32903328 size_t seed = 0x1b873540 ;
32913329 return Matrix_Hash (e_val, seed);
32923330 }
32933331};
3332+
32943333// clang-format off
32953334} // namespace std
32963335// clang-format on
0 commit comments