2012-01-13 88 views
2

是否有的Fortran稀疏矩陣或同等名單的任何實現。的Fortran:稀疏數組或列表

在我們通過大型數據集的計算階段說的n=10000大小的一個子程序數組做一些東西在他們身上。例如,在其中找到類似的元素並按順序列出每個項目。也就是說,對於項目1,通過列表(數組)找到所有相似的項目並存儲結果標記。結果可能會很大,因爲每個元素的列表都很大。請注意,關於標準,我們使用的相似性不是對稱的,這意味着我們需要對所有項目的評估進行完全迭代。因此,根據所使用的標準,所得結果可能各不相同。因此,存儲所有結果,需要稀疏矩陣/列表,它可在Python爲:


R = an array    # an array 
L = []     # list initialization 
for e in R:    # iteration on all elements of R 
    r = similars(e,R,criteria) # r is array & different in size for each element 
    L.append(r)   # store the ranks in list L 
 

爲了簡單起見,現在我們用平常陣列使用Fortran其中用於n<=1000n*n。正如你所看到的,對於更大尺寸來說這是一個非常低效的想法。 任何解決方案?

+1

[鏈接列表](http://fortranwiki.org/fortran/show/Linked+list)在這裏可能會有用。 – Chris 2012-01-13 11:28:35

+0

fortran 77,90,2k3? – Anycorn 2012-01-13 11:30:32

+0

@Anycorn F90。和GCC4.5 – Developer 2012-01-13 11:37:28

回答

4

沒有鏈接列表的解決方案。

這裏假設矢量「r」包含雙精度值。

注意,這個解決方案使用沒有指針,只分配數組,其值得以避免內存泄漏。重新分配的數量是有限的(log2(list%n)),但是可以接受分配列表%結果的大小比真正需要的大(最多兩次)。

最後,矢量「R」在列表中被複制(這是不是在Python版本的情況下)。

module extendable_list 

implicit none 

type result_type 
    double precision,allocatable :: vector(:) 
end type 

type list_type 
    integer :: n 
    type(result_type),allocatable :: result(:) 
end type 

contains 

subroutine append(list,r) 
    type(list_type),intent(inout) :: list 
    double precision,intent(in) :: r(:) 
    type(result_type),allocatable :: temporary(:) 
    integer :: i 
    if(.not.allocated(list%result)) then 
    allocate(list%result(10)) 
    list%n=0 
    else if(list%n >= size(list%result)) then 
    allocate(temporary(2*list%n)) 
    do i=1,list%n 
     call move_alloc(list%result(i)%vector,temporary(i)%vector) 
    enddo 
    call move_alloc(temporary,list%result) 
    endif 
    list%n=list%n+1 
    allocate(list%result(list%n)%vector(size(r))) 
    list%result(list%n)%vector=r 
end subroutine 

end module 

program main 
    use extendable_list 
    implicit none 
    type(list_type) :: list 
    integer :: i 
    do i=1,10 
    call append(list,(/1.d0,3.d0/)) 
    call append(list,(/7.d0,-9.d0,45.d0/)) 
    enddo 
    do i=1,list%n 
    write(*,*) list%result(i)%vector 
    enddo 
end program 

結果:

[email protected]:~/test$ ifort t65.f90 
[email protected]:~/test$ ./a.out 
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
    1.00000000000000  3.00000000000000  
    7.00000000000000  -9.00000000000000  45.0000000000000  
+0

感謝您的回答,代碼和解釋。 – Developer 2012-01-14 07:40:11

+0

謝謝,這真的很有幫助。是否有可能具有任意類型作爲result_type?我喜歡將第一個列表項存儲爲REAL * 8,接下來是COMPLEX * 16,DIMENSION(:, :)等...... – DaPhil 2014-05-24 06:31:26

0

您可能會感興趣的通過ISO-C-綁定使用Judy-Arrays。它爲您提供了動態稀疏數組的功能。否則,我會推薦Francois Jacq解決方案,或者添加一個額外的排序條目列表,以對給定值執行二進制搜索,如果需要的話。 這兩種方法在我的經驗中都很好。