按其他常量指定的顺序填充常量数组?

时间:2016-04-19 00:24:51

标签: fortran

有没有办法按照其他常量变量指定的顺序填充常量数组?

所以,实际上是这样的:

integer, parameter :: ired  = 1
integer, parameter :: iblue = 2
real,    parameter :: myarr(2,3)
myarr(ired, :) = [1,0,0]
myarr(iblue,:) = [0,0,1]

除了以上当然不会编译。有没有办法以某种方式达到这个目的?

2 个答案:

答案 0 :(得分:1)

不,在程序启动后无法为parameter分配值;这正是属性parameter旨在阻止的内容。

你可以写

real, parameter :: myarr(2,3) = reshape([1.0,0,0,0,0,1],[2,3])

初始化myarr。请注意,元素以Fortran指定的数组元素顺序提供给reshape(即列专业);在这里,它恰好与您在行主要顺序中指定它们相同。请注意,在Fortran initialization中,确切地说,在声明语句中设置一个值,这是参数获取值的方式。

我没有立即看到在初始化中使用irediblue的任何方法,但我很难将其视为一个问题。

在OP的评论之后编辑:

我猜你可以写点像

  INTEGER, PARAMETER :: ired  = 1
  INTEGER, PARAMETER :: iblue = 2
  REAL, PARAMETER, DIMENSION(2,3) :: rows = reshape([1,0,0,0,0,1],[2,3])
  REAL, PARAMETER :: myarr(2,3) = RESHAPE([rows(ired,:), rows(iblue,:)], [2,3])

现在您只需交换iredblue的值即可更改myarr。你唯一可能忘记的就是为什么你写了这么复杂的代码!

答案 1 :(得分:1)

为了概括@ HPM对irediblue等可能不连续的情况(例如,1和3)的回答,结合使用隐含的do-loop +数组构造函数可能很有用。因为Fortran中的数组是列主要的,所以我将矩阵中的向量对齐,使得[vec1,vec2,...,vecN] vecX是一个3向量。

integer :: k
integer, parameter :: ired = 1, iblue = 3, mxvec = 4, ndim = 3, zero(3) = [0,0,0]

integer, dimension( ndim * mxvec ), parameter :: &
        red  = [ (zero, k=1,ired-1 ), [1,1,1], (zero, k=ired+1, mxvec) ], &
        blue = [ (zero, k=1,iblue-1), [7,7,7], (zero, k=iblue+1,mxvec) ]

integer, parameter :: myarr( ndim, mxvec ) = reshape( red + blue, [ ndim, mxvec ] )

print "(a,/100(3i2/))", "red   = ", red
print "(a,/100(3i2/))", "blue  = ", blue
print "(a,/100(3i2/))", "myarr = ", myarr

print *, "myarr( :, ired  ) = ", myarr( :, ired  )
print *, "myarr( :, iblue ) = ", myarr( :, iblue )

结果:

red   =
 1 1 1
 0 0 0
 0 0 0
 0 0 0

blue  =
 0 0 0
 0 0 0
 7 7 7
 0 0 0

myarr =
 1 1 1
 0 0 0
 7 7 7
 0 0 0

 myarr( :, ired  ) =            1           1           1
 myarr( :, iblue ) =            7           7           7