📄 matvec.cpp
字号:
pFile = Fopen(sIndexFile1, "w");Fprintf(pFile, "si %s\n", sIndexFile1); // si is magic number for string index filesfor (int i = 0; i < iMat; i++) Fprintf(pFile, "%s`%ld\n", gIndexTab[i].s, gIndexTab[i].iPos); // backquote ` used as a delimiterfclose(pFile);if (fVerbose) lprintf("%d mats in %s\n", iMat, sIndexFile1);}//-----------------------------------------------------------------------------// Return -2: no index file// -1: not in index file// 0..N: index of vector, and M, sTagstatic int iReadSelectedMatGivenRegExpUsingIndexFile (Mat &M, char *sTag, // out const char sMatFile[], FILE *pMatFile, // in const char sTagRegExp[], bool fPlainString=false, // in bool fVerbose=false, bool fPrintAssociatedString=false) // in{static IndexTabStruct Tab[CONF_nMaxMatVec]; // table of matrix labels and offsets (i.e memory table of index file)static int nMats; // nbr of entries in Tabstatic char sIndexedFile[SLEN]; // name of file currently held in Tabint iMat;regex_t CompiledRegExp;if (!fPlainString && (0 != regcomp(&CompiledRegExp, sTagRegExp, REG_EXTENDED|REG_ICASE|REG_NOSUB))) SysErr("Invalid regular expression %s", sTagRegExp);int iRet = -2; // assume we can't open index filebool fFound = false;if (nMats == 0 || strcmp(sIndexedFile, sMatFile)) // table not initialized (for this file)? { char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT], sIndexFile[_MAX_PATH]; _splitpath(sMatFile, sDrive, sDir, sFname, sExt); _makepath(sIndexFile, sDrive, sDir, sFname, ".index"); if (fVerbose) lprintf("Building index table from %s\n", sIndexFile); FILE *pFile = fopen(sIndexFile, "r"); if (pFile) { if (fVerbose) lprintf("Reading %s\n", sIndexFile); nMats = 0; strcpy(sIndexedFile, sMatFile); // header line, of the form "si anything" where si is the magic number for shape index files char sLine[SLEN]; if (!fgets(sLine, 200-1, pFile)) SysErr("Can't read index file %s header"); if (sLine[0] != 's' || sLine[1] != 'i') SysErr("File %s is not an index file, bad header: %s", sIndexFile, sLine); // line is of the form "0000 000_11.pgm`15690" where backquote ` is a separator while (fgets(sLine, 200-1, pFile)) { char *p = strchr(sLine, '`'); // replace tilde with 0 if (!p) SysErr("No terminating backquote ` in index file %s: %s", sIndexFile, sLine); *p = 0; if (p - sLine >= FLEN) SysErr("Index file %s: line too long, max is %d: %s", sIndexFile, FLEN, sLine); strcpy(Tab[nMats].s, sLine); long iPos = -1; if (1 != sscanf(p + 1, "%ld", &iPos) || iPos < 0) SysErr("Can't get file pos from index file %s: %s", sIndexFile, sLine); Tab[nMats].iPos = iPos; nMats++; } fclose(pFile); } }if (nMats) // table initialized? { iRet = -1; if (fVerbose) lprintf("Search for %s in index table\n", sTagRegExp); if (fPlainString) // plain string (not a regex)? { // yes, do a binary search void *p = bsearch(sTagRegExp, (void *)Tab, nMats, sizeof(Tab[0]), CompareTab); if (p) { iMat = (IndexTabStruct *)p - &Tab[0]; fFound = true; } } else { for (iMat = 0; iMat < nMats; iMat++) // linear search { if (fRegExpMatch(CompiledRegExp, Tab[iMat].s)) { fFound = true; break; } } } if (fFound) { if (fVerbose) lprintf("Found at %d, reading %s", Tab[iMat].iPos, sMatFile); FILE *pFile = Fopen(sMatFile, "r"); if (0 != fseek(pFile, Tab[iMat].iPos, 0)) SysErr("Fseek %d in index file %s failed", Tab[iMat].iPos, sMatFile); M.sread(sMatFile, pFile, sTag); fclose(pFile); if (fVerbose) { lprintf(", extracted matrix %d", iMat); if (fPrintAssociatedString && sTag) lprintf(": %s", sTag); lprintf("\n"); } // cross check: make sure what we have is what we specified if ((fPlainString && strcmp(sTagRegExp, sTag)) || (!fPlainString && !fRegExpMatch(CompiledRegExp, sTag))) SysErr("Match %s in index file %s returned wrong matrix %s\n" " (corrupt index file? run makeShapeIndexFile)", sTagRegExp, sMatFile, sTag); } }if (!fPlainString) regfree(&CompiledRegExp);if (fFound) return iMat;else return iRet;}//-----------------------------------------------------------------------------// Read one matrix embedded in a matrix vector file, looking for a match on// the tag string prefixing each matrix. We match the string against sTagRegExp, ignoring case.// If fPlainString is true then sTagRegExp is actually just a string and// we search faster (use a binary instead of a linear search through index table).//// Returns index of the matrix, or <0 if couldn't find a match.// If sTag is not null, we copy the string associated with the matrix to sTag.//// Will call Err if the regular expression is invalidint iReadSelectedMatGivenRegExp (Mat &M, char sTag[], // out const char sMatFile[], FILE *pMatFile, // in const char sTagRegExp[], bool fPlainString, // in bool fVerbose, bool fPrintAssociatedString) // in{int iRet = -1;iRet = iReadSelectedMatGivenRegExpUsingIndexFile(M, sTag, sMatFile, pMatFile, sTagRegExp, fPlainString, fVerbose, fPrintAssociatedString);if (iRet == -2) // no index file? { lprintf("No index file for %s\n", sMatFile); regex_t CompiledRegExp; if (0 != regcomp(&CompiledRegExp, sTagRegExp, REG_EXTENDED|REG_ICASE|REG_NOSUB)) SysErr("Invalid regular expression %s", sTagRegExp); // use a brute force method: read 'em all, pick one MatVec MatV; StringVec StringV; ReadMatVec(&MatV, &StringV, sMatFile, pMatFile, NULL, 0, 0, 0, MAT_NO_CHECK_SAME_DIM, fVerbose, fVerbose); for (int iMat = 0; iMat < MatV.size(); iMat++) // linear search if (fRegExpMatch(CompiledRegExp, StringV[iMat].c_str())) break; // found it if (iMat < MatV.size()) // success? { iRet = iMat; M = MatV[iMat]; strcpy(sTag, StringV[iMat].c_str()); if (fVerbose) { lprintf(", extracted matrix %d", iMat); if (fPrintAssociatedString) lprintf(": %s", sTag); lprintf("\n"); } } regfree(&CompiledRegExp); }return iRet;}//-----------------------------------------------------------------------------// PrintMatVec() prints a vector of matrices, all parameters except aMats are optional//// If sMsg is specified it gets printed in the file before the matrices//// sFormat is a printf style format string for printing matrice elements e.g. "%g "// Default sFormat is the class static variable sPrintFormat,// change the default with setPrintFormat().//// If sFile and pFile both null prints using lprintf// If pFile specified writes to it (and uses sFile only for user msgs)// If sFile specified but pFile null then opens sFile and writes to it and then closes it//// nMax is max rows/cols to print, 0 for all//// If fPrintRowIndex is true then prefixes each row with the row index// If pFile is NULL then a new file is opened. Else we append to pFile and sFile is// just used for user messages.//// Within this function, the matrix size is passed as a printf param to sMsg// which you can use if you want (use %d in sMsg).void PrintMatVec (MatVec &MatV, const char sMsg[], const char sFormat[], const char *sFile, FILE *pFile, int nMax, bool fPrintRowIndex){bool fCloseFile = false;ASSERT(!(pFile && !sFile)); // you must give a file name for error reporting if pFile is givenif (sFile && pFile == NULL) { pFile = Fopen(sFile, "w") ; fCloseFile = true; }if (sMsg) if (pFile) Fprintf(pFile, sMsg, MatV.size()); else lprintf(sMsg, MatV.size());if (MatV.empty()) { if (pFile) Fprintf(pFile, "EMPTY\n"); else lprintf("EMPTY\n"); }else for (MatVec::iterator Iter = MatV.begin(); Iter != MatV.end(); Iter++) { char s[32]; sprintf(s, "Mat %d:\n", Iter-MatV.begin()); Iter->print(s, sFormat, sFile, pFile, nMax, fPrintRowIndex); }if (fCloseFile) fclose(pFile);}//-----------------------------------------------------------------------------// WriteMatVec writes a vector of matrices//// sMatVecComment is an optional commnent printed before all matrices// sMatComment is an optional comment printed before each matrix. It get printed followed by matrix nbr.// TagStrings is an optional array of strings, print a string before each matrix.//// If pFile is NULL then it is opened. If pFile is already open then we append// to it (and sFile isn't used except for user messages).void WriteMatVec (const MatVec MatV, const char *sFile, FILE *pFile, const char *sMatVecComment, const char *sMatComment, StringVec *pTagStrings, bool fVerbose, char *sFormat){bool fCloseFile = false;ASSERT(!(pFile && !sFile)); // must give a file name for error reporting if pFile is givenif (pFile == NULL) { pFile = Fopen(sFile, "w") ; fCloseFile = true; }if (sMatVecComment) Fprintf(pFile, "# %s", sMatVecComment);for (MatVec::const_iterator Iter = MatV.begin(); Iter != MatV.end(); Iter++) { if (sMatComment) { char s[SLEN]; sprintf(s, "%s %d", sMatComment, Iter-MatV.begin()); Fprintf(pFile, "# %s\n", s); } if (pTagStrings) { int i = Iter-MatV.begin(); if ((*pTagStrings)[i][0]) Fprintf(pFile, "\"%s\"\n", (*pTagStrings)[i].c_str()); } Iter->write(sFile, pFile, fVerbose, NULL, sFormat); }if (fCloseFile) fclose(pFile);}//-----------------------------------------------------------------------------// Same as PrintMatVec but for MatVecView// TODO why can't I combined this with PrintMatVec?void PrintMatVec (MatViewVec &MatV, const char sMsg[], const char sFormat[], const char *sFile, FILE *pFile, int nMax, bool fPrintRowIndex){bool fCloseFile = false;ASSERT(!(pFile && !sFile)); // you must give a file name for error reporting if pFile is givenif (sFile && pFile == NULL) { pFile = Fopen(sFile, "w") ; fCloseFile = true; }if (sMsg) if (pFile) Fprintf(pFile, sMsg, MatV.size()); else lprintf(sMsg, MatV.size());if (MatV.empty()) { if (pFile) Fprintf(pFile, "EMPTY\n"); else lprintf("EMPTY\n"); }else for (MatViewVec::iterator Iter = MatV.begin(); Iter != MatV.end(); Iter++) { char s[32]; sprintf(s, "Mat %d:\n", Iter-MatV.begin()); Iter->print(s, sFormat, sFile, pFile, nMax, fPrintRowIndex); }if (fCloseFile) fclose(pFile);}//-----------------------------------------------------------------------------// If pFile is NULL then it is opened. If pFile is already open then we append// to it (and sFile isn't used except for user messages).void WriteMatVecAsCArray (const MatVec &MatV, const char sArrayName[], const char *sFile, FILE *pFile, const char *sType, bool fVerbose, bool fLimitOutputWidth){bool fCloseFile = false;ASSERT(!(pFile && !sFile)); // must give a file name for error reporting if pFile is givenif (pFile == NULL) { pFile = Fopen(sFile, "w") ; fCloseFile = true; }if (!sFile) // make sure we have something to print in user messages sFile = "file";int ncols = MatV[0].ncols();int nVecs = MatV.end() - MatV.begin();int nrowsTotal = 0;// write an offsets arrayFprintf(sFile, pFile, "// Indices of first array in %s are for n%sRows[0] to n%sRows[1]-1\n", sArrayName, sArrayName, sArrayName);Fprintf(sFile, pFile, "#ifdef DEFS_ONLY\n");Fprintf(sFile, pFile, "extern int n%s[%d];\n", sArrayName, nVecs+1);Fprintf(sFile, pFile, "#else\n");Fprintf(sFile, pFile, "int n%s[%d] = {\n\t", sArrayName, nVecs+1);int iVec = 0;Fprintf(sFile, pFile, "%d,", iVec);for (MatVec::const_iterator Iter = MatV.begin(); Iter != MatV.end(); Iter++) { DASSERT(ncols == Iter->ncols()); // must all have the same number of columns iVec += Iter->nrows(); int iMat = Iter - MatV.begin(); Fprintf(sFile, pFile, "%d%s", iVec, (iMat < nVecs-1? ",":"")); if ((iMat+1) % 12 == 0 && iMat < nVecs) // limit output width (up to 12 numbers per line) Fprintf(sFile, pFile, "\n\t"); nrowsTotal += Iter->nrows(); }Fprintf(sFile, pFile, "\n};\n");Fprintf(sFile, pFile, "#endif // DEFS_ONLY\n");// write the matrix vectorFprintf(sFile, pFile, "#ifdef DEFS_ONLY\n");Fprintf(sFile, pFile, "extern %s %s[%d][%d];\n", sType, sArrayName, nrowsTotal, ncols);Fprintf(sFile, pFile, "#else\n");Fprintf(sFile, pFile, "%s %s[%d][%d] = {\n", sType, sArrayName, nrowsTotal, ncols);for (Iter = MatV.begin(); Iter != MatV.end(); Iter++) { Fprintf(sFile, pFile, "// %s %d\n", sArrayName, Iter - MatV.begin()); Iter->writeAsCArray(NULL, sFile, pFile, sType, false, fVerbose); }Fprintf(sFile, pFile, "};\n");Fprintf(sFile, pFile, "#endif // DEFS_ONLY\n");if (fCloseFile) fclose(pFile);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -