Fortran 无法从同一作用域调用函数
我对范围感到困惑。我下载了一个Fortran文件,在一个源文件中有一个主程序、一个子程序和一个函数。主程序不包含子程序,该函数由子程序调用。它工作得很好,但是当我使用“contains”修改主程序以包含这两个子程序时,它给出了编译错误,表示函数没有定义。但是,如果我在同一包含部分中创建一个小函数并从子例程调用,它不会给出错误 这两个函数之间有什么区别?为什么我会出错 我创建了一个具有相同结构的小程序,1 main包含一个子例程和一个func,它没有给出错误 我的环境是ubuntu 14.04,使用gfortran编译器Fortran 无法从同一作用域调用函数,fortran,fortran90,gfortran,Fortran,Fortran90,Gfortran,我对范围感到困惑。我下载了一个Fortran文件,在一个源文件中有一个主程序、一个子程序和一个函数。主程序不包含子程序,该函数由子程序调用。它工作得很好,但是当我使用“contains”修改主程序以包含这两个子程序时,它给出了编译错误,表示函数没有定义。但是,如果我在同一包含部分中创建一个小函数并从子例程调用,它不会给出错误 这两个函数之间有什么区别?为什么我会出错 我创建了一个具有相同结构的小程序,1 main包含一个子例程和一个func,它没有给出错误 我的环境是ubuntu 14.04,使
建设目标:QRbasic 调用:GNU Fortran链接器 gfortran-o“QRbasic”。/main.o
./main.o:在函数
qrbasic'中:
/*/QRbasic/Debug/./main.f95:79:未定义的对
ajnorm"的引用
/home/kenji/workspace/QRbasic/Debug/。/main.f95:104:未定义对“ajnorm”的引用
collect2:错误:ld返回了1个退出状态
make:**[QRbasic]错误1
主程序
!====================================================================
! 求特征值的QR基本方法
! 矩阵A的性质
!====================================================================
隐式无
整数,参数::n=3
双精度,参数::eps=1.0e-07
双精度::a(n,n),e(n)
整数i,j,iter
! 矩阵A
! 数据(a(1,i),i=1,3)/8.0,-2.0,-2.0/
! 数据(a(2,i),i=1,3)/-2.0,4.0,-2.0/
! 数据(a(3,i),i=1,3)/-2.0,-2.0,13.0/
数据(a(1,i),i=1,3)/1.0,2.0,3.0/
数据(a(2,i),i=1,3)/2.0,2.0,-2.0/
数据(a(3,i),i=1,3)/3.0,-2.0,4.0/
! 打印标题和原始矩阵
写(*,200)
i=1,n吗
写(*,201)(a(i,j),j=1,n)
结束
! 打印:猜测向量x(i)
! 写入(*,204)
! 写(*,201)(y(i),i=1,3)
呼叫QRbasic(a、e、eps、n、iter)
! 打印解决方案
写入(*,202)
写(*,201)(e(i),i=1,n)
写入(*,205)iter
200格式('QR基本方法-A(n,n)'的特征值,/&
‘矩阵A’)
201格式(6f12.6)
202格式(/,“特征值”)
205格式(/,'iterations=',i5)
!主程序结束
包含
子程序QRbasic(a、e、eps、n、iter)
!==============================================================
! 计算所有特征值:实对称矩阵a(n,n,)
! a*x=λ*x
! 方法:基本QR法
! Alex G.(2010年1月)
!--------------------------------------------------------------
! 输入。。。
! 矩阵a的(n,n)-系数数组
! n维
! 收敛容限
! 输出。。。
! e(n)-特征值
! iter-达到公差的迭代次数
! 评论。。。
! kmax-允许的最大迭代次数
!==============================================================
隐式无
整数n,iter
双精度a(n,n),e(n),eps
双精度q(n,n),r(n,n),w(n),an,Ajnorm,sum,e0,e1
整数k,i,j,m
整数,参数::kmax=1000
! 初始化
q=0.0
r=0.0
e0=0.0
do k=1,kmax!迭代
! 步骤1:计算Q(n,n)和R(n,n)
! 第1栏
an=Ajnorm(a,n,1)
r(1,1)=an
i=1,n吗
q(i,1)=a(i,1)/an
结束
! 第2列,…,n
do j=2,n
w=0.0
dom=1,j-1
! 乘积q^T*a结果=标量
总和=0.0
i=1,n吗
总和=总和+q(i,m)*a(i,j)
结束
r(m,j)=和
! 乘积(q^T*a)*q结果=向量w(n)
i=1,n吗
w(i)=w(i)+和*q(i,m)
结束
结束
! 新a'(j)
i=1,n吗
a(i,j)=a(i,j)-w(i)
结束
! 评估a'(j)的标准值
an=Ajnorm(a,n,j)
r(j,j)=an
! 向量q(j)
i=1,n吗
q(i,j)=a(i,j)/an
结束
结束
! 步骤2:计算A=R(n,n)*Q(n,n)
a=matmul(r,q)
! E值和平均特征值
总和=0.0
i=1,n吗
e(i)=a(i,i)
总和=总和+e(i)*e(i)
结束
e1=sqrt(总和)
! 在这里打印特征值
! 写(*,201)(e(i),i=1,n)
!201格式(6f12.6)
! 检查收敛性
如果(abs(e1-e0)
原始程序不包含这两个程序。这是我收到的错误版本。您的主程序包含函数类型的声明
Ajnorm()
。因此,当编译器发现该名称用作函数名时,它会将其解释为外部函数。这在程序的原始形式中是非常正确的,函数被定义为一个独立的单元,但是对于内部(包含的)函数来说是错误的。一旦我删除了不需要的声明,您的程序就可以为我干净地编译了
Program Main
!====================================================================
! QR basic method to find the eigenvalues
! of matrix A
!====================================================================
implicit none
integer, parameter :: n=3
double precision, parameter:: eps=1.0e-07
double precision :: a(n,n), e(n)
integer i, j, iter
! matrix A
! data (a(1,i), i=1,3) / 8.0, -2.0, -2.0 /
! data (a(2,i), i=1,3) / -2.0, 4.0, -2.0 /
! data (a(3,i), i=1,3) / -2.0, -2.0, 13.0 /
data (a(1,i), i=1,3) / 1.0, 2.0, 3.0 /
data (a(2,i), i=1,3) / 2.0, 2.0, -2.0 /
data (a(3,i), i=1,3) / 3.0, -2.0, 4.0 /
! print a header and the original matrix
write (*,200)
do i=1,n
write (*,201) (a(i,j),j=1,n)
end do
! print: guess vector x(i)
! write (*,204)
! write (*,201) (y(i),i=1,3)
call QRbasic(a,e,eps,n,iter)
! print solutions
write (*,202)
write (*,201) (e(i),i=1,n)
write (*,205) iter
200 format (' QR basic method - eigenvalues for A(n,n)',/, &
' Matrix A')
201 format (6f12.6)
202 format (/,' The eigenvalues')
205 format (/,' iterations = ',i5)
!end program main
contains
subroutine QRbasic(a,e,eps,n,iter)
!==============================================================
! Compute all eigenvalues: real symmetric matrix a(n,n,)
! a*x = lambda*x
! method: the basic QR method
! Alex G. (January 2010)
!--------------------------------------------------------------
! input ...
! a(n,n) - array of coefficients for matrix A
! n - dimension
! eps - convergence tolerance
! output ...
! e(n) - eigenvalues
! iter - number of iterations to achieve the tolerance
! comments ...
! kmax - max number of allowed iterations
!==============================================================
implicit none
integer n, iter
double precision a(n,n), e(n), eps
double precision q(n,n), r(n,n), w(n), an, Ajnorm, sum, e0,e1
integer k, i, j, m
integer, parameter::kmax=1000
! initialization
q = 0.0
r = 0.0
e0 = 0.0
do k=1,kmax ! iterations
! step 1: compute Q(n,n) and R(n,n)
! column 1
an = Ajnorm(a,n,1)
r(1,1) = an
do i=1,n
q(i,1) = a(i,1)/an
end do
! columns 2,...,n
do j=2,n
w = 0.0
do m=1,j-1
! product q^T*a result = scalar
sum = 0.0
do i=1,n
sum = sum + q(i,m)*a(i,j)
end do
r(m,j) = sum
! product (q^T*a)*q result = vector w(n)
do i=1,n
w(i) = w(i) + sum*q(i,m)
end do
end do
! new a'(j)
do i =1,n
a(i,j) = a(i,j) - w(i)
end do
! evaluate the norm for a'(j)
an = Ajnorm(a,n,j)
r(j,j) = an
! vector q(j)
do i=1,n
q(i,j) = a(i,j)/an
end do
end do
! step 2: compute A=R(n,n)*Q(n,n)
a = matmul(r,q)
! egenvalues and the average eigenvale
sum = 0.0
do i=1,n
e(i) = a(i,i)
sum = sum+e(i)*e(i)
end do
e1 = sqrt(sum)
! print here eigenvalues
! write (*,201) (e(i),i=1,n)
!201 format (6f12.6)
! check for convergence
if (abs(e1-e0) < eps) exit
! prepare for the next iteration
e0 = e1
end do
iter = k
if(k == kmax) write (*,*)'The eigenvlue failed to converge'
print *, func1()
end subroutine QRbasic
function Ajnorm(a,n,j)
implicit none
integer n, j, i
double precision a(n,n), Ajnorm
double precision sum
sum = 0.0
do i=1,n
sum = sum + a(i,j)*a(i,j)
end do
Ajnorm = sqrt(sum)
end function Ajnorm
integer function func1()
print *, "dummy"
func1=1
end function
end program