FORTRAN-正确的值是以简单的精度计算的,而错误的解是以双精度计算的?
我有以下代码,关于牛顿计算多变量向量函数零点的方法:FORTRAN-正确的值是以简单的精度计算的,而错误的解是以双精度计算的?,fortran,double-precision,newtons-method,Fortran,Double Precision,Newtons Method,我有以下代码,关于牛顿计算多变量向量函数零点的方法: program Newton_Method_R_N_R_N_1_Numeric use Inverse_Matrices implicit none integer :: i, j !INDEX real (kind = 8) :: X(0:501,3) !VECTORS IN NEWTON METHOD real (kind = 8) :: A(3
program Newton_Method_R_N_R_N_1_Numeric
use Inverse_Matrices
implicit none
integer :: i, j !INDEX
real (kind = 8) :: X(0:501,3) !VECTORS IN NEWTON METHOD
real (kind = 8) :: A(3,3) !JACOBI'S MATRIX FOR EACH VECTOR
integer , parameter :: n = 3 !DIMENSION OF JACOBI'S MATRIZ
real (kind = 8) :: Inv(3,3) !INVERSE JACOBI'S MATRIX
real (kind = 8), parameter :: eps = 1D-8 !NEAR-ZERO VALUE
real (kind = 8) :: det !DETERMINANT
X(0,:) = (/2.D0,2.D0,2.D0/)
do i = 0, 500
A = h(X(i,:))
call LU_Factorization (n, A)
call Determinant (n, A, det)
if (abs(det)<eps) then
exit
end if
call Inverse_Matrix (n, A, Inv)
X(i + 1,:) = X(i,:) - matmul(Inv,g(X(i,:)))
end do
write(*,*) ' A zero of the function is: ', X(i,:)
read(*,*)
contains
function g(t)
implicit none
real (kind = 8), intent(in) :: t(3)
real (kind = 8) :: g(3)
g(1) = t(1)**2 - t(2)**2 + 1.0D0
g(2) = 2.0D0*t(1)*t(2)
g(3) = t(3)**2 - 2.0D0
end function g
function g_1(t_1)
implicit none
real (kind = 8), intent(in) :: t_1(3)
real (kind = 8) :: g_1
g_1 = t_1(1)**2 - t_1(2)**2 + 1.0D0
end function g_1
function g_2(t_2)
implicit none
real (kind = 8), intent(in) :: t_2(3)
real (kind = 8) :: g_2
g_2 = (2.0D0)*t_2(1)*t_2(2)
end function g_2
function g_3(t_3)
implicit none
real (kind = 8), intent(in) :: t_3(3)
real (kind = 8) :: g_3
g_3 = t_3(3)**2 - 2.0D0
end function g_3
function h(q)
implicit none
real (kind = 8), intent(in) :: q(3)
real (kind = 8) :: h(3,3)
real (kind = 8), parameter :: dx = 1D-4
real (kind = 8) :: a(3)
real (kind = 8) :: b(3)
real (kind = 8) :: c(3)
a(1) = dx
a(2) = 0.D0
a(3) = 0.D0
b(1) = 0.D0
b(2) = dx
b(3) = 0.D0
c(1) = 0.D0
c(2) = 0.D0
c(3) = dx
h(1,1) = ((g_1(q + a)) - g_1(q)) / dx
h(1,2) = ((g_1(q + b)) - g_1(q)) / dx
h(1,3) = ((g_1(q + c)) - g_1(q)) / dx
h(2,1) = ((g_2(q + a)) - g_2(q)) / dx
h(2,2) = ((g_2(q + b)) - g_2(q)) / dx
h(2,3) = ((g_2(q + c)) - g_2(q)) / dx
h(3,1) = ((g_3(q + a)) - g_3(q)) / dx
h(3,2) = ((g_3(q + b)) - g_3(q)) / dx
h(3,3) = ((g_3(q + c)) - g_3(q)) / dx
end function h
end program
您为我们提供了一个模块
矩阵逆矩阵2
,其中包含明显的西班牙语命名过程,但您的程序使用了一个名为逆矩阵的模块,因此我们仍然没有一组完全可编译的代码
您还没有指定您认为正确显示的内容。
我对您的模块代码进行了明显的更改,以便使用nagfor-kind=byte-u-C=all-C=undefined-gline
匹配并编译您的过程名。跑步,我得到了
mod.f90:
[NAG Fortran Compiler normal termination]
test.f90:
Warning: test.f90, line 93: Unused local variable J
[NAG Fortran Compiler normal termination, 1 warning]
Loading...
Runtime Error: mod.f90, line 27: Reference to undefined variable V
Program terminated by fatal error
mod.f90, line 27: Error occurred in MATRICES_INVERSAS_2:FACTORIZACION_LU
test.f90, line 18: Called by NEWTON_METHOD_R_N_R_N_1_NUMERIC
Abort (core dumped)
您正在尝试两种大小的n
数组(V
和W
)的dot\u产品
),从您的代码来看,似乎只有第一个(k-1)
元素被初始化。如果我将两个dot_product
调用替换为dot_product(V(1:(k-1)),W(1:(k-1))
,则程序运行到完成并显示
A zero of the function is: 0.0000000000000000 1.0000000000000000 1.4142135623730951
逆矩阵模块是标准的还是有文档记录的?是的,但只有当我改变主程序中的内容时,解才会发生变化。整个模块也是双精度的。我几乎可以肯定这与主程序中双精度表达式的编写方式有关。write
导致一些明显不相关的问题,比如数组越界或使用未初始化的值,或类似的问题,因此它很可能与模块函数有关。尝试打开完整边界检查等等。另一方面,最好将X
上的索引反转为X(3,*)
,以便每个向量的分量在内存中对齐。h(X)
是g(X)
的导数。您能告诉我们预期结果是什么吗。
A zero of the function is: 0.0000000000000000 1.0000000000000000 1.4142135623730951