SpecialRelations.cc

Go to the documentation of this file.
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   // read in Special Relations
00018   // compactify special relations on file
00019   // (that is: remove relations which are marked redundant)
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   // Special Relations einlesen
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; // read "G "
00032      SpecialRelations_from_file >> relation.factor; // read special 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'); // read over invalid/redundant lines
00038      ++g_hits;
00039     }
00040   wpos=rpos=SpecialRelations_from_file.tellg(); // write position = read position
00041 
00042   // quick sanity check:
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'); // read over invalid/redundant lines
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'); // read over invalid/redundant lines
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       //cout << (long long int)static_cast<streamoff>(rpos) << " , " << (long long int)static_cast<streamoff>(wpos) << endl;
00103     }
00104    cout << endl;
00105    
00106   // in the absence of a truncate-operation we fill up the
00107   // rest of the file with U's (u=ungültig=invalid)
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     //cout << (long long int)static_cast<streamoff>(pos) << " , " << (long long int)static_cast<streamoff>(ende) << endl;
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         //cout << (long long int)static_cast<streamoff>(SpecialRelations_to_file.tellp()) << " , " << (long long int)static_cast<streamoff>(ende) << endl;
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 //#define AUTOMATIC_CYCLESEARCH
00134 // If AUTOMATIC_CYCLESEARCH is set, then a automatic cycle search is done
00135 // in regular intervals; however since we sieve with a lot of single large primes,
00136 // more and more DLPs get split. So our dynamic sieving algorithm does not need
00137 // any DLP-cyclesearch. In fact, the cyclesearch slows down the server...
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   // If we are able to find/construct a subset of Double-Large-Primes that
00147   // represents a cycle (p1,p2),(p2,p3),(p3,p4),...(pk,p1), then this
00148   // cycle neutralizes the Large Primes inside this subset, because
00149   // every Large Prime occurs twice (or as multiple of 2) inside the cycle.
00150   // -> we gain a static relation for each cycle.
00151 
00152   if (SpecialFactorRelations.empty()) return; // there is nothing to find
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   // Hint: to reduce memory usage, we move the Special-Factor-Relations
00160   // to the WorkingSet instead of copying them.
00161   // Therefore we must pay attention to move them back after cycle-find is done!
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(); // important! (due to repeated iteration)
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); // remove old Specialfactor (swapped copy)
00185      SpecialFactorRelations.insert(relation);
00186      relation.factor.swap();
00187 
00188      //cout << "Starting new round of cycle search." << endl;
00189      while (!EdgeList.empty())
00190       {
00191         //for (TEdgeList::iterator p=EdgeList.begin(); p!=EdgeList.end(); ++p)
00192         // cout << (*p).factor << "|";
00193         //cout << endl;
00194         //cout << "Searching for " << left_side << endl;
00195         //cout << "WorkingSet contains: " << endl;
00196         //for (pos=WorkingSet.begin(); pos!=WorkingSet.end(); ++pos)
00197         // cout << (*pos).factor << ",";
00198         //cout << endl;
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            // a node can be inserted at the left side
00205            relation = *pos;
00206            WorkingSet.erase(pos); // remove old Specialfactor
00207            SpecialFactorRelations.insert(relation);
00208            relation.factor.swap();
00209            WorkingSet.erase(relation); // remove old Specialfactor (swapped copy)
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               // found a cycle!
00216               statistical_data::DLP_cycle_hits++;
00217               cout << "DLP-cycle found... " << endl;
00218               // now: 
00219               // evaluate cycle, construct the relation and insert it
00220               // into the system of equations
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               //cout << relation.factor;
00227 
00228               // Walk through the EdgeList up to the position, where the
00229               // value of "left_side" occurs firstly. 
00230               //  -> cycle ends at this position.
00231               // Don't forget to multiply the root of the product of the specialfactors!
00232               // As each part of a specialfactor occurs twice, we can use
00233               // the "right_side" values.
00234               unsigned int CycleLength=1;
00235               for (TEdgeList::iterator p=EdgeList.begin(); p!=EdgeList.end(); ++p)
00236                {
00237                  CycleLength++;
00238                  //cout << " - " << p->factor;
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               //cout << endl;
00246               cout << "DLP-cycle size: " << CycleLength << endl;
00247               GL->SanityCheck(); // as a precaution...
00248               StaticRelations::insert(GL);
00249 
00250               // The length of the cycle is (roughly) the number of large primes inside the cycle.
00251               statistical_data::DynamicFactorRating.increment_Hits_at_position(CycleLength);
00252             
00253               // remove an edge (which should represent this cycle) out of the Special-Relation-Set,
00254               // we choose the last (=current) edge):
00255               SpecialFactorRelations.erase(relation); // remove old special factor
00256               relation.factor.swap();
00257               SpecialFactorRelations.erase(relation); // and the swapped copy, too!
00258               relation.factor.swap();
00259               {
00260                 // mark this relation as redundant/invalid on file!
00261                 const streampos pos = SpecialRelations_to_file.tellp(); // memorize write position
00262                 SpecialRelations_to_file.seekp(relation.fpos); SpecialRelations_to_file << "U " << flush; // mark as invalid
00263                 SpecialRelations_to_file.seekp(pos); // restore fileposition
00264               }
00265  
00266               // important: continue cycle search, there may be more than just one!
00267               left_side=relation.factor/left_side;
00268               continue;
00269             }
00270            else
00271             {
00272               // no cycle found -> insert edge and node (and retry)
00273               NodeSet.insert(left_side);
00274               EdgeList.push_front(relation);
00275               //cout << "Insert node " << relation.factor << endl;
00276               continue;
00277             } 
00278          }
00279         // no edge found which can be appended at the left side.
00280         // -> alternative 1: insert right-wise (not necessary for cyclefind)
00281         // -> alternative 2: remove the current left-sided edge (as this edge gains no further connections)
00282         //cout << "removing edge " << EdgeList.begin()->factor << endl;
00283         left_side=EdgeList.begin()->factor/left_side;
00284         EdgeList.pop_front(); // remove left-sided edge
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 /* =0 */)
00292 {
00293   // insert Special-Factor into Special-Factor-Set. (This is done for both
00294   // factors of the DLP for fast access.) If the Special-Factor is already
00295   // present, then combine it to get a static relation.
00296 
00297   if (DLP.LP1()==DLP.LP2()) // special case: DoubleLargePrime=LargePrime^2
00298    {
00299      cout << "special hit: DLP is a square!" << endl;
00300      statistical_data::Special_hit++;
00301      // please note: Delta is not the square, but it is the part of the
00302      // relation which is to square. Therefore never forget to multiply
00303      // roots into Delta!
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      // trigger cyclesearch on DLP at regular intervals
00321      if (!--next_CycleSearch)
00322       {
00323         next_CycleSearch=CycleSearchPeriod;
00324         SpecialRelations::CycleSearch();
00325       }
00326 #endif      
00327      return true;
00328    }
00329   else
00330    { 
00331      // Special-Factor already known
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      //StaticRelations::insert(GL); // should be done elsewhere!
00340      return false;
00341    }
00342 }
00343 
00344 
00345 bool SpecialRelations::SpecialFactor_splitable(const CmpqsFactor &DLP)
00346 {
00347   // check, whether Special-Factor can be split successfully
00348   // true -> yes, false -> no
00349   if (DLP.LP1()==DLP.LP2()) // special case: DoubleLargePrime=LargePrime^2
00350    {
00351      // cout << "Special case: DLP is a square!" << endl;
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   // Specialfactors are always outside the static factorbase. No sieving is
00363   // done for special factors.  Special factors are always composite factors
00364   // and (normally) consist of exactly two single large primes.  If one
00365   // SLP-part of a special factor is already inside the dynamic factorbase,
00366   // then we can split the special factor and we get a new SLP and possibly
00367   // a new dynamic factor, too.  Maybe we can gain even a hit inside the
00368   // static factorbase: This happens, when both parts of the special factor
00369   // are known SLPs. Then we can combine all the parts of the special
00370   // relation in conjunction with these single large primes to get a static
00371   // relation.
00372 
00373   // Whenever a new SLP gets detected, we should also check, whether this
00374   // SLP is part of any Specialfactor.  In the latter case, these
00375   // Specialfactors can be split as well. (And we should recurse the
00376   // procedure to get possibly even more of them!) This way we get new
00377   // dynamic factors to sieve with!
00378 
00379   // Any split primefactor (outside the static factorbase) will be
00380   // appended to the new relation as a "correction factor". The relations
00381   // that correspond with these "correction factors" need to be combined
00382   // later to get a valid static relation.  This is a kind of lazy
00383   // evaluation, because the evaluation of the relation will be delayed (or
00384   // even avoided) until it is known that the relation can be combined
00385   // (recursively) to gain a static relation!
00386 
00387   static int Trashcounter = 0; // number of superfluous relations (that contain already eliminated/combined factors)
00388   
00389   TSpecialFactorRelation SearchRelation;
00390   SearchRelation.factor.set_for_search(Primfaktor);
00391 
00392   while (true)
00393    {
00394     //cout << "splitting " << Primfaktor << endl;
00395     /* Because of recursion we need to restart here every time when a specialfactor got
00396        removed inside the loop.  -> get the next biggest Special-Factor */
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); // remove old specialfactor
00403     memorized_Relation.factor.swap();
00404     SpecialFactorRelations.erase(memorized_Relation); // and remove also its swapped version
00405     memorized_Relation.factor.swap(); // swap back to original
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; // this is the new remaining factor
00419     // now we have a correctly computed dynamic factor at hand
00420 
00421     // but is it really a new one, or did it exist already the dynamic factorbase?
00422     if (!is_dynamic_factor(relation))
00423      { 
00424        // it is new!
00425        //cout << "Special Factor: Dynamic Factor detected!" << endl;
00426        statistical_data::Special_to_dynamic_Factor_hit++;
00427        relation.fpos = DynamicRelations_to_file.tellp();
00428        // transform the relation and store it:
00429        {
00430          const streampos rpos=SpecialRelations_from_file.tellg(); // memorize position
00431          SpecialRelations_from_file.seekg(memorized_Relation.fpos); // memorize position
00432 
00433          CStreamDecoder enc_in(SpecialRelations_from_file);
00434          CStreamEncoder enc_out(DynamicRelations_to_file);
00435 
00436          CmpqsFactor ret; string s;
00437          // memorize formatflags of file
00438          const ios::fmtflags oldFlagsR = SpecialRelations_from_file.flags(); // memorize old formatflags
00439          SpecialRelations_from_file.unsetf(ios::hex); SpecialRelations_from_file.setf(ios::dec); // assure decimal notation (note: recursive call can involve SLP correction factors!)
00440          SpecialRelations_from_file.unsetf(ios::showbase); // don't show base (eg. don't prepend "0x" for hexadecimal numbers)
00441          const ios::fmtflags oldFlagsW = DynamicRelations_to_file.flags(); // save old format flags
00442          DynamicRelations_to_file.unsetf(ios::hex); DynamicRelations_to_file.setf(ios::dec); // assure decimal notation (note: recursive call can involve SLP correction factors!)
00443          DynamicRelations_to_file.unsetf(ios::showbase); // don't show base
00444  
00445          SpecialRelations_from_file >> s; // relation start symbol 'G'
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; // read in factor (dynamic-factor or special-factor or 1 (for static factor))
00453          SpecialRelations_from_file >> s; // delta
00454          DynamicRelations_to_file << "G " << setprecision(20) << relation.factor << " " << s << " ";
00455 
00456          // now we use hexadecimal notation:
00457          SpecialRelations_from_file.unsetf(ios::dec); SpecialRelations_from_file.setf(ios::hex); // hexadecimal notation
00458          SpecialRelations_from_file.unsetf(ios::showbase); // don't show base
00459          DynamicRelations_to_file.unsetf(ios::dec); DynamicRelations_to_file.setf(ios::hex); // hexadecimal notation
00460          DynamicRelations_to_file.unsetf(ios::showbase); // don't show base
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); // restore old Formatflags
00481          DynamicRelations_to_file.flags(oldFlagsW); // restore old Formatflags
00482          SpecialRelations_from_file.seekg(rpos); // restore position
00483        }
00484        relation.append_for_sieving();
00485 
00486        // not really important: for the standalone version we would also be
00487        // able to insert the factor immediately for sieving here.
00488 
00489 #ifdef SAFEMODE
00490        // validate the newly generated dynamic factor relation.
00491        // also the new dynamic factor needs to be feed to the validation routine!
00492        {
00493         const streampos rpos=DynamicRelations_from_file.tellg();
00494         DynamicRelations_from_file.seekg(relation.fpos);
00495         CRelation::SanityCheck(DynamicRelations_from_file); // exit if relation is invalid (->this would be an internal error!)
00496         DynamicRelations_from_file.seekg(rpos);
00497        }
00498 #endif
00499 
00500        DynamicFactorRelations.insert(relation); // insert Dynamicfactor
00501        SpecialRelations::split_by_primefactor(relation.factor);
00502      }
00503     else 
00504      { 
00505        // does it already exist in the dynamic FB? -> a new relation!
00506        //cout << "Special Factor: Special Hit!" << endl;
00507        CRelation *GL = new CRelation;
00508        GL->combine(SpecialRelations_from_file,memorized_Relation.fpos);
00509        // combine the dynamic factors which were found:
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        // don't forget to eliminate the primefactors as well!
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); // two SLP are involved
00517      } 
00518 
00519     { 
00520       // remove old (and superfluous) special-relation
00521       const streampos pos = SpecialRelations_to_file.tellp(); // save position
00522       SpecialRelations_to_file.seekp(memorized_Relation.fpos); SpecialRelations_to_file << "U "; // mark as invalid
00523       SpecialRelations_to_file.seekp(pos); // restore position
00524     }
00525 
00526     ++Trashcounter; // count the redundant relations of this file
00527    }
00528 
00529  // If too much trash has been collected, we can do a "garbage collection"
00530  // or issue a message to restart the program to trigger a compactification. 
00531  // But today's harddisks are large enough, so this doesn't matter...
00532 }
00533 
00534 
00535 bool SpecialRelations::insert(const CmpqsFactor &DLP, const string &GL_String)
00536 {
00537   // Insert Special-Factor into Special-Factor-Set. Do this for both parts
00538   // of the DLP to speed up access!
00539   // If the Special-Factor is already known, combine it and gain a new relation.
00540 
00541   if (DLP.LP1()==DLP.LP2()) // special case: DoubleLargePrime=LargePrime^2
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      // caution: Delta isn't the square, but it is to square!
00552      // therefore multiply only square roots!
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); // LAZY -> insert take place here
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      //cout << "Speichere DLP-Relation (LAZY)" << endl;
00565      //relation.fpos=GL->save(SpecialRelations_to_file,relation.factor);
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      // trigger cyclesearch on DLP at regular intervals
00575      if (!--next_CycleSearch)
00576       {
00577         next_CycleSearch=CycleSearchPeriod;
00578         SpecialRelations::CycleSearch();
00579       }
00580 #endif      
00581      return true;
00582    }
00583   else
00584    { 
00585      // Special-Factor already known
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      //GL->multi_combine_exit() may be omitted, if StaticRelations::insert does no multi_combine_init
00600      StaticRelations::insert(GL,without_multi_combine_init); // LAZY -> inserting takes place here...
00601      return false;
00602    }
00603 }

Generated on Wed Nov 7 23:29:26 2007 for Qsieve by  doxygen 1.5.4