void LSH_DFE::set_mapped_rom(LSH_actions_t* actions){ int DIN = in_d.size2(); float* hashFunction = (float*)&(actions->param_hashFunction0000); for(int i=0; i<DOUT; i++){ for(int j=0; j<DIN; j++) hashFunction[i*DIN+j] = m_hash(i, j); } }
void LSH_DFE::hash_generate(){ // generate random hyperplane to do hashing for(unsigned int i=0; i<m_hash.size1(); i++) for(unsigned int j=0; j<m_hash.size2(); j++) m_hash(i, j) = float(rand()) / float(RAND_MAX); // the parameter of the hash function need to be formalized // dist = inner_product(point, hyperplane_parameter) / norm2(hyperplane_parameter) for(unsigned int i=0; i<m_hash.size1(); i++){ float sqr_sum = 0.0f; for(unsigned int j=0; j<m_hash.size2(); j++) sqr_sum += m_hash(i, j) * m_hash(i, j); float sqrt_sum = std::sqrt(sqr_sum); for(unsigned int j=0; j<m_hash.size2(); j++) m_hash(i, j) /= sqrt_sum; } }
size_type doHash( const Key& key, size_type modulus) const { assert(modulus != 0); return m_hash(key) % modulus; }
Handle find(const K& _key) { uint32_t d = 0; uint32_t h = (uint32_t)m_hash(_key);//hash(reinterpret_cast<const uint32_t*>(&_key), sizeof(_key) / 4); uint32_t idx = h % m_capacity; while(m_keys[idx].dist != 0xffffffff)// && d <= m_keys[idx].dist) { if (m_keyCompare(m_keys[idx].key, _key)) return Handle(this, idx); if(++idx >= m_capacity) idx = 0; ++d; } return Handle(nullptr, 0); }
void LSH_DFE::rehash_data_projection(){ // locality sensitive hashing using CPU // use int8_t to represent the result of every sub hash function // 128 / 8 = 16, which should be equal to DOUT int8_t temp[DOUT]; std::vector<float> mult(DOUT); for(unsigned int i=0; i<in_d.size1(); i++){ for(unsigned int j=0; j<DOUT; j++){ float data = 0.0f; for(unsigned int k=0; k<in_d.size2(); k++) data += in_d(i, k) * m_hash(j, k); mult[j] = data; } for(unsigned int j=0; j<DOUT; j++) temp[j] = (int8_t)(mult[j]/ m_cell_width); memcpy(&m_new_grid_cpu[i], temp, sizeof(DimType)); } }
void add(_KeyT&& _key, _DataT&& _data) { uint32_t h = (uint32_t)m_hash(_key);//hash(reinterpret_cast<const uint32_t*>(&_key), sizeof(_key) / 4); restartAdd: uint32_t d = 0; uint32_t idx = h % m_capacity; while(m_keys[idx].dist != 0xffffffff) // while not empty cell { if (m_keyCompare(m_keys[idx].key, _key)) // overwrite if keys are identically { m_data[idx] = _data; return; } // probing (collision) // Since we have encountered a collision: should we resize? if(m_size > 0.77 * m_capacity) { resize(m_size * 2); // Try to keep the capacity odd (prime would be even better) // The resize changed everything beginning from the index // to the content of the target cell. Restart the search. goto restartAdd; } if(m_keys[idx].dist < d) // Swap and then insert the element from this location instead { std::swap(_key, m_keys[idx].key); std::swap(d, m_keys[idx].dist); std::swap(_data, m_data[idx]); } ++d; // idx = (idx + 1) % m_capacity; if(++idx >= m_capacity) idx = 0; } new (&m_keys[idx].key)(K)(std::forward<_KeyT>(_key)); m_keys[idx].dist = d; new (&m_data[idx])(T)(std::forward<_DataT>(_data)); ++m_size; }
int tox_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) { return m_hash(hash, data, datalen); }