inline void adjustHeap(diagonalLine *L, int32 p, int32 n, uint32 qsLen) { uint32 q = L[p]._qsPos; uint32 d = L[p]._dsPos; uint32 l = qsLen - q - 1 + d; int32 c = (p << 1) + 1; // let c be the left child of p while (c < n) { // Find the larger of the two children // if ((c+1 < n) && compareLines(L+c, L+c+1, qsLen)) c++; // Does the node in question fit here? // if (compareLines(l, q, L+c, qsLen) == false) break; // Else, swap the parent and the child // L[p]._qsPos = L[c]._qsPos; L[p]._dsPos = L[c]._dsPos; // Move down the tree // p = c; c = (p << 1) + 1; } L[p]._qsPos = q; L[p]._dsPos = d; }
int IntersectionEventNode_compareData(IntersectionEventNode* node1, IntersectionEventNode* node2) { if (compareLines(node1->l1, node2->l1) < 0) { return -1; } else if (compareLines(node1->l1, node2->l1) == 0) { if (compareLines(node1->l2, node2->l2) < 0) { return -1; } else if (compareLines(node1->l2, node2->l2) == 0) { return 0; } else { return 1; } } else { return 1; } }
QList<QLineF> Snapper::findSnappingLines(const SnapLineMap &snappingLineMap, Qt::Orientation orientation, double snapLine, double lowerLimit, double upperLimit, QList<QRectF> *boundingRects) const { QList<QLineF> lineList; SnapLineMapIterator snappingLineIterator(snappingLineMap); while (snappingLineIterator.hasNext()) { snappingLineIterator.next(); if (compareLines(snapLine, snappingLineIterator.key())) { // near distance snapping lines lineList += createSnapLine(orientation, snappingLineIterator.key(), lowerLimit, upperLimit, snappingLineIterator.value().first); if (boundingRects != 0) boundingRects->append(snappingLineIterator.value().first); } } return lineList; }
inline void IntersectionEventList_appendNode( IntersectionEventList* intersectionEventList, Line* l1, Line* l2, IntersectionType intersectionType) { assert(compareLines(l1, l2) < 0); IntersectionEventNode* newNode = malloc(sizeof(IntersectionEventNode)); if (newNode == NULL) { return; } newNode->l1 = l1; newNode->l2 = l2; newNode->intersectionType = intersectionType; newNode->next = NULL; if (intersectionEventList->head == NULL) { intersectionEventList->head = newNode; } else { intersectionEventList->tail->next = newNode; } intersectionEventList->tail = newNode; intersectionEventList->count++; }
bool compareBlocks(HWND view1, HWND view2, const UserSettings& settings, diff_info& blockDiff1, diff_info& blockDiff2) { diff_info* pBlockDiff1 = &blockDiff1; diff_info* pBlockDiff2 = &blockDiff2; if (blockDiff1.len > blockDiff2.len) { std::swap(view1, view2); std::swap(pBlockDiff1, pBlockDiff2); } chunk_info chunk1(pBlockDiff1->off, pBlockDiff1->len); chunk_info chunk2(pBlockDiff2->off, pBlockDiff2->len); getWords(view1, settings, chunk1); getWords(view2, settings, chunk2); // Compare the two chunks const std::vector<diff_info> chunkDiff = DiffCalc<Word>(chunk1.words, chunk2.words)(); const int chunkDiffSize = static_cast<int>(chunkDiff.size()); if (chunkDiffSize == 0) return false; std::vector<std::vector<int>> linesConvergence(chunk1.lineCount, std::vector<int>(chunk2.lineCount, 0)); // Use the MATCH results to synchronize line numbers (count the match length of each line) int wordOffset = 0; for (int i = 0; i < chunkDiffSize; ++i) { const diff_info& cd = chunkDiff[i]; if (cd.type == diff_type::DIFF_DELETE) { wordOffset -= cd.len; } else if (cd.type == diff_type::DIFF_INSERT) { wordOffset += cd.len; } else // diff_type::DIFF_MATCH { for (int wordIdx = cd.off; wordIdx < (cd.off + cd.len); ++wordIdx) { const Word& word1 = chunk1.words[wordIdx]; const Word& word2 = chunk2.words[wordIdx + wordOffset]; if (word1.type != charType::SPACECHAR) linesConvergence[word1.line][word2.line] += word1.length; } } } // Select the line with the most matches (as length) for (int line1 = 0; line1 < chunk1.lineCount; ++line1) { if (pBlockDiff1->isMoved(line1)) continue; int maxConvergence = 0; int line2 = 0; for (int i = 0; i < chunk2.lineCount; ++i) { if (!pBlockDiff2->isMoved(i) && linesConvergence[line1][i] > maxConvergence) { line2 = i; maxConvergence = linesConvergence[line1][i]; } } // Make sure that the line is matched and the other line is not already matched if (maxConvergence == 0 || chunk2.lineMappings[line2] != -1) continue; int line1Size = 0; for (int i = chunk1.lineStartWordIdx[line1]; i < chunk1.lineEndWordIdx[line1]; ++i) { const Word& word1 = chunk1.words[i]; if (word1.type != charType::SPACECHAR) line1Size += word1.length; } // Is enough portion of the line matched to be significant? if (line1Size && maxConvergence > (line1Size / 3)) { chunk1.lineMappings[line1] = line2; chunk2.lineMappings[line2] = line1; } } compareLines(*pBlockDiff1, *pBlockDiff2, chunk1, chunk2); return true; }
int main(int argc, char **argv) { bool nufftMode = false; int arg; while ((arg = getopt(argc, argv, "nh")) != -1) { switch (arg) { case 'n': nufftMode = true; break; default: case 'h': usage(argv); } } unsigned numFiles = argc - optind; if(numFiles < 2) { usage(argv); } if(nufftMode && (numFiles != 2)) { printf("***NUFFT mode requires two input files.\n"); exit(1); } /* open TextParsers for each input file */ char *fileName[numFiles]; TextParser *parser[numFiles]; for(unsigned dex=0; dex<numFiles; dex++) { fileName[dex] = argv[optind + dex]; parser[dex] = new TextParser(fileName[dex]); } /* * The header of all outputs looks like this: * * Library : MatrixFFT * FFT type : Two-dimension complex * Precision : Single * Signal type : Chirp * Loops : 10 * Threads : 8 * Options : Don't time first loop, In-place * System : Version 10.6 (Build 10A110) * CPU : Intel(R) Xeon(R) CPU X5482 @ 3.20GHz * Built as : 64 bit * Complex : Interleaved * Test time : 14:02:29 Oct 6 2008 * * "Loops", "Threads", and "Options" lines are optional. * Do basic validation by getting "Library Type" for each file. */ char libType[numFiles][LINE_LENGTH_MAX]; for(unsigned dex=0; dex<numFiles; dex++) { if(fineLineWithTitle(*parser[dex], "Library", libType[dex])) { printf("***%s is not an FFT output file\n", fileName[dex]); exit(1); } } /* * Make sure precisions, FFT types, and signal types match; * log them as well as log test time for the first file. */ char lineBuf[LINE_LENGTH_MAX]; bool match; for(unsigned dex=1; dex<numFiles; dex++) { if(compareLines(*parser[0], *parser[dex], "FFT type", match, lineBuf)) { printf("***No FFT type line found\n"); exit(1); } if(!match) { printf("***%s and %s measure different FFT types\n", fileName[0], fileName[dex]); exit(1); } } printf("%s\n", lineBuf); bool isConvolve = false; if(strstr(lineBuf, "Convolve")) { isConvolve = true; } for(unsigned dex=1; dex<numFiles; dex++) { if(compareLines(*parser[0], *parser[dex], "Precision", match, lineBuf)) { printf("***No Precision line found\n"); exit(1); } if(!match) { printf("***%s and %s measure different Precision\n", fileName[0], fileName[dex]); exit(1); } } printf("%s\n", lineBuf); for(unsigned dex=1; dex<numFiles; dex++) { if(compareLines(*parser[0], *parser[dex], "Signal type", match, lineBuf)) { printf("***No Signal type line found\n"); exit(1); } if(!match) { printf("***%s and %s measure different Signal types\n", fileName[0], fileName[dex]); exit(1); } } printf("%s\n", lineBuf); /* Optional "Threads" line - print it */ if(parser[0]->findLine("Threads", lineBuf)) { printf("%s\n", lineBuf); } /* and rewind this one in any case; we may be past the Test time line */ parser[0]->setCursor(0); /* * print following required fields: * system version (S/W) * CPU * Built as (32/64 bit) * Complex format * Test time * * NOTE: the Complex Format line anly applies to MatrixFFT; we generally * reuse data from one run of FFTW and vDSP for both Split and Interleaved * format MFFT builds. So, the MFFT file really needs to be specified * first to get the correct COmplex format in the collated output. */ if(!parser[0]->findLine("System", lineBuf)) { printf("***No System found\n"); exit(1); } printf("%s\n", lineBuf); if(!parser[0]->findLine("CPU", lineBuf)) { printf("***No CPU found\n"); exit(1); } printf("%s\n", lineBuf); if(!parser[0]->findLine("Built as", lineBuf)) { printf("***No Built as found\n"); exit(1); } printf("%s\n", lineBuf); if(!parser[0]->findLine("Complex", lineBuf)) { printf("***No Complex found\n"); exit(1); } printf("%s\n", lineBuf); if(!parser[0]->findLine("Test time", lineBuf)) { printf("***No Test Time found\n"); exit(1); } printf("%s\n\n", lineBuf); /* * The output we're parsing looks like this 2-D: * * Width | Height | Samples | Wall time (s) | CTGs * -----------+--------+------------+---------------+--------- * 1024 | 1024 | 1048576 | 0.606012 | 3.46058 * ... * * And for 1-D: * * Samples | Wall time (s) | CTGs * -----------+---------------+-------- * 1024 | 0.000013 | 3.86415 * * For convolve: * * Image Rows | Image Cols | Kernel size | Convolution time (s) * -----------+------------+-------------+--------------------- * * For NUFFT: * * Samples | Wall time (s) | ms/loop * ---------+---------------+---------- * 2^5 | 0.002 | 0.16 * * 1000 | 1000 | 3 | 0.07004 * * So, we generally use the column header line to figure out what kind of output we're * dealing with. */ if(!isConvolve && !nufftMode) { if(!parser[0]->findLine("Samples", lineBuf)) { printf("***Malformed input file (no Samples line)\n"); exit(1); } } unsigned totalTokens = 0; /* expected tokens per line */ unsigned ctgToken = 0; /* index of CTGs/time token */ unsigned matchTokens = 0; /* % of tokens that must match exactly */ bool is2Dim = false; const char **tokens = NULL; unsigned numTokens = parser[0]->parseLine(lineBuf, tokens); char *numStrings[3] = {NULL, NULL, NULL}; if(isConvolve) { is2Dim = true; totalTokens = 7; ctgToken = 6; matchTokens = 6; } else if(nufftMode) { is2Dim = false; totalTokens = 5; matchTokens = 2; ctgToken = 4; // not CTGs, but ms/loop, and we print it as a string } else { switch(numTokens) { case 7: /* 1-dim */ is2Dim = false; totalTokens = 5; ctgToken = 4; matchTokens = 2; break; case 11: /* 2-dim */ is2Dim = true; totalTokens = 9; ctgToken = 8; matchTokens = 6; break; default: printf("***Malformed input file (3)\n"); exit(1); } } parser[0]->freeTokens(numTokens, tokens); /* Skip ahead to first actual data in all files */ for(unsigned dex=0; dex<numFiles; dex++) { if(!parser[dex]->findLine("-----------+", lineBuf)) { printf("***Malformed input file %s (1)\n", fileName[dex]); exit(1); } } if(isConvolve) { printf(" Image Rows | Image Cols | Kernel size "); for(unsigned dex=0; dex<numFiles; dex++) { printf("| %6s time (s) ", libType[dex]); } printf("\n"); printf(" -----------+------------+-------------"); for(unsigned dex=0; dex<numFiles; dex++) { printf("+-----------------"); } printf("\n"); } else if(nufftMode) { printf(" reference optimized\n"); printf(" Samples | ms/loop | ms/loop ratio\n"); printf(" ---------+-------------+-----------+--------\n"); } else if(is2Dim) { printf(" Width | Height | Samples "); for(unsigned dex=0; dex<numFiles; dex++) { char *title = centerStr(libType[dex], "CTGs", 11); printf("|%s", title); free(title); } printf("\n"); printf(" -------+--------+---------"); for(unsigned dex=0; dex<numFiles; dex++) { printf("+-----------"); } printf("\n"); } else { printf(" Samples "); for(unsigned dex=0; dex<numFiles; dex++) { char *title = centerStr(libType[dex], "CTGs", 11); printf("|%s", title); free(title); } printf("\n"); printf(" ---------"); for(unsigned dex=0; dex<numFiles; dex++) { printf("+-----------"); } printf("\n"); } while(1) { unsigned numTokensArr[numFiles]; const char **tokensArr[numFiles]; /* We quit when any file runs out of data */ bool outOfData = false; for(unsigned dex=0; dex<numFiles; dex++) { if(parser[dex]->getTokens(numTokensArr[dex], tokensArr[dex])) { /* no more data */ outOfData = true; break; } if(numTokensArr[dex] == 0) { /* empty line */ outOfData = true; break; } } if(outOfData) { break; } /* verify all files have the right number of tokens */ for(unsigned dex=0; dex<numFiles; dex++) { if(numTokensArr[dex] != totalTokens) { printf("***Malformed input file %s (2)\n", fileName[dex]); exit(1); } } /* the first matchTokens tokens must match exactly */ for(unsigned fileDex=1; fileDex<numFiles; fileDex++) { for(unsigned tokenDex=0; tokenDex<matchTokens; tokenDex++) { if(strcmp(tokensArr[0][tokenDex], tokensArr[fileDex][tokenDex])) { /* maybe they are numbers printed with different representations.. */ size_t num1 = fftParseStringRep(tokensArr[0][tokenDex]); size_t num2 = fftParseStringRep(tokensArr[fileDex][tokenDex]); if((num1 != 0) && (num1 != num2)) { printf("***Mismatched input files\n"); exit(1); } } } } if(isConvolve) { printf(" %6s | %6s | %6s ", tokensArr[0][0], tokensArr[0][2], tokensArr[0][4]); for(unsigned dex=0; dex<numFiles; dex++) { printf("| %10s ", tokensArr[dex][ctgToken]); } printf("\n"); } else if(nufftMode) { /* * Though we print the ms/loop values as uninterpreted strings, we have to parse * them into floats in order to calculate the ratio. */ float f0 = strtof(tokensArr[0][ctgToken], NULL); float f1 = strtof(tokensArr[1][ctgToken], NULL); float ratio = f0 / f1; printf(" %6s | %8s | %8s | %5.1f\n", tokensArr[0][0], tokensArr[0][ctgToken], tokensArr[1][ctgToken], ratio); } else { /* * Convert all numbers to canonical form, no matter how they appear in * input files */ size_t n = fftParseStringRep(tokensArr[0][0]); numStrings[0] = fftStringRepPow2(n); if(is2Dim) { n = fftParseStringRep(tokensArr[0][2]); numStrings[1] = fftStringRepPow2(n); n = fftParseStringRep(tokensArr[0][4]); numStrings[2] = fftStringRepPow2(n); } if(is2Dim) { printf(" %-6s | %-6s | %-6s ", numStrings[0], numStrings[1], numStrings[2]); for(unsigned dex=0; dex<numFiles; dex++) { printf("| %8s ", tokensArr[dex][ctgToken]); } printf("\n"); } else { printf(" %-6s ", numStrings[0]); for(unsigned dex=0; dex<numFiles; dex++) { printf("| %7s ", tokensArr[dex][ctgToken]); } printf("\n"); } free(numStrings[0]); if(is2Dim) { free(numStrings[1]); free(numStrings[2]); } } for(unsigned dex=0; dex<numFiles; dex++) { parser[dex]->freeTokens(numTokensArr[dex], tokensArr[dex]); } } printf("\n"); /* clean up */ for(unsigned dex=0; dex<numFiles; dex++) { delete parser[dex]; } return 0; }
// Detect if lines l1 and l2 will intersect between now and the next time step. inline IntersectionType intersect(Line *l1, Line *l2, double time) { assert(compareLines(l1, l2) < 0); if (!rectanglesOverlap(l1, l2)) { return NO_INTERSECTION; } Vec p1 = {.x = l2->p3.x - l1->delta.x, .y = l2->p3.y - l1->delta.y}; Vec p2 = {.x = l2->p4.x - l1->delta.x, .y = l2->p4.y - l1->delta.y}; if (intersectLines(l1->p1, l1->p2, l2->p1, l2->p2)) { return ALREADY_INTERSECTED; } int num_line_intersections = 0; bool top_intersected = false; bool bot_intersected = false; if (intersectLines(l1->p1, l1->p2, p1, p2)) { num_line_intersections++; } if (intersectLines(l1->p1, l1->p2, p1, l2->p1)) { num_line_intersections++; top_intersected = true; } if (intersectLines(l1->p1, l1->p2, p2, l2->p2)) { num_line_intersections++; bot_intersected = true; } if (num_line_intersections == 2) { return L2_WITH_L1; } if (pointInParallelogram(l1->p1, l2->p1, l2->p2, p1, p2) && pointInParallelogram(l1->p2, l2->p1, l2->p2, p1, p2)) { return L1_WITH_L2; } if (num_line_intersections == 0) { return NO_INTERSECTION; } Vec v1 = Vec_makeFromLine(*l1); Vec v2 = Vec_makeFromLine(*l2); double angle = Vec_angle(v1, v2); if ((top_intersected && angle < 0) || (bot_intersected && angle > 0)) { return L2_WITH_L1; } return L1_WITH_L2; } // Check if a point is in the parallelogram. inline bool pointInParallelogram(Vec point, Vec p1, Vec p2, Vec p3, Vec p4) { double d1 = direction(p1, p2, point); double d2 = direction(p3, p4, point); double d3 = direction(p1, p3, point); double d4 = direction(p2, p4, point); return d1 * d2 < 0 && d3 * d4 < 0; } // Check if two lines intersect. inline bool intersectLines(Vec p1, Vec p2, Vec p3, Vec p4) { return side(p1, p2, p3) != side(p1, p2, p4) && side(p3, p4, p1) != side(p3, p4, p2); } // Obtain the intersection point for two intersecting line segments. inline Vec getIntersectionPoint(Vec p1, Vec p2, Vec p3, Vec p4) { double u; u = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / ((p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)); Vec p; p.x = p1.x + (p2.x - p1.x) * u; p.y = p1.y + (p2.y - p1.y) * u; return p; }