这是我的代码:
Program Arrays
Implicit none
Integer::i,j
Integer,dimension(2)::V_Max
Complex,dimension(0:7,3)::V_cvo
Complex,dimension(7,3)::V_cvo_temp
Do concurrent(i=0:7,j=1:3)
V_cvo(i,j)=cmplx(i+j,2*i-j)
End Do
V_cvo_temp=V_cvo(1:,:)
V_Min=minloc(abs((/((V_cvo_temp(i,j),j=1,3),i=2,5)/)))
Stop
End Program Arrays
编译后我收到了这条消息:
Error: Different shape for array assignment on dimension 1 (2 and 1)|
这里有什么问题?如果我想在该数组的特定扇区中的某个数组中找到最小元素的位置,那么它是如何可能的?
这可能是问题的可能解决方案之一:
Program Arrays
Implicit none
Integer::i,j
Integer,dimension(2)::V_Max
Complex,dimension(0:7,2)::V_cvo
Logical,dimension(0:7,2) :: lmask = .FALSE.
forall(i=2:5,j=1:2)lmask(i,j) = .TRUE.
Do concurrent(i=0:7,j=1:2)
V_cvo(i,j)=cmplx(i+j,2*i-j)
End Do
V_Max = Maxloc(abs(V_cvo),mask=lmask)-(/1,0/)
Open(1,File='Output.txt',Status='Unknown')
Write(1,'(2x,i0,2x,i0)') V_max
Write(1,*)
Do concurrent(i=2:5,j=1:2)
Write(1,'(1x,i0,1x,i0,2x,f7.4)')i,j,abs(V_cvo(i,j))
End Do
Close(1)
Stop
End Program Arrays
输出文件是:
5 1
2 1 4.2426
3 1 6.4031
4 1 8.6023
5 1 10.8167
2 2 4.4721
3 2 6.4031
4 2 8.4853
5 2 10.6301
对此的看法?
答案 0 :(得分:3)
此表达式
minloc(abs((/((V_cvo_temp(i,j),j=1,3),i=2,5)/)))
返回包含1个元素的rank-1数组。赋值的 lhs 是具有2个元素的rank-1数组。 Fortran不会分配不兼容的数组 - 因此编译错误消息。
(@ gdlmx'答案在诊断中是错误的,如果表达式返回标量,Fortran会愉快地将其值广播到数组的每个元素。)
如果表达式确实返回标量,它仍然不会返回V_cvo
部分中最小元素的位置。子表达式
(/((V_cvo_temp(i,j),j=1,3),i=2,5)/)
生成一个包含指定元素V_cvo_temp
的rank-1数组,它基本上将数组变平为一个向量并沿途丢失它们的位置。这就是为什么第一个表达式返回带有1个元素的rank-1数组的原因 - 它是rank-1数组中元素的位置。
此解决方案的问题
V_Min=minloc(abs(V_cvo(2:5,1:3)))
表达式abs(V_cvo(2:5,1:3))
将返回索引的(临时)数组,因为默认情况下Fortran数组在每个等级上为1。当我尝试代码时,它会返回位于所考虑部分之外的位置(1,1)
。这是临时数组的最小元素的位置。
'聪明的问题'我尝试过的解决方案是abs(V_cvo(2:5,1:3))
总是返回,即使从视图中隐藏,每个等级从1开始索引的临时数组。 minloc
或类似函数的任何应用都使用这些索引,而不是v_cvo
使用的索引。最好的解决方案可能是制作一个显式的临时数组(适当声明),如下所示:
allocate(abstemp(LBOUND(v_cvo,1):UBOUND(v_cvo,1),LBOUND(v_cvo,2):UBOUND(v_cvo,2)))
然后
v_min = minloc(abstemp(2:5,1:3))
和
deallocate(abstemp)
答案 1 :(得分:1)
似乎是
的右侧//component/@id[string()]
返回标量而不是2个组件的向量。您需要的是sphere packing problem://component/@id[normalize-space()]
V_Min=minloc(abs((/((V_cvo_temp(i,j),j=1,3),i=2,5)/)))
或更简单
V_cvo_temp(1:3,2:5)
此外,您最后还不需要V_Min=minloc(abs(V_cvo_temp(2:5,1:3)))
。
V_Min=minloc(abs(V_cvo(2:5,1:3))) ! without temp array
返回相对于(1,1)的索引。要了解此行为,请尝试以下示例:
stop
输出:
minloc
因此,如果将子数组传递给minloc,则需要添加基本索引以获得正确的'答案。
答案 2 :(得分:0)
此解决方案也可以正常工作(最好的):
forall(i=1:7,j=1:3) V_cvo_temp(i,j)=abs(V_cvo(i,j))
V_Min = MINLOC(V_cvo_temp(m:n,:))+(/m-1,0/)
对于每个m和n,如果它们在这种情况下的区间1:7或其他某个区间内,则代码是正确的。