逐元操作
当使用子例程和函数时,有三种方法可以在数组上执行逐元操作:
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