2014-10-04

minloc, minval (maxloc, maxval) について再度自分用まとめ。サンプルつき

これ何度目だよって感じだが忘れやすいので…

2次元配列 a(i,j) について考えてみよう。もっと具体的にするか…

a =
i  / j →

 |   1  2   3  0 |     |(1,1) (1,2) (1,3) (1,4)|
 |   5  6   7  8 | ... |(2,1) (2,2) (2,3) (2,4)|
 |   9  8   0  6 |     |(3,1) (3,2) (3,3) (3,4)|
 |  -3  4  -1  2 |     |(4,1) (4,2) (4,3) (4,4)|

としよう。

val:

  • 無指定 → 返り値はスカラ。minval( a ) で配列全体の最小値。 minval( a ) = -3.
  • dim を指定 → 返り値は配列。minval( a, dim=1 ) なら、各列ごとの最小値。minval( a, dim=1 ) = ( -3, 2, -1, 0 )

loc:

  • 無指定 → 返り値は1次元配列(ここを勘違いしてた)。今は2次元配列なので、要素は2つ。考えたら当たり前で、ここに入ってる値ってのが ( i_location_a_is_min, j_location_a_is_min ) ということ。そりゃそうだ…。minloc( a ) = ( 4, 1 ).
  • 当然、3次元配列なら ( i_minloc, j_minloc, k_minloc ) の3要素が入った1次元配列になる。
  • dim を指定 → 返り値は配列。次元は今の場合 2-1 = 1 になる。意味は「各列で最小の値のj位置」になる。つまり minloc( a, dim=1 ) = ( 4, 1, 4, 1 ) となる。i 位置の情報はシーケンシャルというところで入ってるので省略されるわけか…。

サンプルコード

ただし、古い g95 では minloc のところがランタイムに segfault になる。-Wall, -Wextra などはスルーされる。$ g95 -v で 2010 なら多分アウト。バグだったっぽい。gfortran か ifort で試すのがベター。

program test_val_loc
  implicit none
  integer :: a(4,4)

  a(1,1) = 1
  a(1,2) = 2
  a(1,3) = 3
  a(1,4) = 0

  a(2,1) = 5
  a(2,2) = 6
  a(2,3) = 7
  a(2,4) = 8

  a(3,1) = 9
  a(3,2) = 8
  a(3,3) = 0
  a(3,4) = 6

  a(4,1) = -3
  a(4,2) = 4
  a(4,3) = -1
  a(4,4) = 2

  !! val
  write(*,"('minval( a ) = ',i2)") minval( a )
  write(*,"('minval( a, dim=1 ) = ',4(i2,1x))") minval( a, dim=1 )
  write(*,"('minval( a, dim=2 ) = ',4(i2,1x))") minval( a, dim=2 )

  !! loc
  write(*,"('minloc( a ) = (i_minloc,j_minloc) = (',i2,',',i2,')')") minloc( a )
  write(*,"('minloc( a, dim=1 ) = ',4(i2,1x))") minloc( a, dim=1 )
  write(*,"('minloc( a, dim=2 ) = ',4(i2,1x))") minloc( a, dim=2 )

  stop
endprogram test_val_loc

No comments: