用掩码对 Fortran 数组求和
Summing a fortran array with mask
我有一个 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),但这自然会出错。此外,如果有人可以建议如何仅使用 a(i,:) 的某些值,其中 abs(a(i,j)) 大于 0.01,这将很有帮助。
要回答您的最后一个问题,您可以使用 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 循环更好是值得怀疑的。
您可以轻松避免非对角线情况的任何分支。它应该比创建任何掩码数组并检查掩码要快得多。即使分支预测非常有效,分支(条件跳转)也很昂贵。
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
如果你需要你的代码既快又不短,你应该测试这种方法。在我的测试中它要快得多。
我发现对整个数组求和然后减去对角线元素的总和可以快 2 倍。
a1 = 0
do i = 1, n
a1 = a1 + a(i,i)
end do
a1 = sum(a) - a1
end do
我有一个 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),但这自然会出错。此外,如果有人可以建议如何仅使用 a(i,:) 的某些值,其中 abs(a(i,j)) 大于 0.01,这将很有帮助。
要回答您的最后一个问题,您可以使用 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 循环更好是值得怀疑的。
您可以轻松避免非对角线情况的任何分支。它应该比创建任何掩码数组并检查掩码要快得多。即使分支预测非常有效,分支(条件跳转)也很昂贵。
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
如果你需要你的代码既快又不短,你应该测试这种方法。在我的测试中它要快得多。
我发现对整个数组求和然后减去对角线元素的总和可以快 2 倍。
a1 = 0
do i = 1, n
a1 = a1 + a(i,i)
end do
a1 = sum(a) - a1
end do