Fortran 有可能消除do循环吗
我们知道,Fortran的最新版本支持数组操作,这可以消除许多循环。所以我想知道是否有可能在下面的代码片段中消除最后一个剩余的循环(从而使其成为一个单行程序): 其目的是计算Fortran 有可能消除do循环吗,fortran,fortran90,Fortran,Fortran90,我们知道,Fortran的最新版本支持数组操作,这可以消除许多循环。所以我想知道是否有可能在下面的代码片段中消除最后一个剩余的循环(从而使其成为一个单行程序): 其目的是计算nlambda(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)) 是的,您可以缩短此长度,产品可以使用二维阵列: 您首先需要建立一个差异矩阵: 或者,作为一个班轮: forall ( i=
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))
是的,您可以缩短此长度,
产品
可以使用二维阵列:
forall ( i=1:n ) mat(:,i) = x(i) - x
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
是的,您可以缩短此长度,
产品
可以使用二维阵列:
forall ( i=1:n ) mat(:,i) = x(i) - x
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
您是否在数组创建中使用了隐含的do循环进行了尝试?类似于
real,dimension(:),intent(out)::lambda=(/product(x(i)-x,mask=(abs(x(i)-x)>epsilon(eps))),i=1,n/)
。。。我不确定这里的语法,但类似的东西可能会起作用。
如果x
-数组可用,您甚至可以在不调用子例程的情况下创建数组,并在主程序中执行该操作
希望有帮助。您是否在数组创建过程中尝试了隐含do循环?类似于
real,dimension(:),intent(out)::lambda=(/product(x(i)-x,mask=(abs(x(i)-x)>epsilon(eps))),i=1,n/)
。。。我不确定这里的语法,但类似的东西可能会起作用。
如果x
-数组可用,您甚至可以在不调用子例程的情况下创建数组,并在主程序中执行该操作
希望有帮助。好的,试试这个
lambda = product(max(spread(x, dim=1, ncopies=size(x)) - &
spread(x, dim=2, ncopies=size(x)), eps), dim=2)
那是一条单行线。它也相当浪费内存,而且比原稿更难理解。好的,试试这个
lambda = product(max(spread(x, dim=1, ncopies=size(x)) - &
spread(x, dim=2, ncopies=size(x)), eps), dim=2)
那是一条单行线。它也相当浪费记忆,而且比原稿更难理解。它不是一行,也不是一行。很好;-)我也走上了
spread
的轨道,但是与max
的组合取代了掩码。。。美丽的!这个答案也是错误的,因为它将在乘法中包含等于eps
的项,而OP的原始乘法中根本没有任何项。但是,优雅总是胜过正确!!不错;-)我也走上了spread
的轨道,但是与max
的组合取代了掩码。。。美丽的!这个答案也是错误的,因为它将在乘法中包含等于eps
的项,而OP的原始乘法中根本没有任何项。但是,优雅总是胜过正确!!循环在Matlab和Python等解释语言中通常速度较慢,但Fortran编译器优化循环已有50多年的历史。如果循环是实现算法最直接的方式,那么就使用它。在Matlab和Python等解释语言中,循环通常速度较慢,但Fortran编译器优化循环已经有50多年了。如果循环是实现算法最直接的方法,那么就使用它。这有效吗?我自己没试过。它被更多地认为是这方面的一个提示。它在语法级别上不起作用:它在隐含do周围缺少()
,并且它试图初始化一个伪参数(初始化中不允许使用某些东西)。但是这些都是可以修复的。这有用吗?我自己没试过。它被更多地认为是这方面的一个提示。它在语法级别上不起作用:它在隐含do周围缺少()
,并且它试图初始化一个伪参数(初始化中不允许使用某些东西)。不过,这些问题是可以解决的。