包 ranlib.f 中的子程序 ignpoi 已损坏
The subroutine ignpoi in the package ranlib.f is broken
我正在使用 gfortran:linux.
上的 GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
我正在尝试使用此来源 ranlib.f
中的 ignpoi
http://www.netlib.org/random/ (http://www.netlib.org/random/ranlib.f.tar.gz)
我使用
编译库
gfortran -O2 -c *.f
ar cr libranlib.a *.o
当我编写简单的程序来测试 ignpoi(泊松偏差发生器)时
program test
implicit none
integer seed1, seed2, i
real av
integer ignpoi
seed1=123456
seed2=654321
call setall(seed1,seed2)
av=8.0
do i=1,10
print *, ignpoi(av)
enddo
end
具有相同的平均值,但在一个或多个偏差后会出现分段错误。
12
7
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F077F1D3E48
#1 0x7F077F1D2FD0
#2 0x7F077E9042EF
#3 0x401288 in ignpoi_
#4 0x400A3D in MAIN__ at test.f:?
Segmentation fault (core dumped)
我是这样编译测试的,没有编译错误。
gfortran test.f libranlib.a
奇怪的是,当我每次要求不同的号码时,都没有问题。当我评论第 104-105 行时
IF (mu.EQ.muprev) GO TO 10
IF (mu.LT.10.0) GO TO 120
of ignpoi.f
, 问题解决了。
这可以复制吗?
错误的原因是什么?
我知道第 104-105 行是为了节省计算时间。如何修改当前函数以从预计算中受益,而不会出现以相同的平均多次调用函数的问题?
好吧,那个特定的代码被破坏了......在 ignpoi.f
,ll。 218:
IF (mu.EQ.muold) GO TO 130
muold = mu
m = max0(1,ifix(mu))
l = 0
p = exp(-mu)
q = p
p0 = p
C
C STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
C
130 u = ranf()
第一个条件为真,因此您跳过 m
、l
、p
、q
和 p0
的初始化。在这些变量中,之前只有 l
被触及 - 但是 mu == muold
也被跳过了。
不幸的是,很多随后的 calculations/branches 取决于提到的变量,这导致 - 请原谅双关语 - 随机行为。
我不知道在你的情况下段错误发生在哪里,在我的机器上我最终陷入了无限循环。最简单的解决方案是禁用存储旧值。为此,注释掉(或删除)行 (144 & 219)
muold = mu
或者,禁用跳过初始化 (l. 218):
C IF (mu.EQ.muold) GO TO 130
我正在使用 gfortran:linux.
上的 GNU Fortran (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4我正在尝试使用此来源 ranlib.f
中的 ignpoi
http://www.netlib.org/random/ (http://www.netlib.org/random/ranlib.f.tar.gz)
我使用
编译库 gfortran -O2 -c *.f
ar cr libranlib.a *.o
当我编写简单的程序来测试 ignpoi(泊松偏差发生器)时
program test
implicit none
integer seed1, seed2, i
real av
integer ignpoi
seed1=123456
seed2=654321
call setall(seed1,seed2)
av=8.0
do i=1,10
print *, ignpoi(av)
enddo
end
具有相同的平均值,但在一个或多个偏差后会出现分段错误。
12
7
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F077F1D3E48
#1 0x7F077F1D2FD0
#2 0x7F077E9042EF
#3 0x401288 in ignpoi_
#4 0x400A3D in MAIN__ at test.f:?
Segmentation fault (core dumped)
我是这样编译测试的,没有编译错误。
gfortran test.f libranlib.a
奇怪的是,当我每次要求不同的号码时,都没有问题。当我评论第 104-105 行时
IF (mu.EQ.muprev) GO TO 10
IF (mu.LT.10.0) GO TO 120
of ignpoi.f
, 问题解决了。
这可以复制吗?
错误的原因是什么?
我知道第 104-105 行是为了节省计算时间。如何修改当前函数以从预计算中受益,而不会出现以相同的平均多次调用函数的问题?
好吧,那个特定的代码被破坏了......在 ignpoi.f
,ll。 218:
IF (mu.EQ.muold) GO TO 130
muold = mu
m = max0(1,ifix(mu))
l = 0
p = exp(-mu)
q = p
p0 = p
C
C STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
C
130 u = ranf()
第一个条件为真,因此您跳过 m
、l
、p
、q
和 p0
的初始化。在这些变量中,之前只有 l
被触及 - 但是 mu == muold
也被跳过了。
不幸的是,很多随后的 calculations/branches 取决于提到的变量,这导致 - 请原谅双关语 - 随机行为。
我不知道在你的情况下段错误发生在哪里,在我的机器上我最终陷入了无限循环。最简单的解决方案是禁用存储旧值。为此,注释掉(或删除)行 (144 & 219)
muold = mu
或者,禁用跳过初始化 (l. 218):
C IF (mu.EQ.muold) GO TO 130