00001
00006 #ifndef SIEVING_HEADER_
00007 #define SIEVING_HEADER_
00008
00009 #include "qsieve-fwd.H"
00010 #include "StaticFactorbase.H"
00011 #include <cmath>
00012
00013
00014
00015 extern int LogicalSieveSize;
00016
00017
00018
00019
00020
00021
00022 #ifndef TSIEVEELEMENTSIZE
00023 #warning "TSIEVEELEMENTSIZE not defined. Using default value: 1"
00024 #define TSIEVEELEMENTSIZE 1
00025 #endif
00026
00027
00028
00029 #if TSIEVEELEMENTSIZE == 0
00030 typedef signed char TSieveElement;
00031 #define log_SieveEntryMultiplier 1
00032 #ifdef ASM_386
00033 #warning "assembly code is disabled for sieving!"
00034 #endif
00035 #elif TSIEVEELEMENTSIZE == 1
00036 typedef signed char TSieveElement;
00037 #define log_SieveEntryMultiplier 1
00038 #elif TSIEVEELEMENTSIZE == 2
00039 typedef signed short int TSieveElement;
00040 #define log_SieveEntryMultiplier 16
00041 #elif TSIEVEELEMENTSIZE == 4
00042 typedef signed int TSieveElement;
00043 #define log_SieveEntryMultiplier 256
00044 #else
00045 #error "invalid value for TSIEVEELEMENTSIZE"
00046 #endif
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 #if defined(IS_SERVER) || defined(IS_VALIDATOR)
00092
00093
00094
00095
00096
00097
00098
00099
00100 class SieveControl : protected StaticFactorbaseSettings
00101 {
00102 private:
00103 static const int FBLowestStartIndex = 5;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 static void set_logVal_for_Primenumber(const int pos, const TSieveElement val, const TSieveElement dirtyval);
00114 static void set_logVal_for_Primepower(const int pos, const TSieveElement val);
00115
00116 public:
00117 friend void StaticFactorbase::compute_StaticFactorbase();
00118 };
00119
00120
00121
00122 void SieveControl::set_logVal_for_Primenumber(const int, const TSieveElement, const TSieveElement)
00123 {
00124
00125
00126 }
00127
00128 void SieveControl::set_logVal_for_Primepower(const int, const TSieveElement)
00129 {
00130
00131
00132 }
00133
00134 #else
00135
00136
00137 #include <iosfwd>
00138 #include <gmp.h>
00139 #include "utils.H"
00140 #include "mpz_wrapper.H"
00141 using namespace my_mpz_wrapper;
00142
00143 using std::ostream;
00144 using std::istream;
00145
00146 using std::cout;
00147 using std::cerr;
00148
00149
00150 extern int SieveOffset;
00151
00152
00153
00154
00155
00156
00157
00158 extern TSieveElement SieveArray_[PhysicalSieveSize+64+8] __attribute__ ((aligned (64)));
00159 TSieveElement* const SieveArray = &SieveArray_[64];
00160
00161
00162
00163
00164
00165 extern TSieveElement log_Primzahl_of_PrimePowers[StaticFactorbase::max_additional_Powers];
00166
00167
00168
00169 extern mpz_t n, kN, r;
00170 extern double Factor_Threshold;
00171
00172 inline TSieveElement log_DynamicLargePrime (const int p)
00173 {
00174 #if defined(ASM_386) && TSIEVEELEMENTSIZE == 1 && log_SieveEntryMultiplier == 1
00175 #ifdef DEBUG
00176 #warning "assembler i386 TSIEVEELEMENT log lookup enabled"
00177 #endif
00178
00179 register TSieveElement logval;
00180
00181 #if 0
00182
00183
00184 asm ( \
00185 "movb $21,%[L] \n\t" \
00186 "cmpl $485165195,%[P] # exp(20) \n\t" \
00187 "sbbb $0,%[L] \n\t" \
00188 "cmpl $178482300,%[P] # exp(19) \n\t" \
00189 "sbbb $0,%[L] \n\t" \
00190 "cmpl $65659969,%[P] # exp(18) \n\t" \
00191 "sbbb $0,%[L] \n\t" \
00192 "cmpl $24154952,%[P] # exp(17) \n\t" \
00193 "sbbb $0,%[L] \n\t" \
00194 "cmpl $8886110,%[P] # exp(16) \n\t" \
00195 "sbbb $0,%[L] \n\t" \
00196 "cmpl $3269017,%[P] # exp(15) \n\t" \
00197 "sbbb $0,%[L] \n\t" \
00198 "cmpl $1202604,%[P] # exp(14) \n\t" \
00199 "sbbb $0,%[L] \n\t" \
00200 "cmpl $442413,%[P] # exp(13) \n\t" \
00201 "sbbb $0,%[L] \n\t" \
00202 "cmpl $162754,%[P] # exp(12) \n\t" \
00203 "sbbb $0,%[L] \n\t" \
00204 "cmpl $59874,%[P] # exp(11) \n\t" \
00205 "sbbb $0,%[L] \n\t" \
00206 "cmpl $22026,%[P] # exp(10) \n\t" \
00207 "sbbb $0,%[L]" \
00208 : [L] "=&q" (logval) : [P] "r" (p) : "cc");
00209 #endif
00210
00211
00212 static const int TREE[14] __attribute__ ((aligned (64))) =
00213
00214 {
00215
00216 22026, 65659969,
00217
00218 2980, 162754, 8886110, 485165195,
00219
00220 1096, 8103, 59874, 442413, 3269017, 24154952, 178482300, 1318815734
00221 };
00222
00223
00224
00225
00226
00227 #if 0
00228
00229
00230 asm ( \
00231 "xorl %%ecx,%%ecx \n\t" \
00232 "cmpl $1202604,%[P] \n\t" \
00233 "setnc %%cl \n\t" \
00234 "cmpl %[P],%[F](,%%ecx,4) \n\t" \
00235 "rclb $1,%%cl \n\t" \
00236 "cmpl %[P],%[F]+4*2(,%%ecx,4) \n\t" \
00237 "rclb $1,%%cl \n\t" \
00238 "cmpl %[P],%[F]+4*6(,%%ecx,4) \n\t" \
00239 "rclb $1,%%cl \n\t" \
00240 "addb $7,%%cl \n" \
00241 : [L] "=&c" (logval) : [F] "o" (TREE[0]), [P] "r" (p) : "cc");
00242 #endif
00243
00244 #if 1
00245
00246
00247 asm ( \
00248 "xorl %%ecx,%%ecx \n\t" \
00249 "cmpl $65659969,%[P] \n\t" \
00250 "sbb $-1,%%cl \n\t" \
00251 "cmp $22026,%[P] \n\t" \
00252 "sbb $-1,%%cl \n\t" \
00253 "cmpl $1202604,%[P] \n\t" \
00254 "sbb $-1,%%cl \n\t" \
00255 "cmpl %[P],%[F]+4*2(,%%ecx,4) \n\t" \
00256 "lea (,%%ecx,4),%%eax \n\t" \
00257 "adcb $0,%%al \n\t" \
00258 "cmpl %[P],%[F]+4*6(,%%ecx,8) \n\t" \
00259 "adcb $0,%%al \n\t" \
00260 "cmpl %[P],%[F]+4*7(,%%ecx,8) \n\t" \
00261 "adcb $7,%%al \n" \
00262 : [L] "=&a" (logval) : [F] "o" (TREE[0]), [P] "r" (p) : "cc", "ecx");
00263 #endif
00264
00265
00266
00267 #if 0 || defined(DEBUG)
00268
00269
00270 if (logval!=ceil(log_SieveEntryMultiplier*log(p)))
00271 {
00272 MARK;
00273 cout << "P: " << p << " log:" << static_cast<int>(logval) << " " << ceil(log_SieveEntryMultiplier*log(p)) << endl;
00274 exit(1);
00275 }
00276 #endif
00277 return logval;
00278 #else
00279
00280 return static_cast<TSieveElement>(ceil(log_SieveEntryMultiplier*log(p)));
00281 #endif
00282 }
00283
00284
00286 class SieveControl : protected StaticFactorbaseSettings
00287 {
00288 private:
00289 static const int FBLowestStartIndex = 5;
00290
00291
00292
00293
00294
00295
00296
00297
00298 inline static double DirtyFactor(const int i)
00299 {
00300 if (i<FBLowestStartIndex+4) return 1.0;
00301 return 1.0/sqrt(i);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 protected:
00333 static TSieveElement log_PrimeNumbers[StaticFactorbase::MaxSize] __attribute__ ((aligned (16)));
00334 private:
00335 static unsigned int PhysicalSieveIntervalIndex;
00336
00337
00338
00339 static unsigned int BestPSI[2];
00340
00341
00342 static TSieveElement PhysicalSieveIntervalThresholdCorrector[1024];
00343
00344
00345
00346
00347
00348
00349
00350
00351 static TSieveElement log_PrimeNumbers_dirty[StaticFactorbase::MaxSize] __attribute__ ((aligned (16)));
00352
00353
00354 static TSieveElement raw_log_Threshold, log_Threshold, log_ThresholdDeltaHint;
00355 static int myFBStartIndex, myFBStartIndexHint;
00356 static signed int DirtinessPegel;
00357
00358 public:
00359 inline static TSieveElement GetRawLogThreshold() { return raw_log_Threshold; }
00360 inline static TSieveElement GetLogThreshold()
00361 {
00362 return log_Threshold+PhysicalSieveIntervalThresholdCorrector[PhysicalSieveIntervalIndex];
00363 }
00364 inline static TSieveElement GetLogDirtyCorrection() { return raw_log_Threshold-log_Threshold; }
00365 inline static void RenewThresholds()
00366 {
00367 log_Threshold+=log_ThresholdDeltaHint;
00368 log_ThresholdDeltaHint=0;
00369 myFBStartIndex=myFBStartIndexHint;
00370 }
00371 static void RecalibrateThresholds();
00372 static void create_sieve_image(int* &Image, int mySieveOffset);
00373
00374 inline static int FBStartIndex() { return myFBStartIndex; }
00375 static void compute_SieveThreshold();
00376 static bool Hit_after_DirtyCorrection(const signed int SievePos, TSieveElement Value);
00377
00378 inline static TSieveElement PrimzahlSieveWeight(const int i)
00379 {
00380
00381
00382
00383
00384 return log_PrimeNumbers[i];
00385 }
00386 inline static TSieveElement PrimzahlSieveWeight_dirty(const int i)
00387 {
00388
00389
00390
00391
00392
00393 return log_PrimeNumbers_dirty[i];
00394 }
00395
00396 private:
00397
00398 static void set_logVal_for_Primenumber(const int pos, const TSieveElement val, const TSieveElement dirtyval);
00399 static void set_logVal_for_Primepower(const int pos, const TSieveElement val);
00400
00401 static void IncreaseDirtiness(void)
00402 {
00403
00404 if (myFBStartIndexHint>(StaticFactorbase::Size()>>2)) return;
00405 log_ThresholdDeltaHint-=PrimzahlSieveWeight_dirty(myFBStartIndexHint);
00406 ++myFBStartIndexHint;
00407 #ifdef VERBOSE_INFO
00408 cout << "suggested Dirtiness now " << myFBStartIndexHint << endl;
00409 #endif
00410 }
00411
00412 static void DecreaseDirtiness(void)
00413 {
00414
00415 if (myFBStartIndexHint<=FBLowestStartIndex) return;
00416 log_ThresholdDeltaHint+=PrimzahlSieveWeight_dirty(--myFBStartIndexHint);
00417 #ifdef VERBOSE_INFO
00418 cout << "suggested Dirtiness now " << myFBStartIndexHint << endl;
00419 #endif
00420 }
00421
00422 static void RequestDirtiness(const signed int Level)
00423 {
00424 DirtinessPegel+=Level;
00425 if (DirtinessPegel>1000000)
00426 {
00427 DirtinessPegel=0;
00428 IncreaseDirtiness();
00429 } else
00430 if (DirtinessPegel<-1000000)
00431 {
00432 DirtinessPegel=0;
00433 DecreaseDirtiness();
00434 }
00435 }
00436
00437 public:
00438 static inline void RequestMoreDirtiness(const signed int Level = 1000)
00439 {
00440 RequestDirtiness(Level);
00441 }
00442 static inline void RequestLessDirtiness(const signed int Level = 50)
00443 {
00444 RequestDirtiness(-Level);
00445 }
00446
00447 friend void StaticFactorbase::compute_StaticFactorbase();
00448 friend void initialize_Sieve();
00449 friend void initialize_Sieve(const int Image[]);
00450 friend void do_sieving_full_intervals();
00451 friend void do_sieving_partial_intervals();
00452 };
00453
00454 #include <qsieve.H>
00455 #include <vector>
00456
00457
00458
00459 namespace DynamicFactorArrays
00460 {
00461 extern unsigned int DynamicFactorsInUse;
00462 extern double DYNFB_threshold;
00463 void compute_Deltas_for_DynamicFactors(const int offset);
00464 }
00465
00466
00467
00468 class CDeltaComputations : protected StaticFactorbase
00469 {
00470 private:
00471
00472
00473
00474
00475
00476 static int D_mod_FBPrime[StaticFactorbase::MaxSize];
00477 static signed int D_difference_to_last;
00478 class CmpqsDmodPUpdater
00479 {
00480 public:
00481 mpz_t act_D;
00482 CmpqsDmodPUpdater()
00483 {
00484 mpz_init_set_d(act_D,-10e40);
00485 for (int i=0; i<StaticFactorbase::MaxSize; ++i) D_mod_FBPrime[i]=0;
00486 }
00487 ~CmpqsDmodPUpdater()
00488 {
00489 mpz_clear(act_D);
00490 }
00491 void update();
00492 };
00493
00494 static CmpqsDmodPUpdater mpqsDmodPUpdater;
00495 static unsigned int get_A2_mod_FBPrime(const int Nr)
00496 {
00497 #ifdef DEBUG
00498 if (Nr<3 || Nr>StaticFactorbase::Size()) { MARK; exit(777); }
00499 #endif
00500
00501 unsigned int h = numtheory::squaremod(D_mod_FBPrime[Nr],PrimeNumbers[Nr])<<1;
00502 if (h>=static_cast<unsigned int>(PrimeNumbers[Nr])) h-=PrimeNumbers[Nr];
00503 return h;
00504 }
00505 static unsigned int get_A2_mod_FBPrimePair(const int Nr)
00506 {
00507 #ifdef DEBUG
00508 if (Nr&1 || PrimeNumbers[Nr+1]>=46340) { MARK; exit(777); }
00509 #endif
00510
00511 unsigned int h = numtheory::squaremod(D_mod_FBPrime[Nr+1],D_mod_FBPrime[Nr])<<1;
00512 if (h>=static_cast<unsigned int>(D_mod_FBPrime[Nr])) h-=D_mod_FBPrime[Nr];
00513 return h;
00514 }
00515
00516
00517 protected:
00518 static int Delta_of_PrimeNumbers[StaticFactorbase::MaxSize][2] __attribute__ ((aligned (16)));
00519 static int Delta_of_PrimePowers[StaticFactorbase::max_additional_Powers][2] __attribute__ ((aligned (16)));
00520 static int LocalPhysInterval_Delta_of_PrimeNumbers[StaticFactorbase::MaxSize][2] __attribute__ ((aligned (16)));
00521 static int LocalPhysInterval_Delta_of_PrimePowers[StaticFactorbase::max_additional_Powers][2] __attribute__ ((aligned (16)));
00522
00523 private:
00524 static void recompute_all_Deltas(const bool DoReallyAll=true);
00525 static void GetStaticFactorHits(std::vector<unsigned int> &Factors, const signed int SievePos);
00526
00527 friend void do_sieving_full_intervals();
00528 friend void do_sieving_partial_intervals();
00529 friend CRelation::CRelation(const signed int SievePos, short int HitCount );
00530 friend bool SieveControl::Hit_after_DirtyCorrection(const signed int SievePos, TSieveElement Value);
00531 friend void DynamicFactorArrays::compute_Deltas_for_DynamicFactors(const int offset);
00532 };
00533
00534
00535
00536 class CSieveStaticFactors : private CDeltaComputations, protected SieveControl
00537 {
00538 private:
00539
00540 #if (TSIEVEELEMENTSIZE == 1)
00541
00542
00543
00544
00545 static unsigned short int LogValRuns[128];
00546 static unsigned short int PrimeNumberDiffs[MaxSize];
00547 static void init_LogValRuns()
00548 {
00549 for (int i=StaticFactorbase::Size()-1; i>1; --i)
00550 {
00551 unsigned int h=PrimeNumbers[i]-PrimeNumbers[i-1];
00552
00553 PrimeNumberDiffs[i]=h;
00554 }
00555
00556 register TSieveElement LogVal = PrimzahlSieveWeight(StaticFactorbase::Size()-1);
00557 register unsigned int c = 0;
00558 int pos = 0;
00559 for (int i = StaticFactorbase::Size()-1; PrimeNumbers[i]>=PhysicalSieveSize; --i)
00560 {
00561 if (SieveControl::PrimzahlSieveWeight(i)==LogVal) ++c;
00562 else
00563 {
00564 if (c>65534)
00565 {
00566 MARK;
00567 cerr << "overflow!" << endl;
00568 }
00569
00570 LogValRuns[pos]=c; c=1; ++pos;
00571 if (--LogVal != PrimzahlSieveWeight(i))
00572 {
00573 cerr << "unexpected LogValue!" << endl;
00574 MARK;
00575 exit(1);
00576 }
00577 }
00578 }
00579 LogValRuns[pos++]=c;
00580 LogValRuns[pos++]=0;
00581 LogValRuns[pos]=0;
00582
00583
00584
00585 }
00586 #endif
00587
00588 static void create_Tables_for_init_LocalDeltas(int* &Table1, int* &Table2, const int SieveOffset);
00589 static void init_LocalDeltas() __attribute__ ((deprecated));
00590 static void init_LocalDeltas(const int Table1[], const int Table2[]);
00591 static void do_sieving_StaticFactors();
00592
00593 static int* DefaultHelperTable[2];
00594
00595 public:
00596 static void initialize()
00597 {
00598 #if (TSIEVEELEMENTSIZE == 1)
00599 init_LogValRuns();
00600 #endif
00601 create_Tables_for_init_LocalDeltas(DefaultHelperTable[0],DefaultHelperTable[1], -LogicalSieveSize);
00602
00603 }
00604
00605 static void destruct()
00606 {
00607 delete [] DefaultHelperTable[1]; DefaultHelperTable[1]=NULL;
00608 delete [] DefaultHelperTable[0]; DefaultHelperTable[0]=NULL;
00609 }
00610
00611 friend void do_sieving_full_intervals();
00612 friend void do_sieving_partial_intervals();
00613 friend int main(const int argc, const char* const argv[]);
00614 };
00615
00616
00617 void do_scanning_Sieve(void);
00618
00619 void do_sieving_Squares();
00620 void do_sieving_DynamicFactors();
00621 void Werteverteilung_im_Sieb_ausgeben(void);
00622
00623 extern void (*do_sieving)();
00624 void do_sieving_full_intervals();
00625
00626 #include "DynamicFactorRelations.H"
00627 extern TDynamicFactorRelations DynamicFactorRelations;
00628
00629 #endif
00630
00631
00632
00633
00634
00635 class CHits
00636 {
00637 public: static const short int MaxHits=64;
00638 public: int Faktor;
00639 private: int Exponent;
00640 public:
00641 inline int GetExponent() const { return Exponent; }
00642 friend CRelation::CRelation(const signed int SievePos, short int HitCount );
00643 };
00644
00645 extern CHits Hits[CHits::MaxHits];
00646
00647 #endif