我有一个Fortran程序,该程序在模块中使用例程来调整矩阵的大小,例如:
module resizemod
contains
subroutine ResizeMatrix(A,newSize,lindx)
integer,dimension(:,:),intent(inout),pointer :: A
integer,intent(in) :: newSize(2)
integer,dimension(:,:),allocatable :: B
integer,optional,intent(in) :: lindx(2)
integer :: i,j
allocate(B(lbound(A,1):ubound(A,1),lbound(A,2):ubound(A,2)))
forall (i=lbound(A,1):ubound(A,1),j=lbound(A,2):ubound(A,2))
B(i,j)=A(i,j)
end forall
if (associated(A)) deallocate(A)
if (present(lindx)) then
allocate(A(lindx(1):lindx(1)+newSize(1)-1,lindx(2):lindx(2)+newSize(2)-1))
else
allocate(A(newSize(1),newSize(2)))
end if
do i=lbound(B,1),ubound(B,1)
do j=lbound(B,2), ubound(B,2)
A(i,j)=B(i,j)
end do
end do
deallocate(B)
end subroutine ResizeMatrix
end module resizemod
主程序如下所示:
program resize
use :: resizemod
implicit none
integer,pointer :: mtest(:,:)
allocate(mtest(0:1,3))
mtest(0,:)=[1,2,3]
mtest(1,:)=[1,4,5]
call ResizeMatrix(mtest,[3,3],lindx=[0,1])
mtest(2,:)=0
print *,mtest(0,:)
print *,mtest(1,:)
print *,mtest(2,:)
end program resize
我使用ifort 14.0编译代码。我面临的问题是有时我无法获得预期的结果:
1 0 0
1 0 5
0 0 -677609912
实际上,我无法使用最少的测试代码来重现该问题(在我的原始程序中存在)。但是我注意到的一点是,当我删除编译器选项时-fast
,此问题消失了。
那我的问题是
我使用的代码段是否完全合法?
是否建议使用其他方法调整矩阵大小,这比此处介绍的方法更好?
所描述问题与编译器选项“ -fast”的相关性。
如果我正确阅读了代码,则是合法的但不正确。在您的示例中,您已将2x3
数组的大小调整为,3x3
但是例程ResizeMatrix
不执行任何操作来设置额外元素的值。您看到的奇怪值(例如-677609912
)是作为整数的解释。读取与未设置的数组元素相对应的存储位置时,内存中的所有位都将被置位(以便可以将其值写出)。
与此相关的-fast
是,在调试或低优化模式下,编译器通常会将内存位置清零,而在打开更高的优化功能时则不会打扰。该程序合法,因为它不包含编译器可确定的语法错误。但是从某种意义上说,读取一个没有初始化或赋值的变量不是您应该定期执行的操作,这是不正确的。这样做实际上会使您的程序没有确定性。
对于您的问题2,这增加了您不熟悉内部函数reshape
(F2003)的可能性move_alloc
。后者几乎可以肯定是您想要的,前者也可以提供帮助。
顺便说一句:这些天我很少pointer
在数组上使用,allocatable
它有用得多,并且通常也更容易和安全。但是您可能有我无法满足的要求。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句