逐元操作
当使用子例程和函数时,有三种方法可以在数组上执行逐元操作:
elemental
过程;- 显式形状 数组;
- 实现向量的操作,并对不同的维度编写简单的包装器(内部使用
reshape
实现)。
在第一种方法中,使用elemental
关键字创建这样的函数:
real(dp) elemental function nroot(n, x) result(y)
integer, intent(in) :: n
real(dp), intent(in) :: x
y = x**(1._dp / n)
end function nroot
所有参数(in
和out
)必须是标量。例如,您可以对任何(兼容的)形状的数组使用此函数,
print *, nroot(2, 9._dp)
print *, nroot(2, [1._dp, 4._dp, 9._dp, 10._dp])
print *, nroot(2, reshape([1._dp, 4._dp, 9._dp, 10._dp], [2, 2]))
print *, nroot([2, 3, 4, 5], [1._dp, 4._dp, 9._dp, 10._dp])
print *, nroot([2, 3, 4, 5], 4._dp)
输出如下,
3.0000000000000000
1.0000000000000000 2.0000000000000000 3.0000000000000000 3.1622776601683795
1.0000000000000000 2.0000000000000000 3.0000000000000000 3.1622776601683795
1.0000000000000000 1.5874010519681994 1.7320508075688772 1.5848931924611136
2.0000000000000000 1.5874010519681994 1.4142135623730951 1.3195079107728942
如上,通常情况下,n
是一个参数,而x
是一个任意形状的数组。
但是如您所见,只要最终的操作是有意义的(即如果一个参数是数组,
那么其他的参数必须是相同的形状的数组或标量),Fortran并不在乎其形式。
如果不满足,那么将得到一个编译错误。
elemental
关键字通常意味着pure
关键字,因此过程必须是纯的,没有副作用。
您可以添加 impure
关键字来取消这一限制,
impure elemental subroutine write_all(a)
inetger, intent(in) :: a
write(*,"(g0)") a
end subroutine write_all