gpt4 book ai didi

recursion - 错误: Statement Function is recursive

转载 作者:行者123 更新时间:2023-12-02 23:30:21 25 4
gpt4 key购买 nike

这是尝试求解 3*3 的线性方程并打印结果,但在注释行中遇到了问题:

我在程序外部定义了 LinearSolution 模块,我应该在程序内部定义它吗?有什么区别?

为什么说该语句是递归的,你知道,当我使用这些语句作为普通子例程而不是模块子例程时,它们被验证是没问题的。

module LinearSolution
type LAE
integer::N
double precision,dimension(:,:),allocatable::A
double precision,dimension( :),allocatable::B
contains
procedure,nopass::RowReduction
end type LAE
contains
subroutine RowReduction
double precision::C
do k=1,N
do i=k+1,N
if(A(k,k)/=0) then
C=A(i,k)/A(k,k)
B(i)=B(i)-B(k)*C !error: Statement Function is recursive
do j=k+1,N
A(i,j)=A(i,j)-A(k,j)*C !error: Statement Function is recursive
end do
end if
end do
end do

do k=N,1,-1
do i=k-1,1,-1
if(A(k,k)/=0) then
C=A(i,k)/A(k,k)
B(i)=B(i)-B(k)*C !error: Statement Function is recursive
end if
end do
end do

do k=1,N
if(A(k,k)/=0) then
B(k)=B(k)/A(k,k) !error: Statement Function is recursive
end if
end do
end subroutine RowReduction
end module LinearSolution

program TestLAE
use LinearSolution !fatal error: cant open module file LinearSolution.mod for reading
type(LAE)::LAE1
LAE1%N=3
allocate(LAE1%B(1:N))
allocate(LAE1%A(1:N,1:N))
LAE1%B=(/1,1,1/)
LAE1%A=(/2,0,0,0,2,0,0,0,2/)
call LAE1%RowReduction
print*, LAE1%B(1),LAE1%B(2),LAE1%B(3)
end program

最佳答案

正如经常发生的情况一样,隐含的没有是你的 friend 。

让我们一次一个地查看错误:

B(i)=B(i)-B(k)*C       !error: Statement Function is recursive

编译器在此上下文中无法识别B;这里没有声明 B 变量(*),所以它能做的最好的事情就是假设它是一个实值 statement function将 B 定义为 I 的函数。语句函数是一种节省空间但又令人困惑的内联定义函数的方法,但除其他外,它们不能是递归的;在这里,您将根据 B(i) 定义 B(i),这显然是失败的。

(*)但是!你哭。 B 是我的类型 LAE 中的数组字段!是的,但我们这里讨论的不是 LAE。事实上,在此函数的上下文中,没有 LAE 类型的变量甚至可以使用 B 值。这是因为该过程被定义为nopass;您需要有一个变量,该变量是正在操作的 LAE 类对象,以便我们可以访问这些字段。看起来像这样:

    type LAE
!...
contains
procedure::RowReduction
end type LAE

contains
subroutine RowReduction(self)
class(LAE), intent(InOut) :: self
double precision::C
integer :: i, j, k
do k= 1, self%N
do i= k+1, self%N
if( self%A(k,k) /= 0 ) then
!....

请注意,我们必须将 self 定义为 class(LAE) 而不是类型;类是类型的超集,在处理可扩展对象(包括具有(重新)分配组件的对象)时需要使用类。另请注意,我们添加了隐式 none,它会立即告诉您 B 尚未定义,因此指定了整数索引 i、j 和 k。

一旦 NAB 被正确引用为 self 的字段,那么大多数程序的其余部分是正确的。请注意,您必须 reshape 您的LAE1%A数组:

LAE1%A=reshape((/2,0,0,0,2,0,0,0,2/), (/N, N/))

但除此之外一切似乎都很好。

module LinearSolution
implicit none

type LAE
integer::N
double precision,dimension(:,:),allocatable::A
double precision,dimension( :),allocatable::B
contains
procedure::RowReduction
end type LAE

contains
subroutine RowReduction(self)
class(LAE), intent(InOut) :: self
double precision::C
integer :: i, j, k
do k= 1, self%N
do i= k+1, self%N
if( self%A(k,k) /= 0 ) then
C = self%A(i,k) / self%A(k,k)
self%B(i) = self%B(i)- self%B(k)*C
do j=k+1, self%N
self%A(i,j) = self%A(i,j) - self%A(k,j)*C
end do
end if
end do
end do

do k = self%N,1,-1
do i=k-1,1,-1
if( self%A(k,k)/=0) then
C= self%A(i,k)/ self%A(k,k)
self%B(i)= self%B(i)- self%B(k)*C
end if
end do
end do

do k=1, self%N
if( self%A(k,k)/=0 ) then
self%B(k) = self%B(k) / self%A(k,k)
end if
end do
end subroutine RowReduction
end module LinearSolution

program TestLAE
use LinearSolution
implicit none

integer, parameter :: N = 3
type(LAE)::LAE1
LAE1%N=N
allocate(LAE1%B(1:N))
allocate(LAE1%A(1:N,1:N))
LAE1%B=(/1,1,1/)
LAE1%A=reshape((/2,0,0,0,2,0,0,0,2/), (/N, N/))
call LAE1%RowReduction
print*, LAE1%B(1),LAE1%B(2),LAE1%B(3)
end program

运行给出:

$ gfortran -o lae lae.f90 -Wall -std=f2003
$ ./lae
0.50000000000000000 0.50000000000000000 0.50000000000000000

关于recursion - 错误: Statement Function is recursive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14078464/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com