/* Last edited on 2008-04-19 15:51:26 by stolfi */ /* ---------------------------------------------------------------------- */ /* msm_cand_refine.c : msm_cand_refine_fill_tableau */ auto bool_t in_head(msm_rung_t g); auto bool_t in_tail(msm_rung_t g); /* TRUE if {g} is inside the `head' (resp. `tail') of the valid region, namely the square of side {kappa} whose upper right (resp. lower left) corner is the first (resp. last) rung of {prold}, widened by {delta} on all sides. */ bool_t in_head(msm_rung_t g) { msm_rung_t gini = msm_pairing_get_rung(prold, 0); int dx = g.c[0] - gini.c[0]; int dy = g.c[1] - gini.c[1]; if ((dx > delta) || (dx < -kappa-delta)) { return FALSE; } if ((dy > delta) || (dy < -kappa-delta)) { return FALSE; } return TRUE; } bool_t in_tail(msm_rung_t g) { int nr = msm_pairing_fund_rung_count(prold); msm_rung_t gfin = msm_pairing_get_rung(prold, nr-1); int dx = g.c[0] - gfin.c[0]; int dy = g.c[1] - gfin.c[1]; if ((dx < -delta) || (dx > +kappa+delta)) { return FALSE; } if ((dy < -delta) || (dy > +kappa+delta)) { return FALSE; } return TRUE; } /* ---------------------------------------------------------------------- */ int msm_seq_desc_filtered_size(int nFine, bool_t circ, int nwtb); /* Computes the number of distinct matching positions in the filtered and downsampled version of a sequence with {nFine} positions and circularity {circ}. */ int msm_seq_desc_filtered_size(int nFine, bool_t circ, int nwtb) { return (nFine - (circ ? 0 : nwtb - 1) + 1)/2; } /* ---------------------------------------------------------------------- */ typedef double msm_step_score_proc_t(msm_rung_t g0, msm_rung_t g1); /* A procedure that computes a numerical score for a single step of a pairing, from rung {g0} to rung {g1}. The procedure should allow for either rung to be {msm_rung_none}. */ /* ---------------------------------------------------------------------- */ /* AFFINE INDEX MAPPING */ int msm_seq_map_index_affinely(int ixold, int dold, int nold, int nnew); /* Applies an affine map to the index {ixold} of an element in some sequence {sold} to obtain the index {ixnew} of the approximately corresponding element in another sequence {snew}. The parameters {nold} and {nnew} should be the element counts of the two sequences. The affine map is {(ixold + dold)*nnew/nold}, rounded to an integer. The mapping is non-decreasing: i.e. increasing {ixold} does not decrease the result. */ int msm_seq_unmap_index_affinely(int ixnew, int nnew, int nold, int dold); /* An approximate inverse of {msm_seq_map_index_affinely}. Namely, computes an index {ixold} such that {msm_seq_map_index_affinely(ixold, dold, nold,nnew)} is equal to {ixnew}, apart from rounding. The formula is {ixnew*nold/nnew + dold}, rounded to the nearest integer. */ int msm_seq_map_index_affinely(int ixold, int dold, int nold, int nnew) { /* Apply the increment {dold}: */ ixold += dold; /* Reduce the index {ixold} (which may be negative) modulo {nold}: */ int kxold = (ixold % nold + nold) % nold; /* Map affinely the range {0..nold} to {0..nnew}: */ int kxnew = (int)floor(((double)kxold + 0.5)*((double)nnew)/((double)nold)); affirm((kxnew >= 0) && (kxnew < nnew), "bug"); /* Add the original number {q} of full turns: */ int q = (ixold - kxold)/nold; int ixnew = kxnew + q*nnew; return ixnew; } int msm_seq_unmap_index_affinely(int ixnew, int nnew, int nold, int dold) { /* Reduce the index {ixnew} (which may be negative) modulo {nnew}: */ int kxnew = (ixnew % nnew + nnew) % nnew; /* Map affinely the range {0..nnew} to {0..nold}: */ int kxold = (int)floor(((double)kxnew + 0.5)*((double)nnold)/((double)nnew)); affirm((kxold >= 0) && (kxold < nold), "bug"); /* Add the original number {q} of full turns: */ int q = (ixnew - kxnew)/nnew; int ixold = kxold + q*nold; /* Un-apply the increment {dold}: */ ixold -= dold; return ixold; } /* Round {xMin,yMin} down to multiples of the sequence lengths: */ xMin = ifloor(xMin, nx); yMin = ifloor(yMin, ny); /* Round {xMax,yMax} up to multiples of the sequence lengths, minus 1: */ xMax = iceil(xMax + 1, nx) - 1; yMax = iceil(yMax + 1, ny) - 1; fprintf(stderr, " adjusted coordinate ranges"); fprintf(stderr, "[%4d .. %4d]�[%4d .. %4d]\n", xMin, xMax, yMin, yMax); /* Paint the indices that are multiples of {nx} or {ny}: */ msm_image_seq_periods_paint(nx, ny, coord_clr, cim, xMin, yMin);