2013-07-01 60 views
0

我正在編寫一個程序。該程序解決矩陣。這些矩陣與用戶在命令行參數中指定的一樣大。我希望程序能夠解決非常大的矩陣問題,所以當我完成包括umfpack,lapack,suitespares,arpack在內的所有線性代數時,我試圖通過刪除未使用的數組來釋放內存空間。我找到了3個完全未使用的數組,僅用於解決其他與解決矩陣有關的問題。Fortran陣列分配刪除現在不正確解決方案

當我從聲明中刪除變量和分配時,程序開始行爲不同。矩陣解決方案現在是錯誤的。我已經回到我的備份文件,它仍然正常工作。我確定刪除聲明並分配未使用的數組會阻止我的程序找到正確的解決方案。

我一直在玩這個問題幾天了。我真的無法想象如何刪除未使用的數組正在改變我的程序的執行。任何幫助表示讚賞。

program HHSolver 
    use MathOperations 
    integer :: O, NEV, i, j, k, a, col, row 
    integer :: coeff, p, b, NTerms, NextCoeff 
    integer :: m, n, symbolic, numeric 
    integer :: TermIndex, ido, NCV,LDV, LWorkL, info2,ierr 
    double precision :: x, y, sigmai, sigmar 
    Character(128) :: String, term, factor 
    character(1) :: bmat 
    character(2) :: which 
    double precision, dimension(:, :), allocatable :: polynomial  !this stores the polynomial boundary equation  
    double precision, dimension(:, :), allocatable :: lap   !this stores the polynomial boundary equation  
    double precision, dimension(:, :), allocatable :: temp   !this stores the polynomial boundary equation  
    double precision, dimension(:, :), allocatable :: R   !this stores the polynomial boundary equation   
    double precision, dimension(:, :), allocatable :: vec   !this stores the polynomial boundary equation   
    double precision, dimension(:, :), allocatable :: lwork   !this stores the polynomial boundary equation   
    double precision, dimension(:), allocatable :: alphar, beta 
    double precision, dimension(:), allocatable :: alphai, work 
    double precision, dimension(1, 1) :: dummy 
    double precision, dimension(:), allocatable :: RESID   
    double precision, dimension(:, :), allocatable :: V, z 
    double precision, dimension(:), allocatable :: workd, workl 
    double precision, dimension(:), allocatable :: workev 
    double precision, dimension(:), allocatable :: Ax, DI, DR 
    integer, dimension(:), allocatable :: Ap, Ai 
    integer, dimension(11) :: IPARAM 
    integer, dimension(14) :: IPNTR  
    integer, dimension(1) :: h 
    double precision :: control(20), info(90), tol 
    logical, dimension(:), allocatable :: select 
    logical :: rvec(1) 
    double precision, dimension(:), allocatable :: tempvec 

    external daxpy, dnrm2, dpttrf, dpttrs, dlapy2 
    intrinsic abs 

    call get_command_argument(1, String) 
    read(String, '(i10)') O 
    call get_command_argument(2, String) 
    read(String, '(i10)') NEV 
    call get_command_argument(3, String) 

    write(*, *) 'try to allocate enough memory for full matrices' 

    !this is wh the matrix is created 
    allocate(lap((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation    
    allocate(temp((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation    
    allocate(R((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation   
    allocate(alphar((O+1)**2)) !this stores the polynomial boundary equation    
    allocate(alphai((O+1)**2)) !this stores the polynomial boundary equation    
    allocate(beta((O+1)**2)) !this stores the polynomial boundary equation    
    allocate(vec((O + 1)**2, (O + 1)**2)) !this stores the polynomial boundary equation    
    allocate(work(8*((O+1)**2))) !this stores the polynomial boundary equation    
    allocate(lwork(2*((O+1)**2), 2*((O+1)**2))) !this stores the polynomial boundary equation   
    allocate(RESID((O+1)**2)) !this stores the initial and last eigenvector 
    allocate(V((O+1)**2,20+NEV)) !this stores the eigenvectors 
    allocate(workd(3*((O+1)**2))) !this stores the eigenvectors    
    allocate(workl(30*(20+NEV)**2 + 60*(20+NEV))) !this stores the eigenvectors    
    allocate(workev(3*(20+NEV))) !this stores the eigenvectors    
    allocate(tempvec((O+1)**2)) !this stores the eigenvectors    
    allocate(DI(NEV+1)) !this stores the eigenvectors    
    allocate(DR(NEV+1)) !this stores the eigenvectors    
    allocate(select(20+NEV)) !this stores the eigenvectors    
    allocate(z((O+1)**2,1+NEV)) !this stores the eigenvectors 

    write(*, *) 'memory for matrices allocated'  

      !create the matrix to be solved 
      !solver the matrix 

    write(*, '(25F20.5)') DI !these are the real and imaginary part of solution 
    write(*, '(25F20.5)') DR 
    end program 

當我嘗試刪除alphai,alphar,lwork時,一切都崩潰了。他們甚至沒有被使用。

+0

請給我們提供一些開始的代碼,找出問題的位置會更容易 – Jk1

+0

它沒有讓我。它不喜歡格式。我不改變1000行代碼的格式。 – user2540350

+0

如果將第3行的隱式none語句放在第三行,會發生什麼? – milancurcic

回答

2

您描述:未使用的數組,如果您刪除,您的程序會給出不正確的答案。一種可能性是使用的其他一些數組被聲明太小。在刪除使用的數組之後,這些數組在內存中重疊並且由於重疊而被錯誤地更改。之前,當你擁有額外的數組時,幸運的是,他們爲數組或陣列提供了額外的存儲空間。

您可以通過初始化未使用的數組,然後在程序結束時查看是否有任何數值發生變化來測試。

您可以查看所有陣列的尺寸。

讓模塊中的所有過程(子例程和函數)使編譯器知道它們的接口將允許編譯器檢查它們被調用的實際參數與它們的僞參數之間的一致性。 external聲明表明您沒有使用Fortran> = 90提供的幫助。

使用編譯器的所有錯誤和警告選項(包括運行時下標檢查)可能會發現問題。如果數組傳遞給子程序的方式會丟失有關其維數的信息,這可能無濟於事。使用gfortran,請嘗試:-fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -fbacktrace

+0

這是我的推測性解釋。未使用的數組實際上正在創建一個緩衝區,其中一個函數超出了邊界數組的邊界。我原以爲這會導致運行時錯誤。似乎很奇怪,我可以分配(a(10)),分配(b(10)),並將某些內容存儲在(11)= b(1)中,而不會發生任何錯誤。 – user2540350

+0

默認不檢查下標使用的正確性。該檢查需要具有運行時成本的額外指令。使用gfortran,你可以用'-fcheck = all'(包括'-fcheck = bounds')來添加這個檢查。它可能會或可能不會找到下標錯誤,具體取決於將數組傳遞給子例程的方式。 –