/*! Resolve the overloaded method to call. The algorithm works conceptually like this: 1. Resolve the set of overloads it is *possible* to call. Impossible overloads include those that have too many parameters or have parameters of unknown type. 2. Filter the set of overloads to only contain those with the closest number of parameters. For example, if we are called with 3 parameters and there are 2 overloads that take 2 parameters and one that takes 3, eliminate the 2 parameter overloads. 3. Find the best remaining overload based on its match score. If two or more overloads have the same match score, call the last one. The match score is constructed by adding the matchScore() result for each of the parameters. */ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::callOverloaded(MethodData *method, QScriptContext *ctxt) { int argumentCount = ctxt->argumentCount(); QDeclarativePropertyCache::Data *best = 0; int bestParameterScore = INT_MAX; int bestMatchScore = INT_MAX; QDeclarativePropertyCache::Data dummy; QDeclarativePropertyCache::Data *attempt = &method->data; do { QList<QByteArray> methodArgTypeNames; if (attempt->flags & QDeclarativePropertyCache::Data::HasArguments) methodArgTypeNames = method->object->metaObject()->method(attempt->coreIndex).parameterTypes(); int methodArgumentCount = methodArgTypeNames.count(); if (methodArgumentCount > argumentCount) continue; // We don't have sufficient arguments to call this method int methodParameterScore = argumentCount - methodArgumentCount; if (methodParameterScore > bestParameterScore) continue; // We already have a better option int methodMatchScore = 0; QVarLengthArray<int, 9> methodArgTypes(methodArgumentCount); bool unknownArgument = false; for (int ii = 0; ii < methodArgumentCount; ++ii) { methodArgTypes[ii] = QMetaType::type(methodArgTypeNames.at(ii)); if (methodArgTypes[ii] == QVariant::Invalid) methodArgTypes[ii] = enumType(method->object->metaObject(), QString::fromLatin1(methodArgTypeNames.at(ii))); if (methodArgTypes[ii] == QVariant::Invalid) { unknownArgument = true; break; } methodMatchScore += matchScore(ctxt->argument(ii), methodArgTypes[ii], methodArgTypeNames.at(ii)); } if (unknownArgument) continue; // We don't understand all the parameters if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) { best = attempt; bestParameterScore = methodParameterScore; bestMatchScore = methodMatchScore; } if (bestParameterScore == 0 && bestMatchScore == 0) break; // We can't get better than that } while((attempt = relatedMethod(method->object, attempt, dummy)) != 0); if (best) { return callPrecise(method->object, *best, ctxt); } else { QString error = QLatin1String("Unable to determine callable overload. Candidates are:"); QDeclarativePropertyCache::Data *candidate = &method->data; while (candidate) { error += QLatin1String("\n ") + QString::fromUtf8(method->object->metaObject()->method(candidate->coreIndex).signature()); candidate = relatedMethod(method->object, candidate, dummy); } return Value(ctxt, ctxt->throwError(error)); } }
pair<vector<unsigned long>,vector<unsigned long>> SeqGraphAlignment::alignStringToGraphFast() { //if (typeid(sequence).name() != "string") { // cerr << "Invalid Type" << endl; // return; //} unsigned long l1 = graph->numberOfNodes; unsigned long l2 = sequence.length(); unordered_map<unsigned long, unsigned long> nodeIDtoIndex; unordered_map<unsigned long, unsigned long> nodeIndexToID; nodeIndexToID[-1] = (unsigned long) -1; auto nodes = graph->nodes; unsigned long index = 0; for (auto nodeID : graph->nodeOrder) { nodeIDtoIndex[nodeID] = index; nodeIndexToID[index] = nodeID; index++; } // for (map<int, Node *>::iterator it = nodes.begin(); it != nodes.end(); it++) { // nodeIDtoIndex[it->second->ID] = it->first; // nodeIndexToID[it->first] = it->second->ID; // } vector<vector<long>> scores(l1 + 1, vector<long>(l2 + 1)); if (globalAlign) { for (int i = 1; i < l2 + 1; i++) { scores[0][i] = openGapValue + (i - 1) * extendGapValue; } nodes = graph->nodes; index = 0; for (auto nodeID : graph->nodeOrder) { auto mIter = graph->nodes[nodeID]; auto prevIndexs = prevIndices(mIter, nodeIDtoIndex); scores[0][0] = openGapValue - extendGapValue; long best = scores[prevIndexs.front() + 1][0]; for (auto lIter = prevIndexs.begin(); lIter != prevIndexs.end(); lIter++) { best = max(best, scores[*lIter + 1][0]); } scores[index + 1][0] = best + extendGapValue; scores[0][0] = 0; index++; } } vector<vector<unsigned long>> backStrIdx(l1 + 1, vector<unsigned long>(l2 + 1)); vector<vector<unsigned long>> backGrphIdx(l1 + 1, vector<unsigned long>(l2 + 1)); vector<char> seqvec; copy(sequence.begin(), sequence.end(), back_inserter(seqvec)); vector<vector<long>> insertCost(l1 + 1, vector<long>(l2 + 1, this->openGapValue)); // memset(*insertCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1)); vector<vector<long>> deleteCost(l1 + 1, vector<long>(l2 + 1, this->openGapValue)); // memset(deleteCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1)); // fill(&insertCost[0][0], &insertCost[l1][l2], this->openGapValue); // fill(&deleteCost[0][0], &deleteCost[l1][l2], this->openGapValue); vector<bool> inserted(l2 + 1, false); vector<long> insertScore(l2 + 2, 0); char gbase; vector<unsigned long> predecessors; vector<long> matchPoints, deleteScore(l2), matchScore(l2); vector<unsigned long> bestDelete(l2), bestMatch(l2); vector<bool> deleted; index = 0; for (auto nodeID : graph->nodeOrder) { auto it = nodes[nodeID]; gbase = it->base; predecessors = prevIndices(it, nodeIDtoIndex); matchPoints = matchScoreVec(gbase, seqvec); deleteScore.clear(); for (int j = 1; j < l2 + 1; j++) { deleteScore.push_back(scores[predecessors.front() + 1][j] + deleteCost[predecessors.front() + 1][j]); matchScore[j - 1] = scores[predecessors.front() + 1][j - 1] + matchPoints[j - 1]; } auto fill_value = predecessors.front() + 1; fill(bestDelete.begin(), bestDelete.end(), fill_value); fill(bestMatch.begin(), bestMatch.end(), fill_value); for (auto it2 = next(predecessors.begin()); it2 != predecessors.end(); it2++) { vector<long> newDeleteScore; vector<long> newMatchScore; for (int j = 1; j < l2 + 1; j++) { newDeleteScore.push_back(scores[*it2 + 1][j] + deleteCost[*it2 + 1][j]); newMatchScore.push_back(scores[*it2 + 1][j - 1] + matchPoints[j - 1]); } for (int i = 0; i < l2; i++) { bestDelete[i] = newDeleteScore[i] > deleteScore[i] ? *it2 + 1 : bestDelete[i]; bestMatch[i] = newMatchScore[i] > matchScore[i] ? *it2 + 1 : bestMatch[i]; } for (int i = 0; i < l2; i++) { deleteScore[i] = max(newDeleteScore[i], deleteScore[i]); matchScore[i] = max(newMatchScore[i], matchScore[i]); } } deleted.clear(); for (unsigned long i = 0; i < l2; i++) { deleted.push_back(deleteScore[i] > matchScore[i]); } for (unsigned long j = 1; j < l2 + 1; j++) { scores[index + 1][j] = deleteScore[j - 1] >= matchScore[j - 1] ? deleteScore[j - 1] : matchScore[j - 1]; backGrphIdx[index + 1][j] = deleted[j - 1] ? bestDelete[j - 1] : bestMatch[j - 1]; backStrIdx[index + 1][j] = deleted[j - 1] ? j : j - 1; deleteCost[index + 1][j] = deleted[j - 1] ? extendGapValue : deleteCost[index + 1][j]; } //insertions fill(inserted.begin(), inserted.end(), false); for (int j = 0; j < l2 + 1; j++) { insertScore[j] = scores[index + 1][j] + insertCost[index + 1][j]; } for (unsigned long j = 0; j < l2; j++) { if (insertScore[j] > scores[index + 1][j + 1]) { scores[index + 1][j + 1] = insertScore[j]; insertCost[index + 1][j + 1] = extendGapValue; backStrIdx[index + 1][j + 1] = j; inserted[j + 1] = true; insertScore[j + 1] = scores[index + 1][j + 1] + insertCost[index + 1][j + 1]; } } for (int j = 1; j < l2 + 1; j++) { if (inserted[j]) { insertCost[index + 1][j] = extendGapValue; deleteCost[index + 1][j] = openGapValue; backGrphIdx[index + 1][j] = index + 1; } } if (!globalAlign) { for (int j = 0; j < l2; j++) { backGrphIdx[nodeID + 1][j] = scores[nodeID + 1][j] > 0 ? backGrphIdx[nodeID + 1][j] : (unsigned long) -1; backStrIdx[nodeID + 1][j] = scores[nodeID + 1][j] > 0 ? backStrIdx[nodeID + 1][j] : (unsigned long) -1; scores[nodeID + 1][j] = max(scores[nodeID + 1][j], 0L); } } index++; } return backTrack(l1, l2, scores, backStrIdx, backGrphIdx, nodeIndexToID); }
pair<vector<unsigned long>,vector<unsigned long>> SeqGraphAlignment::alignStringToGraphSimple() { unsigned long l1 = graph->numberOfNodes; unsigned long l2 = sequence.length(); unordered_map<unsigned long, unsigned long> nodeIDtoIndex; unordered_map<unsigned long, unsigned long> nodeIndexToID; nodeIndexToID[-1] = (unsigned long) -1; auto nodes = graph->nodes; unsigned long index = 0; for (auto nodeID : graph->nodeOrder) { nodeIDtoIndex[nodeID] = index; nodeIndexToID[index] = nodeID; index++; } vector<vector<long>> scores(l1 + 1, vector<long>(l2 + 1)); if (globalAlign) { for (unsigned long i = 1; i < l2 + 1; i++) { scores[0][i] = openGapValue + (i - 1) * extendGapValue; } nodes = graph->nodes; index = 0; for (auto nodeID : graph->nodeOrder) { auto mIter = graph->nodes[nodeID]; auto prevIndexs = prevIndices(mIter, nodeIDtoIndex); scores[0][0] = openGapValue - extendGapValue; long best = scores[prevIndexs.front() + 1][0]; for (auto lIter = prevIndexs.begin(); lIter != prevIndexs.end(); lIter++) { best = max(best, scores[*lIter + 1][0]); } scores[index + 1][0] = best + extendGapValue; scores[0][0] = 0; index++; } } vector<vector<unsigned long>> backStrIdx(l1 + 1, vector<unsigned long>(l2 + 1)); vector<vector<unsigned long>> backGrphIdx(l1 + 1, vector<unsigned long>(l2 + 1)); // map<tuple<int,int>,int> insertCost, deleteCost; int insertCost[l1 + 1][l2 + 1]; // memset(*insertCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1)); int deleteCost[l1 + 1][l2 + 1]; // memset(deleteCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1)); fill_n(*insertCost, (l1+1) * (l2+1), this->openGapValue); fill_n(*deleteCost, (l1+1) * (l2+1), this->openGapValue); char gbase; vector<char> seqvec; copy(sequence.begin(), sequence.end(), back_inserter(seqvec)); index = 0; for (auto nodeID : graph->nodeOrder) { auto it = nodes[nodeID]; gbase = it->base; unsigned long index2=0; for (vector<char>::iterator it3 = seqvec.begin(); it3 != seqvec.end(); it3++) { long best1=scores[index+1][index2] + insertCost[index+1][index2]; unsigned long best2=index+1; unsigned long best3=index2; string best4="INS"; auto predIndex = prevIndices(it, nodeIDtoIndex); for (auto it2 = predIndex.begin(); it2 != predIndex.end(); it2++) { if( best1 < (scores[*it2+1][index2] + matchScore(*it3,gbase)) || best2 < (*it2+1) || best3 < index2 ) { best1 = (scores[*it2+1][index2] + matchScore(*it3,gbase)); best2 = (*it2+1); best3 = index2; best4 = "MATCH"; } if( best1 < (scores[*it2+1][index2+1] + deleteCost[*it2+1][index2]) || best2 < (*it2+1) || best3 < index2 ) { best1 = (scores[*it2+1][index2+1] + deleteCost[*it2+1][index2]); best2 = (*it2+1); best3 = index2+1; best4 = "DEL"; } } scores[index+1][index2+1] = best1; backGrphIdx[index+1][index2+1] = best2; backStrIdx[index+1][index2+1] = best3; if(best4 == "INS") { insertCost[index+1][index2+1] = extendGapValue; } else if(best4 == "DEL") { deleteCost[index+1][index2+1] = extendGapValue; } } } return backTrack(l1, l2, scores, backStrIdx, backGrphIdx, nodeIndexToID); }
void NDalgorithm::forward(char *A, int32 Alen, char *T, int32 Tlen, int32 &A_End, int32 &T_End, bool &Match_To_End) { assert (Alen <= Tlen); int32 Best_d = 0; int32 Best_e = 0; int32 Best_row = 0; int32 Best_score = 0; int32 Row = 0; int32 Dst = 0; int32 Err = 0; int32 Sco = 0; int32 fromd = 0; // Skip ahead over matches. The original used to also skip if either sequence was N. while ((Row < Alen) && (isMatch(A[Row], T[Row]))) { Sco += matchScore(A[Row], T[Row]); Row++; } if (Edit_Array_Lazy[0] == NULL) allocateMoreEditSpace(); Edit_Array_Lazy[0][0].row = Row; Edit_Array_Lazy[0][0].dist = Dst; Edit_Array_Lazy[0][0].errs = 0; Edit_Array_Lazy[0][0].score = Sco; Edit_Array_Lazy[0][0].fromd = INT32_MAX; // Exact match? if (Row == Alen) { A_End = Alen; T_End = Alen; Match_To_End = true; Right_Score = Sco; Right_Delta_Len = 0; return; } int32 Left = 0; int32 Right = 0; int32 Max_Score = PEDMINSCORE; int32 Max_Score_Len = 0; int32 Max_Score_Best_d = 0; int32 Max_Score_Best_e = 0; for (int32 ei=1; ei <= Edit_Space_Max; ei++) { if (Edit_Array_Lazy[ei] == NULL) if (allocateMoreEditSpace() == false) { // FAIL return; } Left = MAX (Left - 1, -ei); Right = MIN (Right + 1, ei); //fprintf(stderr, "FORWARD ei=%d Left=%d Right=%d\n", ei, Left, Right); Edit_Array_Lazy[ei-1][Left - 1].init(); Edit_Array_Lazy[ei-1][Left ].init(); // Of note, [0][0] on the first iteration is not reset here. Edit_Array_Lazy[ei-1][Right ].init(); Edit_Array_Lazy[ei-1][Right + 1].init(); for (int32 d = Left; d <= Right; d++) { // A mismatch. { int32 aPos = (1 + Edit_Array_Lazy[ei-1][d].row) - 1; // -1 because we need to compare the base we are at, int32 tPos = (1 + Edit_Array_Lazy[ei-1][d].row) + d - 1; // not the base we will be at after the mismatch Row = 1 + Edit_Array_Lazy[ei-1][d].row; Dst = Edit_Array_Lazy[ei-1][d].dist + 1; Err = Edit_Array_Lazy[ei-1][d].errs + 1; fromd = d; // If positive, we have a pointer into valid sequence. If not, this mismatch // doesn't make sense, and the row/score are set to bogus values. if ((aPos >= 0) && (tPos >= 0)) { assert (aPos <= Alen); assert( tPos <= Tlen); assert(A[aPos] != T[tPos]); Sco = Edit_Array_Lazy[ei-1][d].score + mismatchScore(A[aPos], T[tPos]); } else { Sco = PEDMINSCORE; } } // Insert a gap in A. Check the other sequence to see if this is a zero-cost gap. Note // agreement with future value of Row and what is used in isMatch() below. { int32 tPos = 0 + Edit_Array_Lazy[ei-1][d-1].row + d; //assert(tPos >= 0); //assert(tPos < Tlen); if ((tPos >= 0) && (tPos <= Tlen)) { int32 gapCost = isFreeGap( T[tPos] ) ? PEDFREEGAP : PEDGAP; //if (gapCost == 0) // fprintf(stderr, "NDalgorithm::forward()-- free A gap for aPos=%d tPos=%d t=%c/%d\n", tPos - d, tPos, T[tPos], T[tPos]); if (Edit_Array_Lazy[ei-1][d-1].score + gapCost > Sco) { Row = Edit_Array_Lazy[ei-1][d-1].row; Dst = Edit_Array_Lazy[ei-1][d-1].dist + (gapCost == PEDFREEGAP) ? 0 : 0; Err = Edit_Array_Lazy[ei-1][d-1].errs + (gapCost == PEDFREEGAP) ? 0 : 0; Sco = Edit_Array_Lazy[ei-1][d-1].score + gapCost; fromd = d-1; } } } // Insert a gap in T. // Testcase test-st-ts shows this works. { int32 aPos = 1 + Edit_Array_Lazy[ei-1][d+1].row; //assert(aPos >= 0); //assert(aPos < Tlen); if ((aPos >= 0) && (aPos <= Alen)) { int32 gapCost = isFreeGap( A[aPos] ) ? 0 : PEDGAP; //if (gapCost == 0) // fprintf(stderr, "NDalgorithm::forward()-- free T gap for aPos=%d tPos=%d a=%c/%d\n", aPos, aPos + d, A[aPos], A[aPos]); if (Edit_Array_Lazy[ei-1][d+1].score + gapCost > Sco) { Row = 1 + Edit_Array_Lazy[ei-1][d+1].row; Dst = Edit_Array_Lazy[ei-1][d+1].dist + (gapCost == PEDFREEGAP) ? 0 : 1; Err = Edit_Array_Lazy[ei-1][d+1].errs + (gapCost == PEDFREEGAP) ? 0 : 1; Sco = Edit_Array_Lazy[ei-1][d+1].score + gapCost; fromd = d+1; } } } // If A or B is N, that isn't a mismatch. // If A is lowercase and T is uppercase, it's a match. // If A is lowercase and T doesn't match, ignore the cost of the gap in B while ((Row < Alen) && (Row + d < Tlen) && (isMatch(A[Row], T[Row + d]))) { Sco += matchScore(A[Row], T[Row + d]); Row += 1; Dst += 1; Err += 0; } Edit_Array_Lazy[ei][d].row = Row; Edit_Array_Lazy[ei][d].dist = Dst; Edit_Array_Lazy[ei][d].errs = Err; Edit_Array_Lazy[ei][d].score = Sco; Edit_Array_Lazy[ei][d].fromd = fromd; //fprintf(stderr, "SET ei=%d d=%d -- row=%d dist=%d errs=%d score=%d fromd=%d\n", ei, d, Row, Dst, Err, Sco, fromd); if (Row == Alen || Row + d == Tlen) { A_End = Row; // One past last align position T_End = Row + d; Set_Right_Delta(ei, d); Match_To_End = true; return; //return(ei); } } // Over all diagonals. // Reset the band // // The .dist used to be .row. while ((Left <= Right) && (Left < 0) && (Edit_Array_Lazy[ei][Left].dist < Edit_Match_Limit[ Edit_Array_Lazy[ei][Left].errs ])) Left++; if (Left >= 0) while ((Left <= Right) && (Edit_Array_Lazy[ei][Left].dist + Left < Edit_Match_Limit[ Edit_Array_Lazy[ei][Left].errs ])) Left++; if (Left > Right) break; while ((Right > 0) && (Edit_Array_Lazy[ei][Right].dist + Right < Edit_Match_Limit[ Edit_Array_Lazy[ei][Right].errs ])) Right--; if (Right <= 0) while (Edit_Array_Lazy[ei][Right].dist < Edit_Match_Limit[ Edit_Array_Lazy[ei][Right].errs ]) Right--; assert (Left <= Right); for (int32 d = Left; d <= Right; d++) if (Edit_Array_Lazy[ei][d].score > Best_score) { Best_d = d; Best_e = ei; Best_row = Edit_Array_Lazy[ei][d].row; Best_score = Edit_Array_Lazy[ei][d].score; } if (Best_score > Max_Score) { Max_Score_Best_d = Best_d; Max_Score_Best_e = Best_e; Max_Score = Best_score; Max_Score_Len = Best_row; } } // Over all possible number of errors //fprintf(stderr, "NDalgorithm::forward()- iterated over all errors, return best found\n"); A_End = Max_Score_Len; T_End = Max_Score_Len + Max_Score_Best_d; Set_Right_Delta(Max_Score_Best_e, Max_Score_Best_d); Match_To_End = false; return; //return(Max_Score_Best_e); }