bool IAddr_Func_EBPPrologue_UniqueStr::FindAddrWin(uintptr_t& addr) const { using StrRefScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, const char *>; const char *p_str = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetUniqueStr()); if (p_str == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr: \"%s\": failed to find ostensibly unique string\n", this->GetName()); return false; } CScan<StrRefScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::TEXT), p_str); if (!scan1.ExactlyOneMatch()) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr: \"%s\": found %u refs to ostensibly unique string\n", this->GetName(), scan1.Matches().size()); return false; } auto p_in_func = (const char **)scan1.FirstMatch(); auto p_func = Scan::FindFuncPrologue(p_in_func); if (p_func == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr: \"%s\": could not locate EBP prologue\n", this->GetName()); return false; } addr = (uintptr_t)p_func; return true; }
Local void processUsual(struct LOC_processLine *LINK) { if (hasVerseNumber(LINK->voice)) strcat(LINK->pretex, "\\mtxVerse"); LINK->l = pos1(multi_group, LINK->note); if (LINK->l > 0) scan1(LINK->note, LINK->l + 1, &LINK->nmulti); activateBeamsAndSlurs(LINK->voice); LINK->in_group = false; if (LINK->ngrace > 0) { LINK->in_group = true; LINK->ngrace--; } else { if (LINK->nmulti > 0) { LINK->in_group = true; LINK->nmulti--; } } checkOctave(LINK->voice, LINK->note); renewPitch(LINK->voice, LINK->note); if (!LINK->in_group) { resetDuration(LINK->voice, durationCode(LINK->note)); markDebeamed(LINK->voice, LINK->note); } lookahead(LINK); getSyllable(LINK->voice, LINK->pretex); addUptext(LINK->voice, &LINK->no_uptext, LINK->pretex); addChords(LINK); }
bool IAddr_Func_EBPPrologue_UniqueRef::FindAddrWin(uintptr_t& addr) const { using SymRefScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, const void *>; auto p_ref = AddrManager::GetAddr(this->GetUniqueSymbol()); if (p_ref == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueRef: \"%s\": no addr for ostensibly unique symbol\n", this->GetName()); return false; } CScan<SymRefScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::TEXT), p_ref); if (!scan1.ExactlyOneMatch()) { DevMsg("IAddr_Func_EBPPrologue_UniqueRef: \"%s\": found %u refs to ostensibly unique symbol\n", this->GetName(), scan1.Matches().size()); return false; } auto p_in_func = (const char **)scan1.FirstMatch(); auto p_func = Scan::FindFuncPrologue(p_in_func); if (p_func == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueRef: \"%s\": could not locate EBP prologue\n", this->GetName()); return false; } addr = (uintptr_t)p_func; return true; }
bool IAddr_Pattern::FindAddrWin(uintptr_t& addr) const { using PatternScanner = CMaskedScanner<ScanDir::FORWARD, ScanResults::ALL, 1>; const char *str_seek = this->GetPattern(); const char *str_mask = this->GetMask(); size_t strlen_seek = strlen(str_seek); size_t strlen_mask = strlen(str_mask); if (strlen_seek == 0) { DevMsg("IAddr_Pattern: \"%s\": empty pattern\n", this->GetName()); return false; } if (strlen_mask == 0) { DevMsg("IAddr_Pattern: \"%s\": empty mask\n", this->GetName()); return false; } if (strlen_seek != strlen_mask) { DevMsg("IAddr_Pattern: \"%s\": pattern and mask have differing numbers of digits\n", this->GetName()); return false; } if (strlen_seek % 2 == 1) { DevMsg("IAddr_Pattern: \"%s\": pattern and mask have odd number of digits\n", this->GetName()); return false; } size_t len = strlen_seek / 2; ByteBuf seek(len); ByteBuf mask(len); for (size_t i = 0; i < len; ++i) { char buf[3]; buf[2] = '\0'; memcpy(buf, str_seek + (i * 2), 2); seek[i] = std::stoi(buf, nullptr, 0x10); memcpy(buf, str_mask + (i * 2), 2); mask[i] = std::stoi(buf, nullptr, 0x10); } CScan<PatternScanner> scan1(CLibSegBounds(this->GetLibrary(), LibMgr::Seg_FromString(this->GetSegment())), seek, mask); if (!scan1.ExactlyOneMatch()) { DevMsg("IAddr_Pattern: \"%s\": found %u pattern matches\n", this->GetName(), scan1.Matches().size()); return false; } addr = (uintptr_t)scan1.FirstMatch(); return true; }
void Hash_Partition(int *ary, int size) { int *keyzonenum = (int*)malloc(sizeof(int) * size); assert(keyzonenum); memset(keyzonenum, 0, sizeof(int) * size); int *hisgram = (int*)malloc(sizeof(int) * ZONENUM); assert(hisgram); memset(hisgram, 0, sizeof(int) * ZONENUM); init(keyzonenum, size, ary); scan1(keyzonenum, hisgram, size); begin_addr(hisgram); scan2(keyzonenum, hisgram, size, ary); free(keyzonenum); free(hisgram); }
bool IAddr_DataDescMap::FindAddrWin(uintptr_t& addr) const { struct GetDataDescMap { bool operator==(const GetDataDescMap& that) const { return (memcmp(this, &that, sizeof(*this)) == 0); } uint8_t buf[6]; }; using ClassNameRefScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, const char *, 0x4>; using GetDataDescMapScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, GetDataDescMap, 0x10>; const char *p_str = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetClassName()); if (p_str == nullptr) { DevMsg("IAddr_DataDescMap: \"%s\": failed to find class name string\n", this->GetName()); return false; } CScan<ClassNameRefScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::DATA), p_str); std::vector<GetDataDescMapScanner *> scanners; for (auto match : scan1.Matches()) { GetDataDescMap gddm; gddm.buf[0x00] = 0xb8; // mov eax,[????????] *(uint32_t *)(&gddm.buf[0x01]) = (uint32_t)match - offsetof(datamap_t, dataClassName); gddm.buf[0x05] = 0xc3; // ret scanners.push_back(new GetDataDescMapScanner(CLibSegBounds(this->GetLibrary(), Segment::TEXT), gddm)); } CMultiScan<GetDataDescMapScanner> scan2(scanners); std::vector<const void *> results; for (auto scanner : scanners) { if (scanner->ExactlyOneMatch()) { results.push_back(scanner->FirstMatch()); } } if (results.size() != 1) { DevMsg("IAddr_DataDescMap: \"%s\": found %u matches for GetDataDescMap func\n", this->GetName(), results.size()); return false; } addr = *(uintptr_t *)((uintptr_t)results[0] + 1); return true; }
bool IAddr_Func_EBPPrologue_VProf::FindAddrWin(uintptr_t& addr) const { #if defined __GNUC__ #warning FIXME: VPROF_BUDGET finder is not reliable due to using first scan result #endif using VProfScanner = CBasicScanner<ScanDir::FORWARD, ScanResults::FIRST, 1>; const char *p_name = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetVProfName()); if (p_name == nullptr) { DevMsg("IAddr_Func_EBPPrologue_VProf: \"%s\": failed to find name string\n", this->GetName()); return false; } const char *p_group = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetVProfGroup()); if (p_group == nullptr) { DevMsg("IAddr_Func_EBPPrologue_VProf: \"%s\": failed to find group string\n", this->GetName()); return false; } uint8_t vprof[] = { 0x68, 0x00, 0x00, 0x00, 0x00, // push 0x???????? 0x68, 0x00, 0x00, 0x00, 0x00, // push 0x???????? }; *(const char **)(vprof + 0x01) = p_name; *(const char **)(vprof + 0x06) = p_group; CScan<VProfScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::TEXT), (const void *)vprof, sizeof(vprof)); if (!scan1.ExactlyOneMatch()) { DevMsg("IAddr_Func_EBPPrologue_VProf: \"%s\": could not locate VPROF_BUDGET\n", this->GetName()); return false; } auto p_in_func = scan1.FirstMatch(); auto p_func = Scan::FindFuncPrologue(p_in_func); if (p_func == nullptr) { DevMsg("IAddr_Func_EBPPrologue_VProf: \"%s\": could not locate EBP prologue\n", this->GetName()); return false; } addr = (uintptr_t)p_func; return true; }
bool IAddr_Func_EBPPrologue_NonUniqueStr_KnownVTIdx::FindAddrWin(uintptr_t& addr) const { using StrRefScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, const char *>; const char *p_str = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetStr()); if (p_str == nullptr) { DevMsg("IAddr_Func_EBPPrologue_NonUniqueStr_KnownVTIdx: \"%s\": failed to find string\n", this->GetName()); return false; } CScan<StrRefScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::TEXT), p_str); if (scan1.Matches().empty()) { DevMsg("IAddr_Func_EBPPrologue_NonUniqueStr_KnownVTIdx: \"%s\": no refs to string\n", this->GetName()); return false; } auto p_VT = RTTI::GetVTable(this->GetVTableName()); if (p_VT == nullptr) { DevMsg("IAddr_Func_EBPPrologue_NonUniqueStr_KnownVTIdx: \"%s\": no addr for vtable\n", this->GetName()); return false; } for (auto p_in_func : scan1.Matches()) { auto p_func = Scan::FindFuncPrologue(p_in_func); if (p_func == nullptr) { continue; } auto vfptr = p_VT[this->GetVTableIndex()]; if (vfptr == p_func) { addr = (uintptr_t)p_func; return true; } } DevMsg("IAddr_Func_EBPPrologue_NonUniqueStr_KnownVTIdx: \"%s\": found %u string refs, but none matched vtable entry\n", this->GetName(), scan1.Matches().size()); return false; }
bool IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx::FindAddrWin(uintptr_t& addr) const { using StrRefScanner = CTypeScanner<ScanDir::FORWARD, ScanResults::ALL, const char *>; const char *p_str = Scan::FindUniqueConstStr(this->GetLibrary(), this->GetUniqueStr()); if (p_str == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx: \"%s\": failed to find ostensibly unique string\n", this->GetName()); return false; } CScan<StrRefScanner> scan1(CLibSegBounds(this->GetLibrary(), Segment::TEXT), p_str); if (!scan1.ExactlyOneMatch()) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx: \"%s\": found %u refs to ostensibly unique string\n", this->GetName(), scan1.Matches().size()); return false; } auto p_in_func = (const char **)scan1.FirstMatch(); auto p_func = Scan::FindFuncPrologue(p_in_func); if (p_func == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx: \"%s\": could not locate EBP prologue\n", this->GetName()); return false; } auto p_VT = RTTI::GetVTable(this->GetVTableName()); if (p_VT == nullptr) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx: \"%s\": no addr for vtable\n", this->GetName()); return false; } auto vfptr = p_VT[this->GetVTableIndex()]; if (vfptr != p_func) { DevMsg("IAddr_Func_EBPPrologue_UniqueStr_KnownVTIdx: \"%s\": func addr (0x%08x) doesn't match vtable entry (0x%08x)\n", this->GetName(), (uintptr_t)p_func, (uintptr_t)vfptr); return false; } addr = (uintptr_t)p_func; return true; }
Static void processLine(voice_index voice_, short bar_no) { struct LOC_processLine V; paragraph_index par_line; Char STR1[256]; V.voice = voice_; *V.pretex = '\0'; V.no_chords = false; V.no_uptext = false; par_line = musicLineNo(V.voice); V.nmulti = 0; V.ngrace = 0; line_no = orig_line_no[par_line-1]; do { getMusicWord(V.note, V.voice); if (*V.note == '\0') return; /* if debugMode then writeln(voice,' ',note); */ switch (thisNote(V.voice)) { case rword: if (*multi_bar_rest != '\0') { if (uptextOnRests()) addUptext(V.voice, &V.no_uptext, V.pretex); } else { V.l = pos1(multi_group, V.note); if (V.l > 0) scan1(V.note, V.l + 1, &V.nmulti); if (V.nmulti > 0) { V.in_group = true; V.nmulti--; } if (uptextOnRests()) addUptext(V.voice, &V.no_uptext, V.pretex); if (!(isPause(V.note) || V.in_group)) /*0.63: allow rests in xtuples*/ resetDuration(V.voice, durationCode(V.note)); } break; case abcdefg: processUsual(&V); break; case barword: if (V.voice == nvoices) { if (endOfBar(V.voice, bar_no)) strcpy(repeat_sign, V.note); else writeRepeat(V.note); } sprintf(STR1, "%c", barsym); if (strcmp(V.note, STR1)) *V.note = '\0'; V.no_chords = false; break; case FirstOnly: if (V.voice != nvoices) *V.note = '\0'; else strcpy(V.note, processOther(STR1, V.note, &V)); break; default: strcpy(V.note, processOther(STR1, V.note, &V)); break; } output(V.note, &V); } while (!endOfBar(V.voice, bar_no)); if (!V.no_chords) skipChordBar(V.voice); }
int main(int argc, char * argv[]) { if (argc != 3) { std::cerr << "ERROR: Wrong number of arguments." << std::endl; std::cout << "Usage:\n\t" << argv[0] << " file1 file2" << std::endl; return 1; } std::ifstream file1(argv[1], std::ios_base::binary | std::ios_base::in), file2(argv[2], std::ios_base::binary | std::ios_base::in); if (!file1 || !file2) { std::cerr << "ERROR: Unable to open one or both files." << std::endl; return 2; } file1.unsetf(std::ios_base::skipws); file2.unsetf(std::ios_base::skipws); iterator iter_file1(file1), iter_file2(file2); scanner scan1(iter_file1, iterator()), scan2(iter_file2, iterator()); std::size_t line = 1, column = 1; while (!scan1.at_end() && !scan2.at_end()) { if (spirit::eol_p.parse(scan1)) { if (!spirit::eol_p.parse(scan2)) { std::cout << "Files differ at line " << line << ", column " << column << '.' << std::endl; return 3; } ++line, column = 1; continue; } if (*scan1 != *scan2) { std::cout << "Files differ at line " << line << ", column " << column << '.' << std::endl; return 4; } ++scan1, ++scan2, ++column; } if (scan1.at_end() != scan2.at_end()) { std::cout << "Files differ in length." << std::endl; return 5; } }
void match( int N, // number of nodes (must be even) double *total_weight, // cost of optimal matching int *nmatch, // matching array double (*cost)(int i, int j, void* data), void *data, // The following are work arrays each of length N int *basis, int *mem, int *ka, int *kb, int *sm, int *tma, int *tmb, int *m1, double *y1, double *y2, double *dplus, double *dminus ){ const int top = N + 1; for(int n1 = 0; n1 < N; ++n1){ basis[n1] = n1; mem[n1] = n1; y1[n1] = 0.0; y2[n1] = 0.0; sm[n1] = top; tma[n1] = top; tmb[n1] = top; nmatch[n1] = top; dplus[n1] = DBL_MAX; dminus[n1] = DBL_MAX; ka[n1] = -1; kb[n1] = n1; } // Start of main procedure for(int n1 = 0; n1 < N; ++n1){ if(nmatch[n1] != top){ continue; } int nn = -1; double d = DBL_MAX; for(int n2 = 0; n2 < N; ++n2) { if(n1 == n2){ continue; } double newcost = cost(n1,n2,data) - y1[n2]; if(newcost < d){ d = newcost; nn = -1; if(nmatch[n2] == top){ nn = n2; } }else if(newcost == d && nn < 0 && nmatch[n2] == top){ nn = n2; } } if(nn >= 0){ y1[n1] = d; nmatch[n1] = nn; nmatch[nn] = n1; } } // Initial labeling int nn = 0; for(int ni = 0; ni < N; ++ni){ if(nmatch[ni] != top){ continue; } nn++; sm[ni] = -1; dplus[ni] = 0.0; double Y1B = y1[ni]; for(int nk = 0; nk < N; ++nk){ if(ni == nk){ continue; } double newcost = cost(ni,nk,data) - Y1B - y1[nk]; if(newcost < dminus[nk]){ dminus[nk] = newcost; ka[nk] = ni; } } } if(nn <= 1){ goto finalize; } // Examination of the labeling and decision for the next step { make_decision: int n1, n2; int nka, nkb; double dbest = DBL_MAX; int nbest; for(int nb = 0; nb < N; ++nb) { if(basis[nb] != nb){ continue; } double d = dminus[nb]; if(sm[nb] >= top){ if(tma[nb] >= top){ if(d >= dbest){ continue; } nbest = nb; dbest = d; } if(mem[nb] != nb){ d += y1[nb]; if(d < dbest){ nbest = nb; dbest = d; } } }else{ d = 0.5*(d + dplus[nb]); if(d <= dbest){ nbest = nb; dbest = d; } } } if(tma[nbest] < top){ // Expansion of a T labeled blossom n1 = mem[nbest]; int nb3 = n1; nka = ka[n1]; { int nk2 = n1; do{ int nk1 = nk2; nkb = kb[nk1]; double y1b = y1[nk1]; do{ basis[nk2] = nk1; y2[nk2] -= y1b; if(nk2 == nkb){ break; } nk2 = mem[nk2]; }while(1); nk2 = mem[nkb]; mem[nkb] = nk1; }while(nk2 != nka); } { double y1b = dplus[n1]; y1[nbest] = y1b; mem[nbest] = nka; int nk2 = nka; do{ y2[nk2] -= y1b; if(nk2 == nbest){ break; } nk2 = mem[nk2]; }while(1); } int nk1 = nmatch[nbest]; int nb = basis[sm[basis[nk1]]]; if(nb != nbest){ { int nb2 = nb; int nk; do{ nk = tma[nb2]; int nb1 = basis[nk]; if(nb1 == nbest){break; } nb2 = sm[nb1]; nb2 = basis[nb2]; }while(1); tma[nb] = tma[nbest]; tma[nbest] = tmb[nb2]; tmb[nb] = tmb[nbest]; tmb[nbest] = nk; } int nk3 = sm[nb]; nb3 = basis[nk3]; int nk4 = sm[nb3]; sm[nb] = top; nmatch[nb] = nk1; int nb1 = nb3; do{ nk1 = tma[nb1]; int nk2 = tmb[nb1]; tma[nb1] = nk4; tmb[nb1] = nk3; sm[nb1] = nk1; nmatch[nb1] = nk1; int nb2 = basis[nk1]; nmatch[nb2] = nk2; nk3 = sm[nb2]; sm[nb2] = nk2; if(nb2 == nbest){ break; } nb1 = basis[nk3]; nk4 = sm[nb1]; tma[nb2] = nk3; tmb[nb2] = nk4; }while(1); } int nk2 = tmb[nb]; int nb1 = basis[nk2]; dminus[nb1] = dbest; n1 = -1; if(nb1 != nb){ nk1 = tma[nb1]; nb3 = basis[nk1]; tma[nb1] = tma[nb]; tmb[nb1] = nk2; int nk; do{ nk = sm[nb1]; sm[nb1] = top; int nb2 = basis[nk]; nk = tma[nb2]; tma[nb2] = top; n2 = tmb[nb2]; tmb[nb2] = n1; n1 = nb2; dplus[nb2] = dbest; nb1 = basis[nk]; dminus[nb1] = dbest; }while(nb1 != nb); tma[nb] = n2; tmb[nb] = nk; sm[nb] = top; if(nb3 == nb){ goto do_scan1; } } nb1 = -1; { int nb2 = nb3; do{ int nk = sm[nb2]; sm[nb2] = top; tma[nb2] = top; tmb[nb2] = nb1; nb1 = basis[nk]; nk = tma[nb1]; sm[nb1] = top; tma[nb1] = top; tmb[nb1] = nb2; nb2 = basis[nk]; }while(nb2 != nb); } scan2(nb1, N, cost, data, basis, mem, ka, kb, sm, tma, tmb, y1, y2, dplus, dminus); do_scan1: while(n1 >= 0){ int nb = n1; scan1(nb, N, cost, data, basis, mem, ka, kb, sm, tma, tmb, y1, y2, dplus, dminus, m1); n1 = tmb[nb]; tmb[nb] = top; } }else if(sm[nbest] >= top){ // Growing an alternating tree by adding two edges tma[nbest] = ka[nbest]; tmb[nbest] = kb[nbest]; int nmb = basis[nmatch[nbest]]; dplus[nmb] = dbest; sm[nmb] = nmatch[nmb]; scan1(nmb, N, cost, data, basis, mem, ka, kb, sm, tma, tmb, y1, y2, dplus, dminus, m1); }else{ nka = ka[nbest]; nkb = kb[nbest]; n1 = nbest; int nb1 = n1; n2 = basis[nka]; int nb2 = n2; do{ tma[nb1] = nb2; int nk = sm[nb1]; if(nk < 0){ break; } nb2 = basis[nk]; nb1 = tma[nb2]; nb1 = basis[nb1]; }while(1); int nb = nb1; nb1 = n2; nb2 = n1; while(tma[nb1] >= top){ tma[nb1] = nb2; int nk = sm[nb1]; if(nk < 0){ goto augment_matching; } nb2 = basis[nk]; nb1 = tma[nb2]; nb1 = basis[nb1]; } while(nb1 != nb){ int nk = tma[nb]; tma[nb] = top; nb = basis[nmatch[nk]]; } // Shinking a blossom double yb = y1[nb] + dbest - dplus[nb]; y1[nb] = 0.0; int nk1 = nb; do{ y2[nk1] += yb; nk1 = mem[nk1]; }while(nk1 != nb); int memsave = mem[nb]; if(nb == n2){ n2 = n1; nb2 = tma[nb]; } do{ mem[nk1] = nb2; int nm = nmatch[nb2]; sm[nb2] = nm; double y1b = y1[nb2] + dminus[nb2] - dbest; nk1 = nb2; int nk2; do{ nk2 = nk1; y2[nk2] += y1b; basis[nk2] = nb; nk1 = mem[nk2]; }while(nk1 != nb2); kb[nb2] = nk2; y1[nb2] = y1b; nb1 = basis[nm]; mem[nk2] = nb1; y1b = y1[nb1] + dbest - dplus[nb1]; nk2 = nb1; do{ nk1 = nk2; y2[nk1] += y1b; basis[nk1] = nb; nk2 = mem[nk1]; }while(nk2 != nb1); kb[nb1] = nk1; y1[nb1] = y1b; if(n2 != nb1){ nb2 = tma[nb1]; tma[nb1] = tmb[nb2]; tmb[nb1] = tma[nb2]; continue; } if(n2 != nbest){ tma[n2] = nkb; tmb[n2] = nka; if(nb != nbest){ n2 = n1; nb2 = tma[nb]; continue; } break; }else{ tma[nbest] = nka; tmb[nbest] = nkb; break; } }while(1); mem[nk1] = memsave; n1 = mem[nb]; ka[n1] = memsave; dplus[n1] = yb; tma[nb] = top; dplus[nb] = dbest; scan1(nb, N, cost, data, basis, mem, ka, kb, sm, tma, tmb, y1, y2, dplus, dminus, m1); } goto make_decision; // Augmentation of matching // Exchange of the matching and non matching edges along the augmenting path augment_matching: { int nb = n1; int nk = nka; do{ int nb1 = nb; do{ nmatch[nb1] = nk; nk = sm[nb1]; tma[nb1] = top; if(nk < 0){ break; } int nb2 = basis[nk]; int nk1 = tma[nb2]; nk = tmb[nb2]; nb1 = basis[nk1]; nmatch[nb2] = nk1; }while(1); if(nb != n1){ break; } nb = n2; nk = nkb; }while(1); } // Removing all labels on non exposed base nodes for(int nb = 0; nb < N; ++nb){ if(basis[nb] != nb){ continue; } if(sm[nb] >= top){ if(tma[nb] < top){ double d = dminus[nb] - dbest; y1[nb] += d; tma[nb] = top; tmb[nb] = top; } }else{ double d = dbest - dplus[nb]; y1[nb] += d; sm[nb] = top; if(nmatch[nb] != top){ dplus[nb] = DBL_MAX; }else{ sm[nb] = -1; dplus[nb] = 0.0; } } dminus[nb] = DBL_MAX; } nn -= 2; if(nn <= 1){ goto finalize; } // Determination of the new dminus values for(int n1 = 0; n1 < N; ++n1){ int nb1 = basis[n1]; if(sm[nb1] >= 0){ continue; } double y1b = y1[nb1]; double y2b = y2[n1]; for(int n2 = 0; n2 < N; ++n2) { int nb2 = basis[n2]; if(nb1 == nb2){ continue; } if(n1 == n2){ continue; } double newcost = cost(n1,n2,data) - y1b - y2b - y1[nb2] - y2[n2]; if(newcost < dminus[nb2]){ ka[nb2] = n1; kb[nb2] = n2; dminus[nb2] = newcost; } } } goto make_decision; } // Generation of the original graph by expansion of all shrunken blossoms finalize: *total_weight = 0; for(int nb1 = 0; nb1 < N; ++nb1) { if(basis[nb1] != nb1 || sm[nb1] < -1){ continue; } int n2 = nmatch[nb1]; int nb2 = basis[n2]; int n1 = nmatch[nb2]; sm[nb1] = -2; sm[nb2] = -2; if(n1 == n2){ continue; } double nc = cost(n1,n2,data); //double d = nc - y1[nb1] - y1[nb2] - y2[n1] - y2[n2]; *total_weight += nc; } for(int n1 = 0; n1 < N; ++n1) { restart_loop: int nb = basis[n1]; if(nb == n1){ continue; } int nk2 = mem[nb]; int nka = ka[nk2]; int nb3 = nk2; double yb = dplus[nk2]; do{ int nk1 = nk2; int nkb = kb[nk1]; double y1b = y1[nk1]; do{ basis[nk2] = nk1; y2[nk2] -= y1b; if(nk2 == nkb){ break;} nk2 = mem[nk2]; }while(1); nk2 = mem[nkb]; mem[nkb] = nk1; }while(nk2 != nka); y1[nb] = yb; mem[nb] = nka; nk2 = nka; do{ y2[nk2] -= yb; if(nk2 == nb){ break; } nk2 = mem[nk2]; }while(1); int nk = nmatch[nb]; int nk1 = basis[nk]; nk1 = nmatch[nk1]; int nb1 = basis[nk1]; if(nb == nb1){ goto skip_forward; } nmatch[nb1] = nk; nb3 = tma[nb1]; nb3 = basis[nb3]; do{ int nb2 = basis[sm[nb1]]; int nk1 = tma[nb2]; nk2 = tmb[nb2]; nb1 = basis[nk1]; nmatch[nb1] = nk2; nmatch[nb2] = nk1; if(nk1 == nk2){ goto restart_loop; } double nc = cost(nk1,nk2,data); double d = nc - y1[nb1] - y1[nb2] - y2[nk1] - y2[nk2]; if(fabs(d) > DBL_EPSILON){ fprintf(stderr, "Optimality conditions are violated at edge %3d <--> %3d)\n", nk1, nk2); } *total_weight += nc; }while(nb1 != nb); loop: if(nb3 == nb) goto restart_loop; skip_forward: int n2 = sm[nb3]; int nb2 = basis[n2]; int n3 = sm[nb2]; if(n2 == n3){ goto restart_loop; } { double nc = cost(n2,n3,data); double d = nc - y1[nb2] - y1[nb3] - y2[n2] - y2[n3]; if(fabs(d) > DBL_EPSILON){ fprintf(stderr, "Optimality conditions are violated at edge %3d <--> %3d)\n", n2, n3); } *total_weight += nc; } n3 = tma[nb2]; nb3 = basis[n3]; goto loop; } }