(1) (1/2) 处数组引用中的排名不匹配
Rank mismatch in array reference at (1) (1/2)
我是 Fortran 的新手,基本上只是在大学里玩。我的代码代表了一个更维的牛顿算法来解决残差问题。我将所有函数和子例程放在一个文件中,以排除因错误包含而出错的可能性。
我的问题是我在第 52 行收到以下错误:
J = DFuncDx(x)
错误:在 (1) (1/2) 处的数组引用中排名不匹配
我知道传递的参数的维度一定有问题,但我不知道问题出在哪里。在我的理解中,变量 x 被声明为 3 维数组,函数需要 3 维。
我使用 "gfortran -o nDNewtonMain nDNewtonMain.f90 -l lapack" 在 Linux 上编译。
此外,每当我调用函数 Funct 或 DFuncDx 时,我都会收到 "REAL array index at (1)" 警告。
program nDNewton
IMPLICIT NONE
integer, parameter :: N = 3
double precision, dimension(N) :: x
integer, parameter :: NMAXIT = 10
double precision, parameter :: MAXERR = 1.d-8
integer :: Nit, i
double precision :: ERR
do i=1,N
x(i) = 0.d0
end do
Nit = 0; ERR = 1.d0
call myNewton( x, Nit, NMAXIT, MAXERR, ERR, N)
write(*,*) "Solution: x="
do i=1,N
write(*,*) x(i)
end do
write(*,*) "Found after ", Nit, " iterations. Error: ", ERR
end program nDNewton
subroutine myNewton(x, Nit, NMAXIT, MAXERR, ERR, N)
IMPLICIT NONE
integer, intent(in) :: N
double precision, intent(inout), dimension(N) :: x
integer, intent(in) :: NMAXIT
integer, intent(inout) :: Nit
double precision, intent(in) :: MAXERR
double precision, intent(inout) :: ERR
double precision, dimension(N, N) :: J
integer, dimension(N) :: ipiv
integer :: info, i
double precision, dimension(N) :: F
double precision, dimension(N) :: Funct
double precision, dimension(N, N) :: DFuncDx
Nit = 0
F = Funct(x)
ERR = norm2(F)
do while (Nit < NMAXIT .AND. ERR > abs(MAXERR))
J = DFuncDx(x)
call DGESV( 3, 1, J, 3, ipiv, -F, 3, info )
x = x + F
Nit = Nit + 1
F = Funct(x)
ERR = norm2(F)
do i=1, 3
write(*,*) x(i)
end do
write(*,*) "Error: ", ERR,", Nit: ", Nit
end do
end subroutine myNewton
function Funct(x)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: ASys
double precision, dimension(3) :: a, e1
double precision, dimension(3) :: Funct
double precision :: exp_part
ASys = reshape( (/ 1.d0,2.d0/3.d0,-2.d0,0.d0,7.d0,6.d0/7.d0,-1.d0/3.d0,0.d0,1.d0 /), (/ 3,3/) )
ASys = transpose(ASys)
a = (/ 5.0, 3.0, 2.0 /)
e1 = (/ 1.0, 0.0, 0.0 /)
Funct = matmul(ASys, x) + a + exp_part(x(1), x(2), x(3)) * e1
end function
function DFuncDx(x)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: DFDx
double precision :: val
double precision, dimension(3, 3) :: DFuncDx
double precision :: exp_part
val = exp_part(x(1), x(2), x(3))
DFDx = reshape( (/ 1.d0 + val, 2.d0/3.d0 + 7.d-1*val, -2.d0 + 5.d-1*val, &
0.d0, 7.d0, 6.d0/7.d0, -1.d0/3.d0, 0.d0, 1.d0 /), (/ 3,3/) )
DFuncDx = transpose(DFDx)
end function
double precision function exp_part(x1, x2, x3)
IMPLICIT NONE
double precision, intent(in) :: x1, x2, x3
double precision, dimension(3) :: b
b = (/ 1.0, 0.7, 0.5 /)
exp_part = exp(b(1)*x1 + b(2)*x2 + b(3)*x3)
end function exp_part
多亏了 High Performance Mark,我才找到了解决方案。也许这会在将来帮助其他用户:
module A
contains
subroutine myNewton(x, Nit, NMAXIT, MAXERR, ERR, N)
IMPLICIT NONE
integer, intent(in) :: N
double precision, intent(inout), dimension(N) :: x
integer, intent(in) :: NMAXIT
integer, intent(inout) :: Nit
double precision, intent(in) :: MAXERR
double precision, intent(inout) :: ERR
double precision, dimension(N, N) :: J
integer, dimension(N) :: ipiv
integer :: info, i
double precision, dimension(N) :: F, B
Nit = 0
F = Funct(x)
ERR = norm2(F)
do while (Nit < NMAXIT .AND. ERR > abs(MAXERR))
J = DFuncDx(x)
B = -F
call DGESV( 3, 1, J, 3, ipiv, B, 3, info )
x = x + B
Nit = Nit + 1
F = Funct(x)
ERR = norm2(F)
do i=1, 3
write(*,*) x(i)
end do
write(*,*) "Error: ", ERR,", Nit: ", Nit
end do
end subroutine myNewton
function Funct(x) result(res)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: ASys
double precision, dimension(3) :: a, e1
double precision, dimension(3) :: res
ASys = reshape( (/ 1.d0,2.d0/3.d0,-2.d0,0.d0,7.d0,6.d0/7.d0,-1.d0/3.d0,0.d0,1.d0 /), (/ 3,3/) )
ASys = transpose(ASys)
a = (/ 5.0, 3.0, 2.0 /)
e1 = (/ 1.0, 0.0, 0.0 /)
res = matmul(ASys, x) + a + exp_part(x(1), x(2), x(3)) * e1
end function
function DFuncDx(x) result(res)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: DFDx
double precision :: val
double precision, dimension(3, 3) :: res
val = exp_part(x(1), x(2), x(3))
DFDx = reshape( (/ 1.d0 + val, 2.d0/3.d0 + 7.d-1*val, -2.d0 + 5.d-1*val, &
0.d0, 7.d0, 6.d0/7.d0, -1.d0/3.d0, 0.d0, 1.d0 /), (/ 3,3/) )
!DFDx
res = transpose(DFDx)
end function
double precision function exp_part(x1, x2, x3)
IMPLICIT NONE
double precision, intent(in) :: x1, x2, x3
double precision, dimension(3) :: b
b = (/ 1.0, 0.7, 0.5 /)
exp_part = exp(b(1)*x1 + b(2)*x2 + b(3)*x3)
end function exp_part
end module
program nDNewton
use A
IMPLICIT NONE
integer, parameter :: N = 3
double precision, dimension(N) :: x
integer, parameter :: NMAXIT = 10
double precision, parameter :: MAXERR = 1.d-8
integer :: Nit, i
double precision :: ERR
do i=1,N
x(i) = 0.d0
end do
Nit = 0; ERR = 1.d0
call myNewton( x, Nit, NMAXIT, MAXERR, ERR, N)
write(*,*) "Solution: x="
do i=1,N
write(*,*) x(i)
end do
write(*,*) "Found after ", Nit, " iterations. Error: ", ERR
x = Funct(x)
write(*,*) "Residium Test: r="
do i=1,N
write(*,*) x(i)
end do
end program nDNewton
我是 Fortran 的新手,基本上只是在大学里玩。我的代码代表了一个更维的牛顿算法来解决残差问题。我将所有函数和子例程放在一个文件中,以排除因错误包含而出错的可能性。 我的问题是我在第 52 行收到以下错误:
J = DFuncDx(x)
错误:在 (1) (1/2) 处的数组引用中排名不匹配
我知道传递的参数的维度一定有问题,但我不知道问题出在哪里。在我的理解中,变量 x 被声明为 3 维数组,函数需要 3 维。
我使用 "gfortran -o nDNewtonMain nDNewtonMain.f90 -l lapack" 在 Linux 上编译。
此外,每当我调用函数 Funct 或 DFuncDx 时,我都会收到 "REAL array index at (1)" 警告。
program nDNewton
IMPLICIT NONE
integer, parameter :: N = 3
double precision, dimension(N) :: x
integer, parameter :: NMAXIT = 10
double precision, parameter :: MAXERR = 1.d-8
integer :: Nit, i
double precision :: ERR
do i=1,N
x(i) = 0.d0
end do
Nit = 0; ERR = 1.d0
call myNewton( x, Nit, NMAXIT, MAXERR, ERR, N)
write(*,*) "Solution: x="
do i=1,N
write(*,*) x(i)
end do
write(*,*) "Found after ", Nit, " iterations. Error: ", ERR
end program nDNewton
subroutine myNewton(x, Nit, NMAXIT, MAXERR, ERR, N)
IMPLICIT NONE
integer, intent(in) :: N
double precision, intent(inout), dimension(N) :: x
integer, intent(in) :: NMAXIT
integer, intent(inout) :: Nit
double precision, intent(in) :: MAXERR
double precision, intent(inout) :: ERR
double precision, dimension(N, N) :: J
integer, dimension(N) :: ipiv
integer :: info, i
double precision, dimension(N) :: F
double precision, dimension(N) :: Funct
double precision, dimension(N, N) :: DFuncDx
Nit = 0
F = Funct(x)
ERR = norm2(F)
do while (Nit < NMAXIT .AND. ERR > abs(MAXERR))
J = DFuncDx(x)
call DGESV( 3, 1, J, 3, ipiv, -F, 3, info )
x = x + F
Nit = Nit + 1
F = Funct(x)
ERR = norm2(F)
do i=1, 3
write(*,*) x(i)
end do
write(*,*) "Error: ", ERR,", Nit: ", Nit
end do
end subroutine myNewton
function Funct(x)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: ASys
double precision, dimension(3) :: a, e1
double precision, dimension(3) :: Funct
double precision :: exp_part
ASys = reshape( (/ 1.d0,2.d0/3.d0,-2.d0,0.d0,7.d0,6.d0/7.d0,-1.d0/3.d0,0.d0,1.d0 /), (/ 3,3/) )
ASys = transpose(ASys)
a = (/ 5.0, 3.0, 2.0 /)
e1 = (/ 1.0, 0.0, 0.0 /)
Funct = matmul(ASys, x) + a + exp_part(x(1), x(2), x(3)) * e1
end function
function DFuncDx(x)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: DFDx
double precision :: val
double precision, dimension(3, 3) :: DFuncDx
double precision :: exp_part
val = exp_part(x(1), x(2), x(3))
DFDx = reshape( (/ 1.d0 + val, 2.d0/3.d0 + 7.d-1*val, -2.d0 + 5.d-1*val, &
0.d0, 7.d0, 6.d0/7.d0, -1.d0/3.d0, 0.d0, 1.d0 /), (/ 3,3/) )
DFuncDx = transpose(DFDx)
end function
double precision function exp_part(x1, x2, x3)
IMPLICIT NONE
double precision, intent(in) :: x1, x2, x3
double precision, dimension(3) :: b
b = (/ 1.0, 0.7, 0.5 /)
exp_part = exp(b(1)*x1 + b(2)*x2 + b(3)*x3)
end function exp_part
多亏了 High Performance Mark,我才找到了解决方案。也许这会在将来帮助其他用户:
module A
contains
subroutine myNewton(x, Nit, NMAXIT, MAXERR, ERR, N)
IMPLICIT NONE
integer, intent(in) :: N
double precision, intent(inout), dimension(N) :: x
integer, intent(in) :: NMAXIT
integer, intent(inout) :: Nit
double precision, intent(in) :: MAXERR
double precision, intent(inout) :: ERR
double precision, dimension(N, N) :: J
integer, dimension(N) :: ipiv
integer :: info, i
double precision, dimension(N) :: F, B
Nit = 0
F = Funct(x)
ERR = norm2(F)
do while (Nit < NMAXIT .AND. ERR > abs(MAXERR))
J = DFuncDx(x)
B = -F
call DGESV( 3, 1, J, 3, ipiv, B, 3, info )
x = x + B
Nit = Nit + 1
F = Funct(x)
ERR = norm2(F)
do i=1, 3
write(*,*) x(i)
end do
write(*,*) "Error: ", ERR,", Nit: ", Nit
end do
end subroutine myNewton
function Funct(x) result(res)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: ASys
double precision, dimension(3) :: a, e1
double precision, dimension(3) :: res
ASys = reshape( (/ 1.d0,2.d0/3.d0,-2.d0,0.d0,7.d0,6.d0/7.d0,-1.d0/3.d0,0.d0,1.d0 /), (/ 3,3/) )
ASys = transpose(ASys)
a = (/ 5.0, 3.0, 2.0 /)
e1 = (/ 1.0, 0.0, 0.0 /)
res = matmul(ASys, x) + a + exp_part(x(1), x(2), x(3)) * e1
end function
function DFuncDx(x) result(res)
IMPLICIT NONE
double precision, dimension(3), intent(in) :: x
double precision, dimension(3, 3) :: DFDx
double precision :: val
double precision, dimension(3, 3) :: res
val = exp_part(x(1), x(2), x(3))
DFDx = reshape( (/ 1.d0 + val, 2.d0/3.d0 + 7.d-1*val, -2.d0 + 5.d-1*val, &
0.d0, 7.d0, 6.d0/7.d0, -1.d0/3.d0, 0.d0, 1.d0 /), (/ 3,3/) )
!DFDx
res = transpose(DFDx)
end function
double precision function exp_part(x1, x2, x3)
IMPLICIT NONE
double precision, intent(in) :: x1, x2, x3
double precision, dimension(3) :: b
b = (/ 1.0, 0.7, 0.5 /)
exp_part = exp(b(1)*x1 + b(2)*x2 + b(3)*x3)
end function exp_part
end module
program nDNewton
use A
IMPLICIT NONE
integer, parameter :: N = 3
double precision, dimension(N) :: x
integer, parameter :: NMAXIT = 10
double precision, parameter :: MAXERR = 1.d-8
integer :: Nit, i
double precision :: ERR
do i=1,N
x(i) = 0.d0
end do
Nit = 0; ERR = 1.d0
call myNewton( x, Nit, NMAXIT, MAXERR, ERR, N)
write(*,*) "Solution: x="
do i=1,N
write(*,*) x(i)
end do
write(*,*) "Found after ", Nit, " iterations. Error: ", ERR
x = Funct(x)
write(*,*) "Residium Test: r="
do i=1,N
write(*,*) x(i)
end do
end program nDNewton