Fortran 无法从同一作用域调用函数

Fortran 无法从同一作用域调用函数,fortran,fortran90,gfortran,Fortran,Fortran90,Gfortran,我对范围感到困惑。我下载了一个Fortran文件,在一个源文件中有一个主程序、一个子程序和一个函数。主程序不包含子程序,该函数由子程序调用。它工作得很好,但是当我使用“contains”修改主程序以包含这两个子程序时,它给出了编译错误,表示函数没有定义。但是,如果我在同一包含部分中创建一个小函数并从子例程调用,它不会给出错误 这两个函数之间有什么区别?为什么我会出错 我创建了一个具有相同结构的小程序,1 main包含一个子例程和一个func,它没有给出错误 我的环境是ubuntu 14.04,使

我对范围感到困惑。我下载了一个Fortran文件,在一个源文件中有一个主程序、一个子程序和一个函数。主程序不包含子程序,该函数由子程序调用。它工作得很好,但是当我使用“contains”修改主程序以包含这两个子程序时,它给出了编译错误,表示函数没有定义。但是,如果我在同一包含部分中创建一个小函数并从子例程调用,它不会给出错误

这两个函数之间有什么区别?为什么我会出错

我创建了一个具有相同结构的小程序,1 main包含一个子例程和一个func,它没有给出错误

我的环境是ubuntu 14.04,使用gfortran编译器


建设目标: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