在Fortran中是否有稀疏数组、或等效的lists的实现。
在大数据集的计算阶段,我们把一个n=10000大小的数组传递给一个子程序来做一些事情。例如,在其中查找相似的元素,并按顺序列出每个项目的元素。也就是说,对于第一项,通过列表(数组)查找所有类似的项目,并存储结果标记。生成的结果可能与每个元素的列表一样大。注意,对于标准,我们使用的相似性是不对称的,这意味着我们需要完全迭代所有项目的计算。因此,根据所使用的标准,所产生的长度可能各不相同。因此,存储所有结果需要稀疏数组/列表,这在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。正如您所看到的,对于较大的尺寸来说,这是一个非常低效的想法。有解决办法吗?
发布于 2012-01-13 15:34:34
没有链接列表的解决方案。
这里,假设向量"r“包含双精度值。
请注意,此解决方案不使用指针,只使用可分配的数组,因此可以避免内存泄漏。重新分配的数量是有限的(log2(列表%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结果:
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 发布于 2012-01-13 16:54:50
您可能对通过ISO绑定使用朱迪阵列感兴趣.它为您提供了动态稀疏数组的功能。否则,我会推荐Francois解决方案,如果需要的话,可以添加一个额外的排序条目列表来执行对给定值的二进制搜索。在我的经验中,这两种方法运作得都很好。
https://stackoverflow.com/questions/8849748
复制相似问题