首页 文章

Fortran代码仅为某些文件提供输出

提问于
浏览
0

我有4个.mtx文件,我正在读取值 . 其中两个在没有问题的情况下读取时运行良好,并将正确的输出生成到.DAT文件中 . 但是,最后2个是非常大的文件;看起来代码正确地从文件中读取并运行,但是从这些中读取时没有输出也没有错误...甚至代码计时器都没有打印时间 . 任何帮助深表感谢!这是代码:

program proj2matrixC40

implicit none
integer,parameter::dp=selected_real_kind(15,307)

! Set Global Variables

real(kind=dp), allocatable::Ax(:,:),A(:,:),Iglobal(:,:)
integer::At(1,3)
integer::nnz,w,n,k,ii,ff,kk
real(kind=dp)::t1,t2
call cpu_time(t1)
open(unit=78,file="e40r5000.mtx",status='old')
read(78,*) At
close(unit=78)
nnz = At(1,3)
n = At(1,1)
k = 40
kk = 35
allocate(Ax(nnz+1,3),A(nnz,3),Iglobal(k,k))
open(unit=61,file="e40r5000.mtx",status='old')
do w=1,nnz+1
   read(61,*) Ax(w,:)
end do
open (unit = 53, file = "proj2matrixC40points.dat")
do ff=1,k
   do ii=1,k
       Iglobal(ii,ff) = (ii/ff)*(ff/ii)
   end do
end do
A(1:nnz,:) = Ax(2:nnz+1,:)
call Arno(A)
call cpu_time(t2)
print '("Time elapsed = ",f10.8," seconds")', (t2 - t1)

contains

subroutine Arno(a)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp),dimension(k,k)::H
real(kind=dp),dimension(k,k+1)::u,q,qconj
real(kind=dp),dimension(k,1)::x0
integer::j,f
call random_number(x0)
q(:,1) = x0(:,1)/norm2(x0(:,1))
do f=1,k
   call spmat(a,q(:,f),u(:,f))
   do j=1,f
      qconj(j,:) = (q(:,j))
      H(j,f) = dot_product(qconj(j,:),u(:,f))
      u(:,f) = u(:,f) - H(j,f)*q(:,j)
   end do
   if (f.lt.k) then
      H(f+1,f) = norm2(u(:,f))
      if (H(f+1,f)==0) then
         print *, "Matrix is reducible"
         stop
      end if
      q(:,f+1) = u(:,f)/H(f+1,f)
   end if
   if (f==k) then
      call qrit(H)
   end if
end do
end subroutine

! QR Iteration with Shifts Subroutine

subroutine qrit(a)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp)::sigmak
real(kind=dp),dimension(kk,k)::dia
real(kind=dp),dimension(k,k)::Qfinal,Rfinal,HH
real(kind=dp),dimension(k,k,kk)::H0,needQR
integer::v,z
HH = a
   H0(:,:,1) = HH
   do v=1,kk
      sigmak = H0(k,k,v)
      if (v-1==0) then
          needQR(:,:,v) = HH - sigmak*Iglobal
      else
          needQR(:,:,v) = H0(:,:,v-1) - sigmak*Iglobal
      end if
      call givens2(needQR(:,:,v),Rfinal,Qfinal)
      H0(:,:,v) = matmul(Rfinal,Qfinal) + sigmak*Iglobal
      do z = 1,k
         dia(v,z) = H0(z,z,v)
         write(53,*) v," ", dia(v,z) ! Write values to .DAT file
      end do
   end do
end subroutine

! Sparse Matrix Vector Multiplication Subroutine

subroutine spmat(a,b,c)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp), intent(in), dimension(k,1)::b
real(kind=dp), intent(out), dimension(k,1)::c
integer::m,rowi,columni
real(kind=dp), dimension(k,1)::x,y
x = b
y(:,1) = 0
do m = 1,nnz
   rowi = a(m,1)
   columni = a(m,2)
   y(rowi,1) = y(rowi,1) + a(m,3)*x(columni,1)
end do
c(:,1) = y(:,1)
end subroutine

! QR Factorization Givens Rotations Subroutine

subroutine givens2(a,Rfinal,Qfinal)
real(kind=dp), intent(in)::a(:,:)
real(kind=dp), dimension(k,k,(k*k))::G,QQ
real(kind=dp), dimension(k,k), intent(out)::Rfinal,Qfinal
real(kind=dp), dimension(k,k)::I2,y,aa
real(kind=dp), dimension(1,k)::ek1,ek2
real(kind=dp)::c,s
integer::kt,m,nn,j,i,l,p
m = size(a,1)
nn = size(a,2)
aa = a
i = 1
do kt=1,nn-1
   do j=m,kt+1,-1
      if (aa(j,kt).eq.0) then
          continue
      else
         ek1(1,:) = 0
         ek2(1,:) = 0
         do p=1,m
            do l=1,m
               I2(l,p) = (l/p)*(p/l)
            end do
         end do
         c = aa(kt,kt)/sqrt(aa(kt,kt)**2 + aa(j,kt)**2)
         s = aa(j,kt)/sqrt(aa(kt,kt)**2 + aa(j,kt)**2)
         ek1(1,kt) = c
         ek1(1,j) = s
         ek2(1,kt) = -s
         ek2(1,j) = c
         I2(kt,:) = ek1(1,:)
         I2(j,:) = ek2(1,:)    
         G(:,:,i) = I2
         if (i.eq.1) then
            QQ(:,:,i) = G(:,:,i)
         else 
            QQ(:,:,i) = matmul(G(:,:,i),QQ(:,:,i-1))
         end if
         y = matmul(G(:,:,i),aa)
         aa = y
         if (kt.eq.nn-1) then
            if (j.eq.kt+1) then
               Qfinal = transpose(QQ(:,:,i))
               Rfinal = aa
            end if
         end if
         i = i + 1
      end if
   end do
end do
end subroutine

end program proj2matrixC40

几个笔记 . 我把星号放在一边(对于这个问题) call mat_print('H',H) 可以't be deleted otherwise I get the wrong answers (this is strange...thoughts?). Also so your computer won'冻结打开大文件,它们的名字是'e40r5000.mtx'和's3dkt3m2.mtx'(这些是我遇到的两个问题) . 我正在使用gfortran版本8.1.0

这是文件的链接

https://1drv.ms/f/s!AjG0dE43DVddaJfY62ABE8Yq3CI

1 回答

  • 3

    当你需要添加对子程序的调用时,为了让事情正常工作,这个子程序实际上不应该改变任何东西,你可能会有内存损坏 . 当您访问其边界之外的数组时,这种情况最常发生 .

    我用一些运行时检查编译了它:

    gfortran -o p2m -g -O0 -fbacktrace -fcheck=all -Wall proj2mat.f90
    

    它已经给了我一些问题:

    • 如果您信任您的数据,那么问题就太严重了 .

    • 在第46行中,数组长度不匹配( x0(:, 1) 长度为40, q(:,1) 为41)

    • 同样在第108行( x=bx 非常大,但 b 只有41长 .

    我现在已经停止了,但我恳请你仔细检查并清理它 . 使用上面的编译器选项可以让您知道何时何地存在数组绑定违规 .

相关问题