TEMPLATE_HEADER typename LR::Data LR::solveNormalEqn( Coordinate & c, Neighbors & nset ){ if( y.size().rows != Basis::size ){ A.resize( Basis::size, Basis::size ); y.resize( Basis::size, 1); } // find bounds for points Coordinate lb = nset[0].point, rb = nset[0].point, tmp; for( int j = 0; j < Coordinate::Dims ; j++ ){ for( int i = 1; i < nset.size(); i++ ){ lb[j] = fmin(nset[i].point[j],lb[j]); rb[j] = fmax(nset[i].point[j],rb[j]); } } // compute weights std::vector<double> weights(nset.size()); wfunc(weights,nset); // store values for A A = 0; for(int j = 0; j < Basis::size; j++ ){ for( int k = j; k < Basis::size; k++ ){ for( int i = 0; i < nset.size(); i++ ){ scale(lb,rb,nset[i].point,tmp); A(j,k) += basis(k, tmp)*basis(j, tmp)*weights[i]; } } } // store values for y y = 0; for(int j = 0; j < Basis::size; j++ ){ for( int i = 0; i < nset.size(); i++ ){ scale(lb,rb,nset[i].point,tmp); y[j] += basis(j, tmp)*weights[i]*nset[i].data; } } // solve system of equations la::solve(A,y,coef); // compute point Data output = 0; for( int i = 0; i < Basis::size; i++ ){ scale(lb,rb,c,tmp); output += coef[i]*basis(i,tmp); } return output; }
// Zhu et al. "A Rank-Order Distance based Clustering Algorithm for Face Tagging", CVPR 2011 // Ob(x) in eq. 1, modified to consider 0/1 as ground truth imposter/genuine. static int indexOf(const Neighbors &neighbors, int i) { for (int j=0; j<neighbors.size(); j++) { const Neighbor &neighbor = neighbors[j]; if (neighbor.first == i) { if (neighbor.second == 0) return neighbors.size()-1; else if (neighbor.second == 1) return 0; else return j; } } return -1; }
SparseMatrix neighbors_distances_matrix(RandomAccessIterator begin, RandomAccessIterator end, const Neighbors& neighbors, DistanceCallback callback, ScalarType& average_distance) { const IndexType k = neighbors[0].size(); const IndexType n = neighbors.size(); if ((end-begin)!=n) throw std::runtime_error("Wrong size"); SparseTriplets sparse_triplets; sparse_triplets.reserve(k*n); average_distance = 0; ScalarType current_distance; for (IndexType i = 0; i < n; ++i) { const LocalNeighbors& current_neighbors = neighbors[i]; for (IndexType j = 0; j < k; ++j) { current_distance = callback.distance(begin[i], begin[current_neighbors[j]]); average_distance += current_distance; SparseTriplet triplet(i, current_neighbors[j], current_distance); sparse_triplets.push_back(triplet); } } average_distance /= (k*n); return sparse_matrix_from_triplets(sparse_triplets, n, n); }
void DBSCAN::dbscan( const DBSCAN::DistanceMatrix& dm ) { std::vector< uint8_t > visited( dm.size1() ); uint32_t cluster_id = 0; for ( uint32_t pid = 0; pid < dm.size1(); ++pid ) { if ( !visited[pid] ) { visited[pid] = 1; Neighbors ne = find_neighbors( dm, pid ); if ( ne.size() >= m_min_elems ) { m_labels[pid] = cluster_id; for ( uint32_t i = 0; i < ne.size(); ++i ) { uint32_t nPid = ne[i]; if ( !visited[nPid] ) { visited[nPid] = 1; Neighbors ne1 = find_neighbors( dm, nPid ); if ( ne1.size() >= m_min_elems ) { for ( const auto& n1 : ne1 ) { ne.push_back( n1 ); } } } if ( m_labels[nPid] == -1 ) { m_labels[nPid] = cluster_id; } } ++cluster_id; } } } }
void ClustererDBSCAN::run_cluster(Points samples) { ClusterId cid = 1; // foreach pid for (PointId pid = 0; pid < samples.size(); pid++) { // not already visited if (!_visited[pid]){ _visited[pid] = true; // get the neighbors Neighbors ne = findNeighbors(pid, _eps); // not enough support -> mark as noise if (ne.size() < _minPts) { _noise[pid] = true; } else { //else it's a core point _core[pid] = true; // Add p to current cluster CCluster c; // a new cluster c.push_back(pid); // assign pid to cluster _pointId_to_clusterId[pid]=cid; // go to neighbors for (unsigned int i = 0; i < ne.size(); i++) { PointId nPid = ne[i]; // not already visited if (!_visited[nPid]) { _visited[nPid] = true; // go to neighbors Neighbors ne1 = findNeighbors(nPid, _eps); // enough support if (ne1.size() >= _minPts) { _core[nPid] = true; // join BOOST_FOREACH(Neighbors::value_type n1, ne1) { // join neighbord ne.push_back(n1); } } } // not already assigned to a cluster if (!_pointId_to_clusterId[nPid]) { // add it to the current cluster c.push_back(nPid); _pointId_to_clusterId[nPid]=cid; } }