static void firstfrontforward(const GtSeqabstract *useq, const GtSeqabstract *vseq, GtFrontResource *ftres, GtFrontspec *fspec) { fspec->left = fspec->offset = 0; fspec->width = 1L; if (ftres->ulen == 0 || ftres->vlen == 0) { GT_FRONT_STORE(ftres,GT_FRONT_ROWVALUE(&ftres->frontspace[0]),0); } else { GtUword lcp = gt_seqabstract_lcp(true, useq, vseq, 0, 0, (GtUword) MIN(ftres->ulen,ftres->vlen)); GT_FRONT_STORE(ftres,GT_FRONT_ROWVALUE(&ftres->frontspace[0]),(GtWord) lcp); } #ifdef SKDEBUG printf("forward front[0]="GT_WD"\n",GT_FRONT_ROWVALUE(&ftres->frontspace[0])); #endif }
static void evalentryforward(const GtSeqabstract *useq, const GtSeqabstract *vseq, GtFrontResource *ftres, GtFrontvalue *fval, const GtFrontspec *fspec, GtWord k) { GtWord value, t; GtFrontvalue *fptr; #ifdef SKDEBUG printf("evalentryforward(k="GT_WD")\n",k); #endif fptr = ftres->frontspace + fspec->offset - fspec->left; t = accessfront(ftres,fptr,fspec,k) + 1; /* same diagonal */ #ifdef SKDEBUG printf("same: access(k="GT_WD")="GT_WD"\n",k,t-1); #endif value = accessfront(ftres,fptr,fspec,k-1); /* diagonal below */ #ifdef SKDEBUG printf("below: access(k="GT_WD")="GT_WD"\n",k-1,value); #endif if (t < value) { t = value; } value = accessfront(ftres,fptr,fspec,k+1) + 1; /* diagonal above */ #ifdef SKDEBUG printf("above: access(k="GT_WD")="GT_WD"\n",k+1,value-1); #endif if (t < value) { t = value; } #ifdef SKDEBUG printf("maximum: t="GT_WD"\n",t); /* the maximum over three values */ #endif if (t < 0 || t+k < 0) /* no negative value */ { GT_FRONT_STORE(ftres,GT_FRONT_ROWVALUE(fval),GT_FRONT_MINUSINFINITY(ftres)); } else { if (ftres->ulen != 0 && ftres->vlen != 0 && t < ftres->ulen && t + k < ftres->vlen) { GtUword lcp, minlen = (GtUword) MIN(ftres->ulen - t,ftres->vlen - (t + k)); lcp = gt_seqabstract_lcp(true, useq, vseq, (GtUword) t, (GtUword) (t + k), minlen); t += lcp; } if (t > ftres->ulen || t + k > ftres->vlen) { GT_FRONT_STORE(ftres,GT_FRONT_ROWVALUE(fval), GT_FRONT_MINUSINFINITY(ftres)); } else { GT_FRONT_STORE(ftres,GT_FRONT_ROWVALUE(fval),t); } } }
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; } } } }