00001
00007 #include "SpecialRelations.H"
00008
00009 SpecialRelations::TSpecialFactorRelations SpecialRelations::SpecialFactorRelations;
00010 filebuf SpecialRelations::FileBuffer;
00011 ostream SpecialRelations::SpecialRelations_to_file(&SpecialRelations::FileBuffer);
00012 istream SpecialRelations::SpecialRelations_from_file(&SpecialRelations::FileBuffer);
00013
00014
00015 void SpecialRelations::Load()
00016 {
00017
00018
00019
00020 cout << "Reading special relations and reorganizing file..." << endl;
00021 unsigned int u_hits = 0, g_hits = 0;
00022 streampos rpos=0, wpos=0;
00023
00024 SpecialRelations_from_file.seekg(0,ios::beg);
00025 SpecialRelations_to_file.seekp(0,ios::beg);
00026
00027 while (SpecialRelations_from_file.peek()=='G')
00028 {
00029 TSpecialFactorRelation relation;
00030 relation.fpos = SpecialRelations_from_file.tellg();
00031 string s; SpecialRelations_from_file >> s;
00032 SpecialRelations_from_file >> relation.factor;
00033 SpecialFactorRelations.insert(relation);
00034 relation.factor.swap();
00035 SpecialFactorRelations.insert(relation);
00036 relation.factor.swap();
00037 SpecialRelations_from_file.ignore(1000000,'\n');
00038 ++g_hits;
00039 }
00040 wpos=rpos=SpecialRelations_from_file.tellg();
00041
00042
00043 if (SpecialRelations_from_file.peek()!='U' && SpecialRelations_from_file.peek()!=EOF)
00044 {
00045 MARK;
00046 cerr << "Special Relations: garbage detected. Giving up. Please validate." << endl;
00047 exit(1);
00048 }
00049
00050 while (true)
00051 {
00052 SpecialRelations_from_file.seekg(rpos);
00053 while (SpecialRelations_from_file.peek()=='U')
00054 {
00055 SpecialRelations_from_file.ignore(1000000,'\n');
00056 ++u_hits;
00057 }
00058
00059 int cached_g = 0;
00060 const int max_cached_g = 1000;
00061 string sG[max_cached_g];
00062 while (SpecialRelations_from_file.peek()=='G')
00063 {
00064 while (SpecialRelations_from_file.peek()!='\n')
00065 {
00066 char buffer[2048];
00067 SpecialRelations_from_file.get(buffer, sizeof(buffer), '\n');
00068 sG[cached_g]+=buffer;
00069 }
00070 SpecialRelations_from_file.ignore(10,'\n');
00071 if (++cached_g>=max_cached_g) break;
00072 while (SpecialRelations_from_file.peek()=='U')
00073 {
00074 SpecialRelations_from_file.ignore(1000000,'\n');
00075 ++u_hits;
00076 }
00077 }
00078 rpos=SpecialRelations_from_file.tellg();
00079 if (cached_g==0) break;
00080 SpecialRelations_to_file.seekp(wpos);
00081
00082 for (int i=0; i<cached_g; ++i)
00083 {
00084 TSpecialFactorRelation relation;
00085 relation.fpos = SpecialRelations_to_file.tellp();
00086 {
00087 istringstream is(sG[i]);
00088 string s; is >> s;
00089 is >> relation.factor;
00090 }
00091 SpecialRelations_to_file << sG[i] << "\n";
00092 SpecialFactorRelations.insert(relation);
00093 relation.factor.swap();
00094 SpecialFactorRelations.insert(relation);
00095 relation.factor.swap();
00096 };
00097 SpecialRelations_to_file.flush();
00098 wpos=SpecialRelations_to_file.tellp();
00099 g_hits+=cached_g;
00100 cout << g_hits << " special relations written, "
00101 << u_hits << " removed." << "\r" << flush;
00102
00103 }
00104 cout << endl;
00105
00106
00107
00108 {
00109 streampos pos, ende;
00110 pos = wpos;
00111 SpecialRelations_to_file.seekp(0, ios::end);
00112 ende = SpecialRelations_to_file.tellp();
00113 SpecialRelations_to_file.seekp(wpos);
00114
00115
00116 char buffer[4096];
00117 for (unsigned int i=0; i<sizeof(buffer); ++i) buffer[i]='U';
00118 while (static_cast<streamoff>(SpecialRelations_to_file.tellp()) < static_cast<streamoff>(ende))
00119 {
00120 SpecialRelations_to_file.write(buffer,sizeof(buffer));
00121
00122 }
00123 SpecialRelations_to_file << flush;
00124 SpecialRelations_to_file.seekp(pos);
00125 }
00126 SpecialRelations_from_file.clear();
00127 cout << "Recover: " << SpecialFactorRelations.size()
00128 << " special relations read, " << endl
00129 << u_hits << " invalid DLP-relations eliminated." << endl;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 #ifdef AUTOMATIC_CYCLESEARCH
00140 const int CycleSearchPeriod = 1000000;
00141 static int next_CycleSearch = CycleSearchPeriod;
00142 #endif
00143
00144 void SpecialRelations::CycleSearch()
00145 {
00146
00147
00148
00149
00150
00151
00152 if (SpecialFactorRelations.empty()) return;
00153 cout << "Starting cycle find for Special-Factor-Set" << endl;
00154
00155 TSpecialFactorRelations WorkingSet;
00156 cout << "Size: " << SpecialFactorRelations.size() << ", " << WorkingSet.size() << endl;
00157
00158 WorkingSet.swap(SpecialFactorRelations);
00159
00160
00161
00162 cout << "Size: " << SpecialFactorRelations.size() << ", " << WorkingSet.size() << endl;
00163
00164 intset NodeSet;
00165 typedef list<TSpecialFactorRelation> TEdgeList;
00166 TEdgeList EdgeList;
00167
00168 TSpecialFactorRelations::iterator pos;
00169 TSpecialFactorRelation SearchRelation;
00170 int right_side,left_side;
00171
00172 while (!WorkingSet.empty())
00173 {
00174 NodeSet.clear();
00175 pos=WorkingSet.begin();
00176 TSpecialFactorRelation relation = *pos;
00177 EdgeList.push_back(relation);
00178 left_side=relation.factor.LP1();
00179 right_side=relation.factor.LP2();
00180 NodeSet.insert(left_side);
00181 NodeSet.insert(right_side);
00182 WorkingSet.erase(pos); SpecialFactorRelations.insert(relation);
00183 relation.factor.swap();
00184 WorkingSet.erase(relation);
00185 SpecialFactorRelations.insert(relation);
00186 relation.factor.swap();
00187
00188
00189 while (!EdgeList.empty())
00190 {
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 SearchRelation.factor.set_for_search(left_side);
00201 pos=WorkingSet.lower_bound(SearchRelation);
00202 if (pos!=WorkingSet.end() && (*pos).factor.DLP_divisible_by(left_side) )
00203 {
00204
00205 relation = *pos;
00206 WorkingSet.erase(pos);
00207 SpecialFactorRelations.insert(relation);
00208 relation.factor.swap();
00209 WorkingSet.erase(relation);
00210 SpecialFactorRelations.insert(relation);
00211 relation.factor.swap();
00212 left_side=relation.factor/left_side;
00213 if (NodeSet.find(left_side)!=NodeSet.end())
00214 {
00215
00216 statistical_data::DLP_cycle_hits++;
00217 cout << "DLP-cycle found... " << endl;
00218
00219
00220
00221 CRelation *GL = new CRelation;
00222 GL->combine(SpecialRelations_from_file,relation.fpos);
00223 mpz_mul_ui(GL->Delta,GL->Delta,left_side);
00224 mpz_mod(GL->Delta,GL->Delta,n);
00225 right_side=relation.factor/left_side;
00226
00227
00228
00229
00230
00231
00232
00233
00234 unsigned int CycleLength=1;
00235 for (TEdgeList::iterator p=EdgeList.begin(); p!=EdgeList.end(); ++p)
00236 {
00237 CycleLength++;
00238
00239 mpz_mul_ui(GL->Delta,GL->Delta,right_side);
00240 mpz_mod(GL->Delta,GL->Delta,n);
00241 GL->combine(SpecialRelations_from_file,(*p).fpos);
00242 if ((*p).factor.DLP_divisible_by(left_side)) break;
00243 right_side=(*p).factor/right_side;
00244 }
00245
00246 cout << "DLP-cycle size: " << CycleLength << endl;
00247 GL->SanityCheck();
00248 StaticRelations::insert(GL);
00249
00250
00251 statistical_data::DynamicFactorRating.increment_Hits_at_position(CycleLength);
00252
00253
00254
00255 SpecialFactorRelations.erase(relation);
00256 relation.factor.swap();
00257 SpecialFactorRelations.erase(relation);
00258 relation.factor.swap();
00259 {
00260
00261 const streampos pos = SpecialRelations_to_file.tellp();
00262 SpecialRelations_to_file.seekp(relation.fpos); SpecialRelations_to_file << "U " << flush;
00263 SpecialRelations_to_file.seekp(pos);
00264 }
00265
00266
00267 left_side=relation.factor/left_side;
00268 continue;
00269 }
00270 else
00271 {
00272
00273 NodeSet.insert(left_side);
00274 EdgeList.push_front(relation);
00275
00276 continue;
00277 }
00278 }
00279
00280
00281
00282
00283 left_side=EdgeList.begin()->factor/left_side;
00284 EdgeList.pop_front();
00285 }
00286 }
00287 cout << "Size: " << SpecialFactorRelations.size() << ", " << WorkingSet.size() << endl;
00288 cout << "cycle find finished." << endl;
00289 }
00290
00291 bool SpecialRelations::insert(const CmpqsFactor &DLP, CRelation *GL, const short int HitCount )
00292 {
00293
00294
00295
00296
00297 if (DLP.LP1()==DLP.LP2())
00298 {
00299 cout << "special hit: DLP is a square!" << endl;
00300 statistical_data::Special_hit++;
00301
00302
00303
00304 mpz_mul_ui(GL->Delta,GL->Delta,DLP.LP1()); mpz_mod(GL->Delta,GL->Delta,n);
00305 return false;
00306 }
00307
00308 TSpecialFactorRelation relation;
00309 relation.factor=DLP;
00310
00311 const TSpecialFactorRelations::iterator pos = SpecialFactorRelations.find(relation);
00312 if (pos==SpecialFactorRelations.end())
00313 {
00314 relation.fpos=GL->save(SpecialRelations_to_file,relation.factor,HitCount);
00315 SpecialFactorRelations.insert(relation);
00316 relation.factor.swap();
00317 SpecialFactorRelations.insert(relation);
00318
00319 #ifdef AUTOMATIC_CYCLESEARCH
00320
00321 if (!--next_CycleSearch)
00322 {
00323 next_CycleSearch=CycleSearchPeriod;
00324 SpecialRelations::CycleSearch();
00325 }
00326 #endif
00327 return true;
00328 }
00329 else
00330 {
00331
00332 cout << "Special Hit by already known Special Factor!" << endl;
00333 statistical_data::Special_hit++;
00334 mpz_t x;
00335 mpz_init(x); DLP.assign_to_mpz(x);
00336 mpz_mul(GL->Delta,GL->Delta,x); mpz_mod(GL->Delta,GL->Delta,n);
00337 mpz_clear(x);
00338 GL->combine(SpecialRelations_from_file,(*pos).fpos);
00339
00340 return false;
00341 }
00342 }
00343
00344
00345 bool SpecialRelations::SpecialFactor_splitable(const CmpqsFactor &DLP)
00346 {
00347
00348
00349 if (DLP.LP1()==DLP.LP2())
00350 {
00351
00352 return true;
00353 }
00354 TSpecialFactorRelation relation;
00355 relation.factor=DLP;
00356 TSpecialFactorRelations::iterator pos = SpecialFactorRelations.find(relation);
00357 return (pos!=SpecialFactorRelations.end());
00358 }
00359
00360 void SpecialRelations::split_by_primefactor(const int Primfaktor)
00361 {
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 static int Trashcounter = 0;
00388
00389 TSpecialFactorRelation SearchRelation;
00390 SearchRelation.factor.set_for_search(Primfaktor);
00391
00392 while (true)
00393 {
00394
00395
00396
00397 const TSpecialFactorRelations::iterator pos=SpecialFactorRelations.lower_bound(SearchRelation);
00398 if (pos==SpecialFactorRelations.end()) break;
00399 if (!(*pos).factor.DLP_divisible_by(Primfaktor)) break;
00400
00401 TSpecialFactorRelation memorized_Relation = *pos;
00402 SpecialFactorRelations.erase(pos);
00403 memorized_Relation.factor.swap();
00404 SpecialFactorRelations.erase(memorized_Relation);
00405 memorized_Relation.factor.swap();
00406
00407 TDynamicFactorRelation relation;
00408 relation.factor=Primfaktor;
00409
00410 if (!is_dynamic_factor(relation))
00411 {
00412 MARK;
00413 cerr << "Inconsistency in dynamic factorbase!" << endl;
00414 exit(1);
00415 }
00416 const TDynamicFactorRelation el=relation;
00417
00418 relation.factor=memorized_Relation.factor/Primfaktor;
00419
00420
00421
00422 if (!is_dynamic_factor(relation))
00423 {
00424
00425
00426 statistical_data::Special_to_dynamic_Factor_hit++;
00427 relation.fpos = DynamicRelations_to_file.tellp();
00428
00429 {
00430 const streampos rpos=SpecialRelations_from_file.tellg();
00431 SpecialRelations_from_file.seekg(memorized_Relation.fpos);
00432
00433 CStreamDecoder enc_in(SpecialRelations_from_file);
00434 CStreamEncoder enc_out(DynamicRelations_to_file);
00435
00436 CmpqsFactor ret; string s;
00437
00438 const ios::fmtflags oldFlagsR = SpecialRelations_from_file.flags();
00439 SpecialRelations_from_file.unsetf(ios::hex); SpecialRelations_from_file.setf(ios::dec);
00440 SpecialRelations_from_file.unsetf(ios::showbase);
00441 const ios::fmtflags oldFlagsW = DynamicRelations_to_file.flags();
00442 DynamicRelations_to_file.unsetf(ios::hex); DynamicRelations_to_file.setf(ios::dec);
00443 DynamicRelations_to_file.unsetf(ios::showbase);
00444
00445 SpecialRelations_from_file >> s;
00446 if (s != "G")
00447 {
00448 MARK;
00449 cerr << "error: wrong position while reading relation" << endl;
00450 exit(1);
00451 }
00452 SpecialRelations_from_file >> ret;
00453 SpecialRelations_from_file >> s;
00454 DynamicRelations_to_file << "G " << setprecision(20) << relation.factor << " " << s << " ";
00455
00456
00457 SpecialRelations_from_file.unsetf(ios::dec); SpecialRelations_from_file.setf(ios::hex);
00458 SpecialRelations_from_file.unsetf(ios::showbase);
00459 DynamicRelations_to_file.unsetf(ios::dec); DynamicRelations_to_file.setf(ios::hex);
00460 DynamicRelations_to_file.unsetf(ios::showbase);
00461
00462 int distance=enc_in.GetValue();
00463 while (distance>=0)
00464 {
00465 enc_out.PutValue(distance);
00466 distance=enc_in.GetValue();
00467 }
00468 enc_out.PutValue(-2);
00469 enc_out.PutValue(Primfaktor);
00470 if (distance==-2)
00471 {
00472 distance=enc_in.GetValue();
00473 while (distance>=0)
00474 {
00475 enc_out.PutValue(distance);
00476 distance=enc_in.GetValue();
00477 }
00478 }
00479 enc_out.PutValue(-1); DynamicRelations_to_file << endl;
00480 SpecialRelations_from_file.flags(oldFlagsR);
00481 DynamicRelations_to_file.flags(oldFlagsW);
00482 SpecialRelations_from_file.seekg(rpos);
00483 }
00484 relation.append_for_sieving();
00485
00486
00487
00488
00489 #ifdef SAFEMODE
00490
00491
00492 {
00493 const streampos rpos=DynamicRelations_from_file.tellg();
00494 DynamicRelations_from_file.seekg(relation.fpos);
00495 CRelation::SanityCheck(DynamicRelations_from_file);
00496 DynamicRelations_from_file.seekg(rpos);
00497 }
00498 #endif
00499
00500 DynamicFactorRelations.insert(relation);
00501 SpecialRelations::split_by_primefactor(relation.factor);
00502 }
00503 else
00504 {
00505
00506
00507 CRelation *GL = new CRelation;
00508 GL->combine(SpecialRelations_from_file,memorized_Relation.fpos);
00509
00510 mpz_mul_ui(GL->Delta,GL->Delta,relation.factor); mpz_mod(GL->Delta,GL->Delta,n);
00511 GL->combine(DynamicRelations_from_file,relation.fpos);
00512
00513 mpz_mul_ui(GL->Delta,GL->Delta,el.factor); mpz_mod(GL->Delta,GL->Delta,n);
00514 GL->combine(DynamicRelations_from_file,el.fpos);
00515 statistical_data::Special_hit++; StaticRelations::insert(GL);
00516 statistical_data::DynamicFactorRating.increment_Hits_at_position(2);
00517 }
00518
00519 {
00520
00521 const streampos pos = SpecialRelations_to_file.tellp();
00522 SpecialRelations_to_file.seekp(memorized_Relation.fpos); SpecialRelations_to_file << "U ";
00523 SpecialRelations_to_file.seekp(pos);
00524 }
00525
00526 ++Trashcounter;
00527 }
00528
00529
00530
00531
00532 }
00533
00534
00535 bool SpecialRelations::insert(const CmpqsFactor &DLP, const string &GL_String)
00536 {
00537
00538
00539
00540
00541 if (DLP.LP1()==DLP.LP2())
00542 {
00543 cout << "special case: DLP is a square! (in LAZY)" << endl;
00544 istringstream is(GL_String);
00545 CRelation* GL = new CRelation();
00546 GL->set_MulticombineData(new CRelation::SMulticombineData);
00547 GL->multi_combine_init();
00548 CmpqsFactor DLP_2 = GL->multi_combine_main(is);
00549 if (DLP!=DLP_2) { MARK; cerr << "DLP-Error somewhere in LAZY!" << endl; exit(1); }
00550 statistical_data::Special_hit++;
00551
00552
00553 mpz_mul_ui(GL->Delta,GL->Delta,DLP.LP1()); mpz_mod(GL->Delta,GL->Delta,n);
00554 StaticRelations::insert(GL,without_multi_combine_init);
00555 return false;
00556 }
00557
00558 TSpecialFactorRelation relation;
00559 relation.factor=DLP;
00560
00561 const TSpecialFactorRelations::iterator pos = SpecialFactorRelations.find(relation);
00562 if (pos==SpecialFactorRelations.end())
00563 {
00564
00565
00566 relation.fpos=SpecialRelations_to_file.tellp();
00567 SpecialRelations_to_file << GL_String;
00568
00569 SpecialFactorRelations.insert(relation);
00570 relation.factor.swap();
00571 SpecialFactorRelations.insert(relation);
00572
00573 #ifdef AUTOMATIC_CYCLESEARCH
00574
00575 if (!--next_CycleSearch)
00576 {
00577 next_CycleSearch=CycleSearchPeriod;
00578 SpecialRelations::CycleSearch();
00579 }
00580 #endif
00581 return true;
00582 }
00583 else
00584 {
00585
00586 cout << "Special Hit by known Special Factor! (LAZY)" << endl;
00587 istringstream is(GL_String);
00588 CRelation* GL = new CRelation();
00589 GL->set_MulticombineData(new CRelation::SMulticombineData);
00590 GL->multi_combine_init();
00591 CmpqsFactor DLP_2 = GL->multi_combine_main(is);
00592 if (DLP!=DLP_2) { MARK; cerr << "DLP-Error somewhere in LAZY!" << endl; exit(1); }
00593 statistical_data::Special_hit++;
00594 mpz_t x;
00595 mpz_init(x); DLP.assign_to_mpz(x);
00596 mpz_mul(GL->Delta,GL->Delta,x); mpz_mod(GL->Delta,GL->Delta,n);
00597 mpz_clear(x);
00598 GL->multi_combine_main(SpecialRelations_from_file,(*pos).fpos);
00599
00600 StaticRelations::insert(GL,without_multi_combine_init);
00601 return false;
00602 }
00603 }