使用掩码对fortran数组求和

问题描述 投票:0回答:3

我有一个fortran数组a(i,j)。我想用一个j不等于i的蒙版在2(j)维上求和。

即,

a1=0
do j=1,n
if(j.ne.i) then
a1=a1+a(i,j)
endif
enddo

在fortran中使用内在求和函数执行此操作的方式是什么,因为我发现内在函数比显式循环快得多。我想到尝试sum(a(i,:),j.ne.i),但这自然会带来错误。同样,如果可以建议如何仅对abs(a(i(j,j))大于0.01的a(i,:)的某些值进行建议,那将是有帮助的。

arrays fortran gfortran
3个回答
1
投票

您可以轻松避免对角线情况下的任何分支。它应该比创建任何掩码数组和检查掩码快得多。即使分支预测非常有效,分支(条件跳转)的代价也很高。

do j=1,n
  do i = 1,j-1
    a1=a1+a(i,j)
  end do

  do i = j+1,n
    a1=a1+a(i,j)
  end do
end do

如果您需要快速而不短的代码,则应测试这种方法。在我的测试中,速度要快得多。


0
投票

要回答您的最后一个问题,您可以使用WHERE结构来构建遮罩。例如,>

 logical :: y(3,3) = .false.
 real x(3,3)
 x = 1
 x(1,1) = 0.1
 x(2,2) = 0.1
 x(3,3) = 0.1
 print * , sum(x)
 where(abs(x) > 0.25) y = .true.
 print *, sum(x,y)
 end

是否比嵌套do-loop更好,这是有疑问的。


0
投票

[我发现相加整个数组然后减去对角线元素之和可以快2倍。

© www.soinside.com 2019 - 2024. All rights reserved.