我有一个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,:)的某些值进行建议,那将是有帮助的。
您可以轻松避免对角线情况下的任何分支。它应该比创建任何掩码数组和检查掩码快得多。即使分支预测非常有效,分支(条件跳转)的代价也很高。
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
如果您需要快速而不短的代码,则应测试这种方法。在我的测试中,速度要快得多。
要回答您的最后一个问题,您可以使用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更好,这是有疑问的。
[我发现相加整个数组然后减去对角线元素之和可以快2倍。