// Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_LSH_HAShES_Hh_ #define DLIB_LSH_HAShES_Hh_ #include "hashes_abstract.h" #include "../hash.h" #include "../matrix.h" namespace dlib { // ---------------------------------------------------------------------------------------- class hash_similar_angles_64 { public: hash_similar_angles_64 ( ) : seed(0) {} hash_similar_angles_64 ( const uint64 seed_ ) : seed(seed_) {} uint64 get_seed ( ) const { return seed; } typedef uint64 result_type; template < typename sparse_vector_type > typename disable_if,uint64>::type operator() ( const sparse_vector_type& v ) const { typedef typename sparse_vector_type::value_type::second_type scalar_type; uint64 temp = 0; for (int i = 0; i < 64; ++i) { // compute the dot product between v and a Gaussian random vector. scalar_type val = 0; for (typename sparse_vector_type::const_iterator j = v.begin(); j != v.end(); ++j) val += j->second*gaussian_random_hash(j->first, i, seed); if (val > 0) temp |= 1; temp <<= 1; } return temp; } template uint64 operator() ( const matrix_exp& v ) const { typedef typename EXP::type T; uint64 temp = 0; for (unsigned long i = 0; i < 64; ++i) { if (dot(matrix_cast(gaussian_randm(v.size(),1,i+seed*64)), v) > 0) temp |= 1; temp <<= 1; } return temp; } unsigned int distance ( const result_type& a, const result_type& b ) const { return hamming_distance(a,b); } private: const uint64 seed; }; // ---------------------------------------------------------------------------------------- class hash_similar_angles_128 { public: hash_similar_angles_128 ( ) : seed(0),hasher1(0), hasher2(1) {} hash_similar_angles_128 ( const uint64 seed_ ) : seed(seed_),hasher1(2*seed),hasher2(2*seed+1) {} uint64 get_seed ( ) const { return seed; } typedef std::pair result_type; template < typename vector_type > result_type operator() ( const vector_type& v ) const { return std::make_pair(hasher1(v), hasher2(v)); } unsigned int distance ( const result_type& a, const result_type& b ) const { return hamming_distance(a.first,b.first) + hamming_distance(a.second,b.second); } private: const uint64 seed; hash_similar_angles_64 hasher1; hash_similar_angles_64 hasher2; }; // ---------------------------------------------------------------------------------------- class hash_similar_angles_256 { public: hash_similar_angles_256 ( ) : seed(0), hasher1(0), hasher2(1) {} hash_similar_angles_256 ( const uint64 seed_ ) : seed(seed_),hasher1(2*seed),hasher2(2*seed+1) {} uint64 get_seed ( ) const { return seed; } typedef std::pair hash128_type; typedef std::pair result_type; template < typename vector_type > result_type operator() ( const vector_type& v ) const { return std::make_pair(hasher1(v), hasher2(v)); } unsigned int distance ( const result_type& a, const result_type& b ) const { return hasher1.distance(a.first,b.first) + hasher1.distance(a.second,b.second); } private: const uint64 seed; hash_similar_angles_128 hasher1; hash_similar_angles_128 hasher2; }; // ---------------------------------------------------------------------------------------- class hash_similar_angles_512 { public: hash_similar_angles_512 ( ) : seed(0), hasher1(0), hasher2(1) {} hash_similar_angles_512 ( const uint64 seed_ ) : seed(seed_),hasher1(2*seed),hasher2(2*seed+1) {} uint64 get_seed ( ) const { return seed; } typedef hash_similar_angles_256::result_type hash256_type; typedef std::pair result_type; template < typename vector_type > result_type operator() ( const vector_type& v ) const { return std::make_pair(hasher1(v), hasher2(v)); } unsigned int distance ( const result_type& a, const result_type& b ) const { return hasher1.distance(a.first,b.first) + hasher1.distance(a.second,b.second); } private: const uint64 seed; hash_similar_angles_256 hasher1; hash_similar_angles_256 hasher2; }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_LSH_HAShES_Hh_