R-Lehmann素性检验中的模警告
我花了一点时间破解了lehmann素性测试的R实现。我借鉴的功能设计 这是我的密码:R-Lehmann素性检验中的模警告,r,primes,R,Primes,我花了一点时间破解了lehmann素性测试的R实现。我借鉴的功能设计 这是我的密码: primeTest <- function(n, iter){ a <- sample(1:(n-1), 1) lehmannTest <- function(y, tries){ x <- ((y^((n-1)/2)) %% n) if (tries == 0) { return(TRUE) }else{
primeTest <- function(n, iter){
a <- sample(1:(n-1), 1)
lehmannTest <- function(y, tries){
x <- ((y^((n-1)/2)) %% n)
if (tries == 0) {
return(TRUE)
}else{
if ((x == 1) | (x == (-1 %% n))){
lehmannTest(sample(1:(n-1), 1), (tries-1))
}else{
return(FALSE)
}
}
}
lehmannTest(a, iter)
}
primeTest(4, 50) # false
primeTest(3, 50) # true
primeTest(10, 50)# false
primeTest(97, 50) # gives false # SHOULD BE TRUE !!!! WTF
prime_test<-c(2,3,5,7,11,13,17 ,19,23,29,31,37)
for (i in 1:length(prime_test)) {
print(primeTest(prime_test[i], 50))
}
经过一些调查,我相信这与浮点转换有关。非常大的数字被四舍五入,因此mod函数给出了错误的响应
现在是问题
modexp<-function(a, b, n){
r = 1
for (i in 1:b){
r = (r*a) %% n
}
return(r)
}
primeTest <- function(n, iter){
a <- sample(1:(n-1), 1)
lehmannTest <- function(y, tries){
x <- modexp(y, (n-1)/2, n)
if (tries == 0) {
return(TRUE)
}else{
if ((x == 1) | (x == (-1 %% n))){
lehmannTest(sample(1:(n-1), 1), (tries-1))
}else{
return(FALSE)
}
}
}
if( n < 2 ){
return(FALSE)
}else if (n ==2) {
return(TRUE)
} else{
lehmannTest(a, iter)
}
}
primeTest(4, 50) # false
primeTest(3, 50) # true
primeTest(10, 50)# false
primeTest(97, 50) # NOW IS TRUE !!!!
prime_test<-c(5,7,11,13,17 ,19,23,29,31,37,1009)
for (i in 1:length(prime_test)) {
print(primeTest(prime_test[i], 50))
}
#ALL TRUE
modexp如果您只使用base R,我会选择#2b。。。“R不擅长这个”。在R中,整数(您似乎没有使用)被限制为16位精度。超过该限制,您将得到舍入误差。您可能应该查看:package:gmp或package:Brobdingnag。包:gmp有大整数和大有理数类。当然,表示整数有问题。在R中,整数将正确表示为2^53-1,约为9e15。而术语y^((n-1)/2)
即使对于小的数字也很容易超过这个值。您必须通过不断平方y
并取模来计算(y^((n-1)/2))%%n
。对应于(n-1)/2
的二进制表示
即使是“实数”数论程序也是如此——参见维基百科的“模幂运算”。也就是说,应该提到的是,像R(或Matlab和其他数值计算系统)这样的程序可能不是实现数论算法的合适环境,甚至可能不是小整数的游戏场
编辑:原始包不正确
您可以像下面这样使用包“pracma”中的函数modpower():
primeTest <- function(n, iter){
a <- sample(1:(n-1), 1)
lehmannTest <- function(y, tries){
x <- modpower(y, (n-1)/2, n) # ((y^((n-1)/2)) %% n)
if (tries == 0) {
return(TRUE)
}else{
if ((x == 1) | (x == (-1 %% n))){
lehmannTest(sample(1:(n-1), 1), (tries-1))
}else{
return(FALSE)
}
}
}
lehmannTest(a, iter)
}
primeTest感谢您的帮助。我不能说这对工作是至关重要的,但这一练习完全击败了我。但现在我知道了模幂运算,我可以快乐地死去。研究之后,我使用pow()函数在python中重写了该函数。我很高兴R中有一个实现。这个解决方案适用于一些数字。然而,当指数不是一个自然数时,modpower函数就会爆炸。这是包中的源代码。指数必须是一个自然数:地板(k)=天花板(k)。当n=4,(n-1)/2=1.5且modpower功能失效时。
primeTest <- function(n, iter){
a <- sample(1:(n-1), 1)
lehmannTest <- function(y, tries){
x <- modpower(y, (n-1)/2, n) # ((y^((n-1)/2)) %% n)
if (tries == 0) {
return(TRUE)
}else{
if ((x == 1) | (x == (-1 %% n))){
lehmannTest(sample(1:(n-1), 1), (tries-1))
}else{
return(FALSE)
}
}
}
lehmannTest(a, iter)
}
prime_test <- seq(1001, 1011, by = 2)
for (i in 1:length(prime_test)) {
print(primeTest(prime_test[i], 50))
}
# FALSE FALSE FALSE FALSE TRUE FALSE