Fortran:稀疏数组或列表
Posted
技术标签:
【中文标题】Fortran:稀疏数组或列表【英文标题】:Fortran: sparse arrays or lists 【发布时间】:2012-02-09 14:35:23 【问题描述】:Fortran 中是否有任何稀疏数组或等效列表的实现。
在计算大型数据集的阶段,我们将一个大小为n=10000
的数组传递给子程序以对其进行处理。例如,在其中找到相似的元素并为每个项目按顺序列出它们。即对于item one,通过列表(数组)查找所有相似的item,并存储结果标记。结果可能像每个元素的列表一样大。请注意,关于标准,我们使用的相似性不是对称的,这意味着我们需要完全迭代所有项目的评估。因此,根据所使用的标准,每个结果的长度可能不同。因此,存储所有结果需要稀疏数组/列表,这在 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<=1000
是 n*n
。如您所见,对于较大的尺寸,这是一个非常低效的想法。
有什么解决办法吗?
【问题讨论】:
linked list 在这里可能有用。 @Anycorn F90。和 GCC4.5 @Chris 感谢您的链接。看起来很有希望。 Fortran 链表最近出现在 Stack Overflow 上 ***.com/questions/8648779/… 【参考方案1】:没有链表的解决方案。
这里假设向量“r”包含双精度值。
请注意,此解决方案不使用指针,只使用可分配数组,这样可以保证避免内存泄漏。重新分配的数量是有限的(log2(list%n)),但是可以接受分配 list%result 的大小大于实际需要的大小(最多两次)。
最后,向量“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
结果:
coul@b10p5001:~/test$ ifort t65.f90
coul@b10p5001:~/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
【讨论】:
谢谢,这真的很有帮助。是否有可能将任意类型作为 result_type?我喜欢将 REAL*8 存储为第一个列表项,接下来是 COMPLEX*16,DIMENSION(:,:) 等等...【参考方案2】:您可能有兴趣通过 ISO-C-Binding 使用 Judy-Arrays。它为您提供动态稀疏数组的功能。否则,如果您需要,我会推荐 Francois Jacq 解决方案,可能会添加额外的排序条目列表,以对给定值执行二进制搜索。 根据我的经验,这两种方法都非常有效。
【讨论】:
以上是关于Fortran:稀疏数组或列表的主要内容,如果未能解决你的问题,请参考以下文章