我有两个列表,我需要将元素中的元素相互匹配,并将这些元素输出到新的矩阵(输出)中。在Fortran中最快的方法是什么?到目前为止蛮力:
do i = 1,Nlistone
do j = 1,Nlisttwo
if A(i).eq.B(j) then
output(i) = B(j)
end if
end do
end do
openmp版本:
!$OMP PARALLEL PRIVATE(i,j)
do i = 1,NA
do j = 1,NB
if A(i).eq.B(j) then
filtered(i) = A(j)
end if
end do
end do
!$OMP END PARALLEL DO
肯定有更好的方法可以做到这一点,并且排序不是一个选项抱歉(+矢量元素没有任何特定的顺序)。在python中有一个类似于mask
的布尔参数吗?
答案 0 :(得分:2)
使用像这样的内在ANY
函数可能会更快
do i = 1,Nlistone
if (any(B==A(i))) output(i) = A(i)
end do
但我不打赌这种改进的性能,我会测试两个版本。您应该能够安全地将其包装在!$OMP PARALLEL DO
构造中,因为output
的每个元素仅由一个线程写入。
答案 1 :(得分:0)
您还可以在forall
或(更新)do concurrent
构造中包含条件测试,这两种构造都使用相同的语法:
do concurrent(i = 1:Nlistone, any(a(i) == b))
output(i) = a(i)
end do
这可能比您的代码列表更快,具体取决于性质A
和B
。但它仍然具有相同的O(n ^ 2)时间复杂度,而排序可以是O(n * log(n))。如果Nlistone /= Nlisttwo
,您可以通过循环较短的数组并将其元素与较长的数组匹配来获得等于这些大小的比率的因子。