GtUword greedyunitedist(GtFrontResource *ftres, const GtSeqabstract *useq, const GtSeqabstract *vseq) { GtUword realdistance, kval; GtWord r; GtFrontspec frontspecspace[2], *fspec, *prevfspec; GtFrontvalue *fptr; #ifdef SKDEBUG printf("unitedistcheckSEPgeneric(ulen=" GT_WU ",vlen=" GT_WU ")\n", ulenvalue,vlenvalue); #endif gt_assert(gt_seqabstract_length(useq) < (GtUword) LONG_MAX); gt_assert(gt_seqabstract_length(vseq) < (GtUword) LONG_MAX); ftres->ulen = (GtWord) gt_seqabstract_length(useq); ftres->vlen = (GtWord) gt_seqabstract_length(vseq); ftres->integermin = -MAX(ftres->ulen,ftres->vlen); prevfspec = &frontspecspace[0]; firstfrontforward(useq,vseq,ftres,prevfspec); if (ftres->ulen == ftres->vlen && GT_FRONT_ROWVALUE(ftres->frontspace) == ftres->vlen) { realdistance = 0; } else { for (kval=1UL, r=1-MIN(ftres->ulen,ftres->vlen); /* Nothing */ ; kval++, r++) { if (prevfspec == &frontspecspace[0]) { fspec = &frontspecspace[1]; } else { fspec = &frontspecspace[0]; } fspec->offset = prevfspec->offset + prevfspec->width; frontspecparms(ftres,fspec,(GtWord) kval,r); while ((GtUword) (fspec->offset + fspec->width) >= ftres->currentallocated) { ftres->currentallocated += kval+1; ftres->frontspace = gt_realloc(ftres->frontspace, sizeof *ftres->frontspace * ftres->currentallocated); } (void) evalfrontforward(useq,vseq,ftres,prevfspec,fspec,r); fptr = ftres->frontspace + fspec->offset - fspec->left; if (accessfront(ftres,fptr,fspec,ftres->vlen - ftres->ulen) == ftres->ulen) { realdistance = kval; break; } if (prevfspec == &frontspecspace[0]) { prevfspec = &frontspecspace[1]; } else { prevfspec = &frontspecspace[0]; } } } #ifdef SKDEBUG printf("unitedistfrontSEP returns "GT_WD"\n",realdistance); #endif return realdistance; }
void gt_evalxdroparbitscoresextend(bool forward, GtXdropbest *xdropbest, GtXdropresources *res, const GtSeqabstract *useq, const GtSeqabstract *vseq, GtXdropscore xdropbelowscore) { const GtWord ulen = (GtWord) gt_seqabstract_length(useq), vlen = (GtWord) gt_seqabstract_length(vseq), end_k = (GtWord) ulen - vlen, /* diagonal of endpoint (ulen, vlen) */ integermax = (GtWord) MAX(ulen, vlen), integermin = -integermax, dback = GT_XDROP_SETDBACK(xdropbelowscore); GtWord idx, lbound, /* diagonal lower bound */ ubound, /* diagonal upper bound */ currd = 0, /* distance */ k; /* lbound - 1 <= k <= ubound + 1*/ /*The following function calculates the maximal allowed number of generations with all front values equal minus infinity.*/ const int allowedMININFINITYINTgenerations = MAX(MAX(res->arbitdistances.mis, res->arbitdistances.ins), res->arbitdistances.del) - 1; int currentMININFINITYINTgeneration = 0; GtXdropfrontvalue tmpfront; GtXdropscore bigt_tmp; /* best score T' seen already */ bool alwaysMININFINITYINT = true; gt_assert(ulen != 0 && vlen != 0); res->big_t.nextfreeGtXdropscore = 0; res->fronts.nextfreeGtXdropfrontvalue = 0; /* phase 0 */ idx = (GtWord) gt_seqabstract_lcp(forward, useq, vseq,0,0); /* alignment already finished */ if (idx >= ulen || idx >= vlen) { lbound = 1L; ubound = -1L; } else { lbound = 0; ubound = 0; } tmpfront.row = (GtWord) idx; tmpfront.direction = (GtUchar) 0; /* no predecessor */ gt_xdrop_frontvalue_set(res,0,0,tmpfront); xdropbest->score = bigt_tmp = GT_XDROP_EVAL(idx + idx, 0); gt_assert(idx >= 0); xdropbest->ivalue = xdropbest->jvalue = (GtUword) idx; xdropbest->best_d = currd; xdropbest->best_k = 0; GT_STOREINARRAY (&res->big_t, GtXdropscore, 10, bigt_tmp); /* phase d > 0 */ while (lbound <= ubound) { currd++; /* calculate fronts */ for (k = lbound - 1; k <= ubound + 1; k++) { GtWord i = integermin, row; /* case 1 : DELETION-EDGE */ if (lbound < k && currd - res->arbitdistances.del >= 0 && -(currd - res->arbitdistances.del) <= k - 1 && k - 1 <= currd - res->arbitdistances.del) { i = gt_xdrop_frontvalue_get(res, currd - res->arbitdistances.del, k-1) + 1; tmpfront.direction = GT_XDROP_DELETIONBIT; } /* case 2: REPLACEMENT-EDGE */ if (lbound <= k && k <= ubound && currd - res->arbitdistances.mis >= 0 && -(currd - res->arbitdistances.mis) <= k && k <= currd - res->arbitdistances.mis) { row = gt_xdrop_frontvalue_get(res, currd - res->arbitdistances.mis, k) + 1; /* test, if case 1 has happened. */ if (!(tmpfront.direction & GT_XDROP_DELETIONBIT) || row > i) { i = row; tmpfront.direction = GT_XDROP_REPLACEMENTBIT; } } /* case 3: INSERTION-EDGE */ if (k < ubound && currd - res->arbitdistances.ins >= 0 && -(currd - res->arbitdistances.ins) <= k + 1 && k + 1 <= currd - res->arbitdistances.ins) { row = gt_xdrop_frontvalue_get(res, currd - res->arbitdistances.ins, k+1); if (!(tmpfront.direction & (GT_XDROP_DELETIONBIT | GT_XDROP_REPLACEMENTBIT)) || row > i) { i = row; tmpfront.direction = GT_XDROP_INSERTIONBIT; } } /* if i = MINUSINFINITYINY or MINUSINFINITYINY + 1 */ if (i < 0) { if (tmpfront.direction == (GtUchar) 0) alwaysMININFINITYINT = false; tmpfront.row = integermin; } else { GtWord j = i - k; const GtWord previousd = currd - dback; /* alignment score smaller than T - X */ if (previousd > 0 && res->big_t.spaceGtXdropscore != NULL && GT_XDROP_EVAL (i + j, currd) < res->big_t.spaceGtXdropscore[previousd] - xdropbelowscore) { tmpfront.row = integermin; } else { if (k <= -currd || k >= currd || (gt_xdrop_frontvalue_get(res, currd-1, k) < i && i <= MIN(ulen, vlen + k))) { if (ulen > i && vlen > j) { GtUword lcp; gt_assert(forward || (ulen - 1 >= (GtWord) i && vlen - 1 >= (GtWord) j)); lcp = gt_seqabstract_lcp(forward, useq, vseq,i,j); i += lcp; j += lcp; } alwaysMININFINITYINT = false; tmpfront.row = i; if (GT_XDROP_EVAL(i + j, currd) > bigt_tmp) { xdropbest->score = bigt_tmp = GT_XDROP_EVAL(i + j, currd); gt_assert(i >= 0 && j >= 0); xdropbest->ivalue = (GtUword) i; xdropbest->jvalue = (GtUword) j; xdropbest->best_d = currd; xdropbest->best_k = k; } } else { alwaysMININFINITYINT = false; tmpfront.row = gt_xdrop_frontvalue_get(res,currd-1,k); } } } gt_xdrop_frontvalue_set(res, currd, k, tmpfront); } /* if all front values are integermin, alignment prematurely finished if allowedMININFINITYINTgenerations exceeded (full front has already ended at currd - currentMININFINITYINTgeneration). */ if (alwaysMININFINITYINT) { currentMININFINITYINTgeneration++; if (currentMININFINITYINTgeneration > allowedMININFINITYINTgenerations) break; } else { currentMININFINITYINTgeneration = 0; alwaysMININFINITYINT = true; } GT_STOREINARRAY (&res->big_t, GtXdropscore, 10, bigt_tmp); /* fill out of bounds values of integermin needed for gt_showfrontvalues function */ for (k = -currd; k < lbound - 1; k++) { tmpfront.row = integermin; gt_xdrop_frontvalue_set(res,currd,k,tmpfront); } for (k = ubound + 2; k <= currd; k++) { tmpfront.row = integermin; gt_xdrop_frontvalue_set(res,currd,k,tmpfront); } /* alignment finished */ if (-currd <= end_k && end_k <= currd && gt_xdrop_frontvalue_get(res,currd,end_k) == ulen) break; /* pruning lower bound lbound may decrease by one or increase/stays the same l <- min{k:R(d,k) > -inf} */ for (k = lbound - 1; k <= ubound + 1; k++) { if (gt_xdrop_frontvalue_get(res,currd,k) > integermin) { lbound = k; break; } } /* pruning upper bound ubound may increase by one or decrease/stays the same u <- max{k:R(d,k) > -inf} */ for (k = ubound + 1; k >= lbound - 1; k--) { if (gt_xdrop_frontvalue_get(res,currd,k) > integermin) { ubound = k; break; } } /* handling boundaries lower bound */ for (k = 0; k >= lbound; k--) { if (gt_xdrop_frontvalue_get(res,currd,k) == vlen + k) { lbound = k; break; } } /* handling boundaries upper bound */ for (k = 0; k <= ubound; k++) { if (gt_xdrop_frontvalue_get(res,currd,k) == ulen) { ubound = k; break; } } } }