Fortran90中的数组段算法
Array section arithmetic in Fortran90
这段代码片段:
real*8 a(20,5,2)
real*8 b(5)
real*8 c(20,5,2)
! define a vals ....
! define b vals ....
c(1:20, :, 1:2) = a(1:20,:,1:2)*b
无法编译,因为 b
与 a
或 c
的形状不同。当然,我希望 b
的五个值与 a
和 c
的中间索引的 5 个值相匹配,但 Fortran 编译器不理解这一点。有什么办法可以告诉它我在这里想要什么吗?我知道我可以在更大的数组中复制 b
以匹配 a
和 c
的形状,但这会浪费内存。我也可以将整个事情放在循环中,但对于我尝试编写的实际代码来说,这将很麻烦。还有其他可能吗?
我认为 Fortran 要么阻止您搬起石头砸自己的脚,要么,如果您愿意,坚持要求您清楚要乘以哪些数组元素。表达式
a(1:20,:,1:2)
是第二个索引的每个值的 40 个元素的部分。根本不清楚 b
的 5 个元素要相乘。
我怀疑您正在寻找 spread
函数,该函数用于 'uprank' 数组。如果没有澄清,就很难提出 spread
的适当应用,也许如果你进一步解释,你会得到比这个更好的答案。
哎呀,不解释就继续吧...
我将 OP 的意图解释为计算 c
的元素,因此:
DO ix = 1,5
c(:,ix,:) = a(:,ix,:)*b(ix)
END DO
可以替换为
c = a * SPREAD(SPREAD(b,dim=1,ncopies=20),dim=3,ncopies=2)
我只进行了非常有限的测试,教训可能是遵循@ptb 的建议坚持 do
循环。
这段代码片段:
real*8 a(20,5,2)
real*8 b(5)
real*8 c(20,5,2)
! define a vals ....
! define b vals ....
c(1:20, :, 1:2) = a(1:20,:,1:2)*b
无法编译,因为 b
与 a
或 c
的形状不同。当然,我希望 b
的五个值与 a
和 c
的中间索引的 5 个值相匹配,但 Fortran 编译器不理解这一点。有什么办法可以告诉它我在这里想要什么吗?我知道我可以在更大的数组中复制 b
以匹配 a
和 c
的形状,但这会浪费内存。我也可以将整个事情放在循环中,但对于我尝试编写的实际代码来说,这将很麻烦。还有其他可能吗?
我认为 Fortran 要么阻止您搬起石头砸自己的脚,要么,如果您愿意,坚持要求您清楚要乘以哪些数组元素。表达式
a(1:20,:,1:2)
是第二个索引的每个值的 40 个元素的部分。根本不清楚 b
的 5 个元素要相乘。
我怀疑您正在寻找 spread
函数,该函数用于 'uprank' 数组。如果没有澄清,就很难提出 spread
的适当应用,也许如果你进一步解释,你会得到比这个更好的答案。
哎呀,不解释就继续吧...
我将 OP 的意图解释为计算 c
的元素,因此:
DO ix = 1,5
c(:,ix,:) = a(:,ix,:)*b(ix)
END DO
可以替换为
c = a * SPREAD(SPREAD(b,dim=1,ncopies=20),dim=3,ncopies=2)
我只进行了非常有限的测试,教训可能是遵循@ptb 的建议坚持 do
循环。