inline T &_3dArray<T>::operator()(size_t index0, size_t index1, size_t index2) { #ifdef FIBER_CHECK_ARRAY_BOUNDS check_indices(index0, index1, index2); #endif return m_storage[index0 + m_extents[0] * index1 + m_extents[0] * m_extents[1] * index2]; }
inline void subview_cube_each2<eT,TB>::operator/= (const Base<eT,T1>& in) { arma_extra_debug_sigprint(); Cube<eT>& p = access::rw(subview_cube_each_common<eT>::P); const unwrap<T1> tmp( in.get_ref() ); const Mat<eT>& A = tmp.M; subview_cube_each_common<eT>::check_size(A); const unwrap<TB> U( base_indices.get_ref() ); check_indices(U.M); const uword p_n_slices = p.n_slices; const uword p_n_elem_slice = p.n_elem_slice; const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; const eT* A_mem = A.memptr(); for(uword i=0; i < N; ++i) { const uword slice = indices_mem[i]; arma_debug_check( (slice >= p_n_slices), "each_slice(): index out of bounds" ); arrayops::inplace_div(p.slice_memptr(slice), A_mem, p_n_elem_slice); } }
inline const T& _2dArray<T>::operator()(size_t index0, size_t index1) const { #ifdef FIBER_CHECK_ARRAY_BOUNDS check_indices(index0, index1); #endif return m_storage[index0 + m_extents[0] * index1]; }
void detect_olaps(output_store* output, SEXP anchor1, SEXP anchor2, SEXP querystarts, SEXP queryends, SEXP subject, SEXP nsubjects, SEXP use_both) { if (!isInteger(anchor1) || !isInteger(anchor2)) { throw std::runtime_error("anchors must be integer vectors"); } const int Npairs = LENGTH(anchor1); if (Npairs != LENGTH(anchor2)) { throw std::runtime_error("anchor vectors must be of equal length"); } const int* a1ptr=INTEGER(anchor1), *a2ptr=INTEGER(anchor2); if (!isInteger(querystarts) || !isInteger(queryends)) { throw std::runtime_error("query indices must be integer vectors"); } const int Nq = LENGTH(querystarts); if (Nq != LENGTH(queryends)) { throw std::runtime_error("query indices must be of equal length"); } const int* qsptr=INTEGER(querystarts), *qeptr=INTEGER(queryends); if (!isInteger(subject)) { throw std::runtime_error("subject indices must be integer"); } const int Ns = LENGTH(subject); const int *sjptr=INTEGER(subject); if (!isInteger(nsubjects) || LENGTH(nsubjects)!=1) { throw std::runtime_error("total number of subjects must be an integer scalar"); } const int Ns_all = asInteger(nsubjects); int true_mode_start, true_mode_end; set_mode_values(use_both, true_mode_start, true_mode_end); // Checking indices. check_indices(qsptr, qeptr, Nq, sjptr, Ns, Ns_all); /* Constructing an output deque */ output->prime(Npairs, Ns_all); int* latest_pair=(int*)R_alloc(Ns_all, sizeof(int)); for (int checkdex=0; checkdex < Ns_all; ++checkdex) { latest_pair[checkdex] = -1; } int curpair=0, mode=0, maxmode, curq=0, curindex=0, curs=0; for (curpair=0; curpair<Npairs; ++curpair) { maxmode=(a1ptr[curpair]==a2ptr[curpair] ? true_mode_start+1 : true_mode_end); // just check one or the other, if they're the same. for (mode=true_mode_start; mode<maxmode; ++mode) { if (mode == 0) { curq = a1ptr[curpair]; } else { curq = a2ptr[curpair]; } if (curq >= Nq || curq < 0 || curq==NA_INTEGER) { throw std::runtime_error("region index out of bounds"); } for (curindex=qsptr[curq]; curindex<qeptr[curq]; ++curindex) { curs=sjptr[curindex]; if (latest_pair[curs] < curpair) { output->acknowledge(curpair, curs); latest_pair[curs] = curpair; if (output->quit()) { // If we just want any hit, we go to the next 'curpair'. goto outofnest; // Ugh. Oh well, cleaner than lots of break's. } } } } outofnest: output->postprocess(); } return; }
inline const T &_4dArray<T>::operator()(size_t index0, size_t index1, size_t index2, size_t index3) const { #ifdef FIBER_CHECK_ARRAY_BOUNDS check_indices(index0, index1, index2, index3); #endif return m_storage[index0 + m_extents[0] * index1 + m_extents[0] * m_extents[1] * index2 + m_extents[0] * m_extents[1] * m_extents[2] * index3]; }
inline void subview_each2<parent,mode,TB>::operator= (const Base<eT,T1>& in) { arma_extra_debug_sigprint(); parent& p = access::rw(subview_each_common<parent,mode>::p); const unwrap_check<T1> tmp( in.get_ref(), (*this).get_mat_ref() ); const Mat<eT>& A = tmp.M; subview_each_common<parent,mode>::check_size(A); const unwrap_check_mixed<TB> U( base_indices.get_ref(), (*this).get_mat_ref() ); check_indices(U.M); const eT* A_mem = A.memptr(); const uword p_n_rows = p.n_rows; const uword p_n_cols = p.n_cols; const uword* indices_mem = U.M.memptr(); const uword N = U.M.n_elem; if(mode == 0) // each column { for(uword i=0; i < N; ++i) { const uword col = indices_mem[i]; arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); arrayops::copy( p.colptr(col), A_mem, p_n_rows ); } } else // each row { for(uword i=0; i < N; ++i) { const uword row = indices_mem[i]; arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); for(uword col=0; col < p_n_cols; ++col) { p.at(row,col) = A_mem[col]; } } } }
SEXP expand_pair_links(SEXP anchor1, SEXP anchor2, SEXP querystarts1, SEXP queryends1, SEXP subject1, SEXP nsubjects1, SEXP querystarts2, SEXP queryends2, SEXP subject2, SEXP nsubjects2, SEXP sameness, SEXP use_both) try { if (!isInteger(anchor1) || !isInteger(anchor2)) { throw std::runtime_error("anchors must be integer vectors"); } const int Npairs = LENGTH(anchor1); if (Npairs != LENGTH(anchor2)) { throw std::runtime_error("anchor vectors must be of equal length"); } const int* a1ptr=INTEGER(anchor1), *a2ptr=INTEGER(anchor2); if (!isInteger(querystarts1) || !isInteger(queryends1)) { throw std::runtime_error("query indices (1) must be integer vectors"); } const int Nq = LENGTH(querystarts1); if (Nq != LENGTH(queryends1)) { throw std::runtime_error("query indices (1) must be of equal length"); } const int* qsptr1=INTEGER(querystarts1), *qeptr1=INTEGER(queryends1); if (!isInteger(subject1)) { throw std::runtime_error("subject indices (1) must be integer"); } const int Ns1 = LENGTH(subject1); const int *sjptr1=INTEGER(subject1); if (!isInteger(querystarts2) || !isInteger(queryends2)) { throw std::runtime_error("query indices (2) must be integer vectors"); } if (Nq != LENGTH(querystarts2) || Nq != LENGTH(queryends2)) { throw std::runtime_error("query indices (2) must be of equal length"); } const int* qsptr2=INTEGER(querystarts2), *qeptr2=INTEGER(queryends2); if (!isInteger(subject2)) { throw std::runtime_error("subject indices (2) must be integer"); } const int Ns2 = LENGTH(subject2); const int *sjptr2=INTEGER(subject2); if (!isInteger(nsubjects1) || LENGTH(nsubjects1)!=1) { throw std::runtime_error("total number of subjects (1) must be an integer scalar"); } const int Ns_all1 = asInteger(nsubjects1); if (!isInteger(nsubjects2) || LENGTH(nsubjects2)!=1) { throw std::runtime_error("total number of subjects (2) must be an integer scalar"); } const int Ns_all2 = asInteger(nsubjects2); int true_mode_start, true_mode_end; set_mode_values(use_both, true_mode_start, true_mode_end); if (!isLogical(sameness) || LENGTH(sameness)!=1) { throw std::runtime_error("same region indicator should be a logical scalar"); } const bool is_same=asLogical(sameness); if (is_same) { true_mode_end=true_mode_start+1; } // No point examining the flipped ones. // Check indices. check_indices(qsptr1, qeptr1, Nq, sjptr1, Ns1, Ns_all1); check_indices(qsptr2, qeptr2, Nq, sjptr2, Ns2, Ns_all2); // Setting up the set. typedef std::pair<int, int> link; std::set<link> currently_active; std::set<link>::const_iterator itca; std::deque<link> stored_inactive; std::deque<int> interactions; int curpair=0, mode=0, maxmode, curq1=0, curq2=0, curindex1=0, curindex2=0; for (curpair=0; curpair<Npairs; ++curpair) { maxmode = (a1ptr[curpair] == a2ptr[curpair] ? true_mode_start+1 : true_mode_end); // Repeating with switched anchors, if the query sets are not the same. for (mode=true_mode_start; mode<maxmode; ++mode) { if (mode==0) { curq1 = a1ptr[curpair]; curq2 = a2ptr[curpair]; if (curq1 >= Nq || curq1 < 0 || curq1==NA_INTEGER) { throw std::runtime_error("region index (1) out of bounds"); } if (curq2 >= Nq || curq2 < 0 || curq2==NA_INTEGER) { throw std::runtime_error("region index (2) out of bounds"); } } else { curq2 = a1ptr[curpair]; curq1 = a2ptr[curpair]; } /* Storing all combinations associated with this pair. Avoiding redundant combinations * for self-linking (we can't use a simple rule like curindex2 < curindex1 to restrict * the loop, as the second anchor can overlap regions above the first anchor if the * latter is nested within the former). */ for (curindex1=qsptr1[curq1]; curindex1<qeptr1[curq1]; ++curindex1) { for (curindex2=qsptr2[curq2]; curindex2<qeptr2[curq2]; ++curindex2) { if (is_same && sjptr1[curindex1] < sjptr2[curindex2]) { currently_active.insert(link(sjptr2[curindex2], sjptr1[curindex1])); } else { currently_active.insert(link(sjptr1[curindex1], sjptr2[curindex2])); } } } } // Relieving the set by storing all inactive entries (automatically sorted as well). for (itca=currently_active.begin(); itca!=currently_active.end(); ++itca) { stored_inactive.push_back(*itca); } interactions.resize(interactions.size() + currently_active.size(), curpair); currently_active.clear(); } // Popping back a list of information. SEXP output=PROTECT(allocVector(VECSXP, 3)); try { const int total_entries=interactions.size(); SET_VECTOR_ELT(output, 0, allocVector(INTSXP, total_entries)); int * oiptr=INTEGER(VECTOR_ELT(output, 0)); SET_VECTOR_ELT(output, 1, allocVector(INTSXP, total_entries)); int * os1ptr=INTEGER(VECTOR_ELT(output, 1)); SET_VECTOR_ELT(output, 2, allocVector(INTSXP, total_entries)); int * os2ptr=INTEGER(VECTOR_ELT(output, 2)); std::copy(interactions.begin(), interactions.end(), oiptr); for (int curdex=0; curdex < total_entries; ++curdex) { os1ptr[curdex]=stored_inactive[curdex].first; os2ptr[curdex]=stored_inactive[curdex].second; } } catch (std::exception& e) { UNPROTECT(1); throw; } UNPROTECT(1); return output; } catch (std::exception& e) { return mkString(e.what()); }
void detect_paired_olaps(output_store* output, SEXP anchor1, SEXP anchor2, SEXP querystarts, SEXP queryends, SEXP subject, SEXP next_anchor_start1, SEXP next_anchor_end1, SEXP next_id1, SEXP next_anchor_start2, SEXP next_anchor_end2, SEXP next_id2, SEXP num_next_pairs, SEXP use_both) { if (!isInteger(anchor1) || !isInteger(anchor2)) { throw std::runtime_error("anchors must be integer vectors"); } const int Npairs = LENGTH(anchor1); if (Npairs != LENGTH(anchor2)) { throw std::runtime_error("anchor vectors must be of equal length"); } const int* a1ptr=INTEGER(anchor1), *a2ptr=INTEGER(anchor2); if (!isInteger(querystarts) || !isInteger(queryends)) { throw std::runtime_error("query indices must be integer vectors"); } const int Nq = LENGTH(querystarts); if (Nq != LENGTH(queryends)) { throw std::runtime_error("query indices must be of equal length"); } const int* qsptr=INTEGER(querystarts), *qeptr=INTEGER(queryends); if (!isInteger(subject)) { throw std::runtime_error("subject indices must be integer"); } const int Ns = LENGTH(subject); const int *sjptr=INTEGER(subject); if (!isInteger(next_anchor_start1) || !isInteger(next_anchor_end1)) { throw std::runtime_error("next indices (1) must be integer vectors"); } const int Nas=LENGTH(next_anchor_start1); if (Nas != LENGTH(next_anchor_end1)) { throw std::runtime_error("next indices (1) must be of equal length"); } const int* nasptr1=INTEGER(next_anchor_start1), *naeptr1=INTEGER(next_anchor_end1); if (!isInteger(next_id1)) { throw std::runtime_error("next ID indices (1) must be integer"); } const int *niptr1=INTEGER(next_id1); if (!isInteger(next_anchor_start2) || !isInteger(next_anchor_end2)) { throw std::runtime_error("next indices (2) must be integer vectors"); } if (Nas != LENGTH(next_anchor_start2) || Nas != LENGTH(next_anchor_end2)) { throw std::runtime_error("next indices (2) must be of equal length"); } const int* nasptr2=INTEGER(next_anchor_start2), *naeptr2=INTEGER(next_anchor_end2); if (!isInteger(next_id2)) { throw std::runtime_error("next ID indices (2) must be integer"); } const int *niptr2=INTEGER(next_id2); if (!isInteger(num_next_pairs) || LENGTH(num_next_pairs)!=1) { throw std::runtime_error("total number of next pairs must be an integer scalar"); } const int Nnp = asInteger(num_next_pairs); if (LENGTH(next_id1)!=Nnp || LENGTH(next_id2)!=Nnp) { throw std::runtime_error("number of next IDs is not equal to specified number of pairs"); } int true_mode_start, true_mode_end; set_mode_values(use_both, true_mode_start, true_mode_end); // Check indices. check_indices(qsptr, qeptr, Nq, sjptr, Ns, Nas); check_indices(nasptr1, naeptr1, Nas, niptr1, Nnp, Nnp); check_indices(nasptr2, naeptr2, Nas, niptr2, Nnp, Nnp); // Setting up logging arrays. output->prime(Npairs, Nnp); int* latest_pair_A=(int*)R_alloc(Nnp, sizeof(int)); int* latest_pair_B=(int*)R_alloc(Nnp, sizeof(int)); bool* is_complete_A=(bool*)R_alloc(Nnp, sizeof(bool)); bool* is_complete_B=(bool*)R_alloc(Nnp, sizeof(bool)); for (int checkdex=0; checkdex < Nnp; ++checkdex) { latest_pair_A[checkdex] = latest_pair_B[checkdex] = -1; is_complete_A[checkdex] = is_complete_B[checkdex] = true; } int curpair=0, mode=0, maxmode, curq1=0, curq2=0, curindex=0, cur_subreg=0, cur_nextanch=0, cur_nextid; int * latest_pair; bool * is_complete; for (curpair=0; curpair<Npairs; ++curpair) { maxmode = (a1ptr[curpair] == a2ptr[curpair] ? true_mode_start+1 : true_mode_end); /* Checking whether the first and second anchor overlaps anything in the opposing query sets. * Doing this twice; first and second anchors to the first and second query sets (A, mode=0), then * the first and second anchors to the second and first query sets (B, mode=1). */ for (mode=true_mode_start; mode<maxmode; ++mode) { if (mode==0) { curq1 = a1ptr[curpair]; curq2 = a2ptr[curpair]; if (curq1 >= Nq || curq1 < 0 || curq1==NA_INTEGER) { throw std::runtime_error("region index (1) out of bounds"); } if (curq2 >= Nq || curq2 < 0 || curq2==NA_INTEGER) { throw std::runtime_error("region index (2) out of bounds"); } latest_pair = latest_pair_A; is_complete = is_complete_A; } else { curq2 = a1ptr[curpair]; curq1 = a2ptr[curpair]; latest_pair = latest_pair_B; is_complete = is_complete_B; } for (curindex=qsptr[curq1]; curindex<qeptr[curq1]; ++curindex) { cur_subreg=sjptr[curindex]; for (cur_nextanch=nasptr1[cur_subreg]; cur_nextanch<naeptr1[cur_subreg]; ++cur_nextanch) { cur_nextid=niptr1[cur_nextanch]; /* An overlap with element 'checkdex' has already been added from the "A" cycle, if * is_complete[checkdex]=true and latest_pair[checkdex] is at the current query index. * Otherwise, updating latest_pair if it hasn't already been updated - setting * latest_pair to the query index to indicate that the first anchor region is overlapped, * but also setting is_complete to false to indicate that the overlap is not complete. */ if (mode!=0 && latest_pair_A[cur_nextid] == curpair && is_complete_A[cur_nextid]) { continue; } if (latest_pair[cur_nextid] < curpair) { latest_pair[cur_nextid] = curpair; is_complete[cur_nextid] = false; } } } for (curindex=qsptr[curq2]; curindex<qeptr[curq2]; ++curindex) { cur_subreg=sjptr[curindex]; for (cur_nextanch=nasptr2[cur_subreg]; cur_nextanch<naeptr2[cur_subreg]; ++cur_nextanch) { cur_nextid=niptr2[cur_nextanch]; /* Again, checking if overlap has already been added from the "A" cycle. Otherwise, we only add * an overlap if anchor region 1 was overlapped by 'cur_nextid', as indicated by latest_pair * (and is_complete is false, to avoid re-adding something that was added in this cycle). */ if (mode!=0 && latest_pair_A[cur_nextid] == curpair && is_complete_A[cur_nextid]) { continue; } if (latest_pair[cur_nextid] == curpair && !is_complete[cur_nextid]) { output->acknowledge(curpair, cur_nextid); is_complete[cur_nextid] = true; if (output->quit()) { // If we just want any hit, we go to the next 'curpair'. goto outofnest; } } } } } outofnest: output->postprocess(); } return; }