2012-01-13 83 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解决方案,或者添加一个额外的排序条目列表,以对给定值执行二进制搜索,如果需要的话。 这两种方法在我的经验中都很好。