Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_MATH_PRIME_NUMBERS_H
00002 #define OPENTISSUE_CORE_MATH_MATH_PRIME_NUMBERS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_constants.h>
00013 #include <OpenTissue/core/math/math_random.h>
00014
00015 #include <cmath>
00016
00017
00018 namespace OpenTissue
00019 {
00020
00021 namespace math
00022 {
00023
00024
00025 namespace detail
00026 {
00027
00036 inline bool withness(int a,int n)
00037 {
00038 int ndec = n-1;int d = 1; int k = ndec;
00039 if(k!=0)
00040 {
00041 int c=0;
00042 while((k&0x80000000)==0)
00043 k<<=1;c++;
00044 while(c<32)
00045 {
00046 int x =d;
00047 d=(d*d)%n;
00048 if((d==1)&&(x!=1)&&(x!=ndec))
00049 return true;
00050 if((k&0x80000000)!=0)
00051 d=(d*a)%n;
00052 k<<=1;c++;
00053 }
00054 }
00055 if(d!=1)
00056 return true;
00057 return false;
00058 }
00059
00060 }
00061
00062
00077 inline bool trial_division(int n)
00078 {
00079 using std::sqrt;
00080 using std::floor;
00081
00082 double sqrN = sqrt(static_cast<double>(n));
00083 int j = static_cast<int>( floor(sqrN) );
00084 for(int i=2;i<=j;++i)
00085 {
00086 if((n%i)==0)
00087 return false;
00088 }
00089 return true;
00090 }
00091
00096 inline int modular_exponentiation(int a,int b,int n)
00097 {
00098 int d = 1;
00099 while(b!=0)
00100 {
00101 if((b&1)!=0)
00102 d=(d*a)%n;
00103 a = (a*a)%n;
00104 b>>=1;
00105 }
00106 return d;
00107 }
00108
00124 inline bool pseudo_prime(int n)
00125 {
00126 if((n==1)||(n==2))
00127 return true;
00128 if(modular_exponentiation(2,n-1,n)!=1)
00129 return false;
00130 return true;
00131 }
00132
00133
00147 inline bool miller_rabin(int n,int s)
00148 {
00149 using std::floor;
00150
00151 static Random<double> random;
00152
00153 int ndec = n-2;
00154 for(int j=s;j>0;--j)
00155 {
00156 int a = static_cast<int>( floor( random()*ndec ) ) + 1;
00157 if(detail::withness(a,n))
00158 return false;
00159 }
00160 return true;
00161 }
00162
00172 inline int prime_search(int n)
00173 {
00174 int l = n;
00175 if((l%2)==0)
00176 l--;
00177 for(;l>1;l=l-2)
00178 {
00179
00180
00181 if(miller_rabin(l,4))
00182 break;
00183 }
00184 int o = n;
00185 if((o%2)==0)
00186 o++;
00187 int max_val = detail::highest<int>();
00188 for(;o<max_val;o=o+2)
00189 {
00190
00191
00192 if(miller_rabin(o,4))
00193 break;
00194 }
00195
00196
00197
00198
00199 if((n-l)<(o-n))
00200 return l;
00201 return o;
00202 }
00203
00212 inline int gcd_euclid_algorithm(int a,int b)
00213 {
00214 if(b==0)
00215 return a;
00216 else
00217 return gcd_euclid_algorithm(b,a%b);
00218 }
00219
00227 inline bool is_relative_prime(int a,int b)
00228 {
00229 if(gcd_euclid_algorithm(a,b)==1)
00230 return true;
00231 return false;
00232 }
00233
00234 }
00235
00236 }
00237
00238
00239 #endif