在Fortran中选择给定逻辑向量的数组的子集

Jou*_*ske 3 arrays fortran logical-operators

在Fortran中,是否可以通过使用一些逻辑值向量而不是索引来选择数组的某些部分?例如这样:

iszero(1) = 0
iszero(2) = 1
iszero(3) = 0
sum0 = sum(iszero) !was  sum0 = sum(iszero==0)
!mymatrix is arbitary is 3 times 3 array
mysubmatrix(1:sum0,1:sum0) = mymatrix(iszero==0,iszero==0)
call dtrmv('l','n','u',sum0,mysubmatrix(1:sum0,1:sum0),sum0,x(1:sum0)),1)
Run Code Online (Sandbox Code Playgroud)

如果直接无法做到这一点,是否有一种简单(快速)的方法来找到iszero = 0的索引?

编辑:我改变了示例以呈现更现实的情况,在前一种情况下我只是将一些值更改为100.0d0,其中元素处理可以正常.

edit2:在代码的第四行有一个类型

Hig*_*ark 8

where (mymatrix==0) mymatrix = 100.0d0
Run Code Online (Sandbox Code Playgroud)

将mymatrix中的所有元素设置为0到100.如果你实际上想要做一些比这更复杂的事情,也许设置一个矩阵以得到1和0的'棋盘'你可以尝试类似的东西;

mymatrix(1:m:2,2:n:2) = 100d0
Run Code Online (Sandbox Code Playgroud)

其中m,n是mymatrix中的行数和列数.我没有测试过后一个片段,它只是建议有时考虑数组下标三元组.

编辑

如果你真的想在where语句中使用一个矩阵(或向量)作为掩码而在赋值部分中使用另一个矩阵(或向量),例如:

where(index_matrix==0) mymatrix = 100d0
Run Code Online (Sandbox Code Playgroud)

那么你(我认为)确保它index_matrix具有相同的大小mymatrix.在您的情况下,您最终可能会得到如下声明:

where(reshape([0,1],[3,3],pad=[0,1])==0) mymatrix = 100d0
Run Code Online (Sandbox Code Playgroud)

再次,我没有测试过这个,我不认为我的填充重塑非常正确,但你可以弄清楚细节.

进一步编辑

我现在发现很难回答这个问题.该声明

sum0 = sum(iszero==0)
Run Code Online (Sandbox Code Playgroud)

将值1赋值给sum,所以声明

mysubmatrix(1:sum0,1:sum0) = mymatrix(iszero==0,iszero==0)
Run Code Online (Sandbox Code Playgroud)

在运行时,将是这样的:

mysubmatrix(1:1,1:1) = mymatrix(iszero==0,iszero==0)
Run Code Online (Sandbox Code Playgroud)

而且我不确定rhs和lhs是否适合Fortran.这会编译吗?如果是,它是否正确执行(使用数组边界检查)?

你想创造submatrix哪个只包含0个元素mymatrix?如果是这样,那么对于一般情况,我认为你将会遇到困难.除非您可以根据索引或下标矢量或下标三元组来定义要选择的元素的位置,否则我不会看到您可以在rhs上的数组上的lhs上创建数组.

如果0的位置是任意的,那么你可以通过将原始数组展平为rank-1并创建它的rank-1子阵列来做你想要的,但是你会失去2D位置和它们的1D对应物之间的对应关系.

最后

不要忘记,在Fortran 2003中,您可以使用指针来引用由向量或三元组下标定义的子矩阵,例如

pointer_to_array => target_array(1:10:2,2:10:2)
Run Code Online (Sandbox Code Playgroud)

然后转pointer_to_array过来.


Eve*_*You 6

对于秩-1阵列,可以使用内部函数通过局部阵列掩码获取阵列子集PACK.例如(在Fortran 2003中)

INTEGER :: X(5) = [1,2,0,3,0]
INTEGER, ALLOCATABLE :: XX(:)
XX = PACK(X,X/=0)
Run Code Online (Sandbox Code Playgroud)

将从X中挑出非零元素,并存储到XX(返回XX = [1,2,3]).

  • @ IRO-bot在2003年的Fortran中,XX将被自动分配,因此没有段错误. (2认同)