我对Fortran编程还不是很陌生,所以这可能是一个明显的问题,请耐心等待。 这是我正在使用的代码:
program A1H
! Householder transformation
implicit none
integer,parameter::dp=selected_real_kind(15,307) ! Double precision kind
real(kind=dp), dimension(6,3)::A
real(kind=dp), dimension(6,1)::b
integer, dimension(6,6)::Pglobal ! Global identity matrix
integer::i,j,g
g = size(A,1)
do j=1,g
do i=1,g
Pglobal(i,j) = (i/j)*(j/i)
end do
end do
b(:,1) = [1237,1941,2417,711,1177,475]
A(1,:) = [1,0,0]
A(2,:) = [0,1,0]
A(3,:) = [0,0,1]
A(4,:) = [-1,1,0]
A(5,:) = [-1,0,1]
A(6,:) = [0,-1,1]
call mat_print('A',A)
call mat_print('b',b)
call mat_print('Pglobal',Pglobal)
call householder(A,b)
contains
subroutine householder(A,b)
real(kind=dp), intent(in)::A(:,:),b(:,:)
real(kind=dp)::alpha,gamma,beta
real(kind=dp), dimension(6,6)::H
real(kind=dp), dimension(6,3)::y,aa
real(kind=dp), dimension(6,1)::yy,v,dglobal,ek,bb
real(kind=dp), dimension(1,6)::d
integer::k,m,n,j
m = size(A,1)
n = size(A,2)
aa = A
bb = b
do k=1,n
dglobal(:,k) = [0,0,0,0,0,0]
alpha = -sign(aa(k,k),aa(k,k))*norm2(aa(k:m,k))
ek(:,1) = Pglobal(:,k)
dglobal(k:m,k) = aa(k:m,k)
v(:,k) = (dglobal(:,k)) - alpha*ek(:,1)
d(k,:) = v(:,k)
beta = dot_product(d(k,:),v(:,k))
if (beta==0) then
continue
end if
H = Pglobal - (2/beta)*(matmul(reshape(v(:,k),(/m,1/)),reshape(d(k,:),(/1,m/))))
y = matmul(H,aa)
yy = matmul(H,bb)
aa = y
bb = yy
call mat_print('aa',y)
call mat_print('bb',yy)
end do
end subroutine
! Matrix print subroutine
subroutine mat_print(b,a)
character(*), intent(in)::b
class(*), intent(in)::a(:,:)
integer::i
print*,' '
print*,b
do i=1,size(a,1)
select type (a)
type is (real(kind=dp)) ; print'(100f9.4)',a(i,:)
type is (integer) ; print'(100i9 )',a(i,:)
end select
end do
print*,' '
end subroutine
end program
我遇到的问题是,当我将变量aa
更改为另一个名称时,我得到了y
变量的错误结果;如果我保持原样,那是正确的;但是,将bb
变量保留为原样,则yy
结果不正确,但是如果将bb
变量更改为另一个其他名称,则会得到yy
的正确结果,但是我对y
的回答改变了!我很困惑如何发生,因为我的编码经验告诉我答案不应该基于简单的变量名更改而改变,如果您看一下代码,则y
和yy
变量甚至在算法中都没有连接。这不是我之前遇到此问题的唯一Fortran代码。任何帮助将不胜感激。
答案 0 :(得分:2)
我能够用GNU Fortran (Homebrew GCC 8.2.0) 8.2.0
重现您的错误。您的程序中确实存在错误。您可以通过使用选项-fbounds_check
进行编译来查找此错误。运行它时,您会发现几个数组访问没有意义。例如,您访问dglobal(:,k) = [0,0,0,0,0,0]
,但是dglobal
的第二维仅为1。使用此标志可帮助修复您的代码,并且我确定此错误将消失。
对于任何想深入了解此错误的出现取决于变量名的人,我都可以使用数组名test_array
来重现它,而不能使用其他短名来重现。如果设置了test_array
,我还可以使用-fmax-stack-var-size=100
名称获得正确的答案,并且其他值的大小不同。我的猜测是gfortran将这些数组放在堆栈上,并且顺序基于名称。某些名称将其放置在“安全”位置,以便缓冲区溢出不会覆盖这些值。