众所周知,Fortran的更新版本支持数组操作,可以消除许多循环。所以我想知道是否有可能消除以下代码片段中的最后一个剩余循环(以使其成为单行):
subroutine test(n,x,lambda)
integer, intent(in) :: n
real, dimension(:), intent(in) :: x
real, dimension(:), intent(out) :: lambda
real :: eps
integer :: i
do i=1,n
lambda(i) = product(x(i)-x, mask=(abs(x(i)-x) > epsilon(eps)))
enddo
end subroutine
其目的是计算<{p>}中的n
lambda(i)
值
lambda(i) = (x(i)-x(1))*(x(i)-x(2))*...*(x(i)-x(i-1)*(x(i)-x(i+1))*...*(x(i)-x(n))
答案 0 :(得分:2)
好的,试试这个
lambda = product(max(spread(x, dim=1, ncopies=size(x)) - &
spread(x, dim=2, ncopies=size(x)), eps), dim=2)
这是一个单行。它也相当浪费记忆,而且比原来更难以理解。
答案 1 :(得分:1)
是的,你可以缩短它,product
可以使用2D数组:
do i=1,n
mat(:,i) = x(i) - x
enddo
或者,作为一个单行:
forall ( i=1:n ) mat(:,i) = x(i) - x
lambda = product(mat, dim=2, mask=(abs(mat) > epsilon(eps)))
整个计划:
program test
integer, parameter :: n = 3
real, dimension(n) :: x
real, dimension(n) :: lambda
real, dimension(n,n) :: mat
real :: eps = 1.
integer :: i
call random_number( x )
do i=1,n
lambda(i) = product(x(i)-x, mask=(abs(x(i)-x) > epsilon(eps)))
enddo
print *,lambda
forall ( i=1:n ) mat(:,i) = x(i) - x
lambda = product(mat, dim=2, mask=(abs(mat) > epsilon(eps)))
print *,lambda
end program
答案 2 :(得分:1)
您是否在阵列创建中使用隐含的do循环尝试了它?像real, dimension(:), intent(out):: lambda =(/product(x(i)-x, mask=(abs(x(i)-x)>epsilon(eps))), i=1, n/)
之类的东西......我不确定这里的语法,但是这样的东西可能有效。
如果你的x
- 数组可用,你甚至可以在不调用子程序的情况下创建数组并在主程序中执行。
希望它有所帮助。