inline umat sort_index ( const Base<typename T1::elem_type,T1>& X, const uword sort_type = 0, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(X.get_ref()); const Mat<eT>& A = tmp.M; if(A.is_empty() == true) { return umat(); } arma_debug_check( (A.is_vec() == false), "sort_index(): currently only handles vectors"); typedef typename umat::elem_type out_elem_type; umat out(A.n_rows, A.n_cols); if(sort_type == 0) { std::vector< arma_sort_index_packet_ascend<eT,out_elem_type> > packet_vec(A.n_elem); sort_index_helper(out.memptr(), packet_vec, A.mem); } else { std::vector< arma_sort_index_packet_descend<eT,out_elem_type> > packet_vec(A.n_elem); sort_index_helper(out.memptr(), packet_vec, A.mem); } return out; }
void inline sort_index_helper(umat_elem_type* out_mem, const eT* in_mem, const uword n_elem) { arma_extra_debug_sigprint(); std::vector< arma_sort_index_packet<eT, umat_elem_type> > packet_vec(n_elem); for(uword i=0; i<n_elem; ++i) { packet_vec[i].val = in_mem[i]; packet_vec[i].index = i; } if(sort_type == 0) { // ascend arma_sort_index_helper_ascend comparator; if(sort_stable == 0) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } else { // descend arma_sort_index_helper_descend comparator; if(sort_stable == 0) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } for(uword i=0; i<n_elem; ++i) { out_mem[i] = packet_vec[i].index; } }
/** * Search the N nearest Neighbor of the scalar array query. * * \param[in] query The query array * \param[in] nbQuery The number of query rows * \param[out] indices The corresponding (query, neighbor) indices * \param[out] distances The distances between the matched arrays. * \param[out] NN The number of maximal neighbor that will be searched. * * \return True if success. */ bool SearchNeighbours ( const Scalar * query, int nbQuery, IndMatches * pvec_indices, std::vector<DistanceType> * pvec_distances, size_t NN ) override { if (memMapping.get() == nullptr) { return false; } if (NN > (*memMapping).rows() || nbQuery < 1) { return false; } //matrix representation of the input data; Eigen::Map<BaseMat> mat_query((Scalar*)query, nbQuery, (*memMapping).cols()); Metric metric; pvec_distances->resize(nbQuery * NN); pvec_indices->resize(nbQuery * NN); #ifdef OPENMVG_USE_OPENMP #pragma omp parallel for schedule(dynamic) #endif for (int queryIndex=0; queryIndex < nbQuery; ++queryIndex) { std::vector<DistanceType> vec_distance((*memMapping).rows(), 0.0); const Scalar * queryPtr = mat_query.row(queryIndex).data(); const Scalar * rowPtr = (*memMapping).data(); for (int i = 0; i < (*memMapping).rows(); ++i) { vec_distance[i] = metric( queryPtr, rowPtr, (*memMapping).cols() ); rowPtr += (*memMapping).cols(); } // Find the N minimum distances: const int maxMinFound = (int) min( size_t(NN), vec_distance.size()); std::vector< stl::indexed_sort::sort_index_packet_ascend< DistanceType, int> > packet_vec(vec_distance.size()); stl::indexed_sort::sort_index_helper(packet_vec, &vec_distance[0], maxMinFound); for (int i = 0; i < maxMinFound; ++i) { (*pvec_distances)[queryIndex*NN+i] = packet_vec[i].val; (*pvec_indices)[queryIndex*NN+i] = IndMatch(queryIndex, packet_vec[i].index); } } return true; };
inline void op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(in.m); const Mat<eT>& X = tmp.M; if(X.is_empty()) { out.copy_size(X); return; } const uword dim = in.aux_uword_a; const uword N = (dim == 0) ? X.n_rows : X.n_cols; // see "fn_sort_index.hpp" for the definition of "arma_sort_index_packet" // and the associated comparison functor std::vector< arma_sort_index_packet<int,uword> > packet_vec(N); for(uword i=0; i<N; ++i) { packet_vec[i].val = std::rand(); packet_vec[i].index = i; } arma_sort_index_helper_ascend comparator; std::sort( packet_vec.begin(), packet_vec.end(), comparator ); const bool is_alias = (&out == &X); if(X.is_vec() == false) { if(is_alias == false) { arma_extra_debug_print("op_shuffle::apply(): matrix"); out.copy_size(X); if(dim == 0) { for(uword i=0; i<N; ++i) { out.row(i) = X.row(packet_vec[i].index); } } else { for(uword i=0; i<N; ++i) { out.col(i) = X.col(packet_vec[i].index); } } } else // in-place shuffle { arma_extra_debug_print("op_shuffle::apply(): in-place matrix"); // reuse the val member variable of packet_vec // to indicate whether a particular row or column // has already been shuffled for(uword i=0; i<N; ++i) { packet_vec[i].val = 0; } if(dim == 0) { for(uword i=0; i<N; ++i) { if(packet_vec[i].val == 0) { const uword j = packet_vec[i].index; out.swap_rows(i, j); packet_vec[j].val = 1; } } } else { for(uword i=0; i<N; ++i) { if(packet_vec[i].val == 0) { const uword j = packet_vec[i].index; out.swap_cols(i, j); packet_vec[j].val = 1; } } } } } else // we're dealing with a vector { if(is_alias == false) { arma_extra_debug_print("op_shuffle::apply(): vector"); out.copy_size(X); if(dim == 0) { if(X.n_rows > 1) // i.e. column vector { for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; } } else { out = X; } } else { if(X.n_cols > 1) // i.e. row vector { for(uword i=0; i<N; ++i) { out[i] = X[ packet_vec[i].index ]; } } else { out = X; } } } else // in-place shuffle { arma_extra_debug_print("op_shuffle::apply(): in-place vector"); // reuse the val member variable of packet_vec // to indicate whether a particular row or column // has already been shuffled for(uword i=0; i<N; ++i) { packet_vec[i].val = 0; } if(dim == 0) { if(X.n_rows > 1) // i.e. column vector { for(uword i=0; i<N; ++i) { if(packet_vec[i].val == 0) { const uword j = packet_vec[i].index; std::swap(out[i], out[j]); packet_vec[j].val = 1; } } } } else { if(X.n_cols > 1) // i.e. row vector { for(uword i=0; i<N; ++i) { if(packet_vec[i].val == 0) { const uword j = packet_vec[i].index; std::swap(out[i], out[j]); packet_vec[j].val = 1; } } } } } } }
inline bool op_find_unique::apply_helper(Mat<uword>& out, const Proxy<T1>& P, const bool ascending_indices) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); if(n_elem == 0) { out.set_size(0,1); return true; } if(n_elem == 1) { out.set_size(1,1); out[0] = 0; return true; } uvec indices(n_elem); std::vector< arma_find_unique_packet<eT> > packet_vec(n_elem); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<n_elem; ++i) { const eT val = Pea[i]; if(arma_isnan(val)) { return false; } packet_vec[i].val = val; packet_vec[i].index = i; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword i = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT val = P.at(row,col); if(arma_isnan(val)) { return false; } packet_vec[i].val = val; packet_vec[i].index = i; ++i; } } arma_find_unique_comparator<eT> comparator; std::sort( packet_vec.begin(), packet_vec.end(), comparator ); uword* indices_mem = indices.memptr(); indices_mem[0] = packet_vec[0].index; uword count = 1; for(uword i=1; i < n_elem; ++i) { const eT diff = packet_vec[i-1].val - packet_vec[i].val; if(diff != eT(0)) { indices_mem[count] = packet_vec[i].index; ++count; } } out.steal_mem_col(indices,count); if(ascending_indices) { std::sort(out.begin(), out.end()); } return true; }
inline bool arma_sort_index_helper(Mat<uword>& out, const Proxy<T1>& P, const uword sort_type, typename arma_not_cx<typename T1::elem_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); out.set_size(n_elem, 1); std::vector< arma_sort_index_packet<eT, uword> > packet_vec(n_elem); if(Proxy<T1>::prefer_at_accessor == false) { for(uword i=0; i<n_elem; ++i) { const eT val = P[i]; if(arma_isnan(val)) { out.reset(); return false; } packet_vec[i].val = val; packet_vec[i].index = i; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword i = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT val = P.at(row,col); if(arma_isnan(val)) { out.reset(); return false; } packet_vec[i].val = val; packet_vec[i].index = i; ++i; } } if(sort_type == 0) { // ascend arma_sort_index_helper_ascend comparator; if(sort_stable == false) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } else { // descend arma_sort_index_helper_descend comparator; if(sort_stable == false) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } uword* out_mem = out.memptr(); for(uword i=0; i<n_elem; ++i) { out_mem[i] = packet_vec[i].index; } return true; }