多次元配列のインデクシングと演算

2026年3月31日
2 分

本題に入る前に。

おとといの例にも出てきたけど、reshape 関数で範囲オブジェクトを多次元配列に変換すると、次のようになる。

julia> reshape(1:4, 2, 2)
2×2 reshape(::UnitRange{Int64}, 2, 2) with eltype Int64:
 1  3
 2  4

期待通り2×2になってるけど、UnitRange{Int64} という見慣れない型になっている。 これは、範囲を表す型らしい。

julia> typeof(1:4)
UnitRange{Int64}

このままだと Int64 の配列にならないので、collect 関数で変換してやるのがいい。

julia> A = collect(reshape(1:4, 2, 2))
2×2 Matrix{Int64}:
 1  3
 2  4

これで普通の Array 型になった。

さて、この要素にアクセスするには、1番目の次元のインデックスを i、2番目の次元のインデックスを j として A[i, j] のようにする。参照するときも代入するときも同じ。

julia> A
2×2 Matrix{Int64}:
 1  3
 2  4

julia> A[1, 2]
3

julia> A[1, 2] = 7
7

julia> A
2×2 Matrix{Int64}:
 1  7
 2  4

改めて確認しておくと、列方向(↓方向)が1番目の次元、行方向(→方向)が2番目の次元だ。 ついでにインデックスは 1 始まり。

配列の基本的な演算は標準でサポートされている。いくつか試してみよう。

julia> B = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> A - B
2×2 Matrix{Int64}:
  0  5
 -1  0

julia> A + B
2×2 Matrix{Int64}:
 2  9
 5  8

julia> A * B
2×2 Matrix{Int64}:
 22  30
 14  20

julia> A / B
2×2 Matrix{Float64}:
 8.5  -2.5
 2.0   0.0

julia> A \ B
2×2 Matrix{Float64}:
  1.7  2.0
 -0.1  0.0

/ は右除算、\ は左除算で、他の演算よりも少し時間がかかる印象。 左除算した結果に左からかけてやれば元に戻る(型は Float64 に変わるけど)。

julia> A * (A \ B)
2×2 Matrix{Float64}:
 1.0  2.0
 3.0  4.0

スカラー積も *

julia> A
2×2 Matrix{Int64}:
 1  7
 2  4

julia> A * 2
2×2 Matrix{Int64}:
 2  14
 4   8

julia> 2 * A
2×2 Matrix{Int64}:
 2  14
 4   8

要素ごとの演算も用意されている。

julia> A .+ B
2×2 Matrix{Int64}:
 2  9
 5  8

julia> A .- B
2×2 Matrix{Int64}:
  0  5
 -1  0

julia> A .* B
2×2 Matrix{Int64}:
 1  14
 6  16

julia> A ./ B
2×2 Matrix{Float64}:
 1.0       3.5
 0.666667  1.0

スカラーとの演算も同様。

julia> A .+ 2
2×2 Matrix{Int64}:
 3  9
 4  6

julia> A .- 2
2×2 Matrix{Int64}:
 -1  5
  0  2

julia> A .* 2
2×2 Matrix{Int64}:
 2  14
 4   8

julia> A ./ 2
2×2 Matrix{Float64}:
 0.5  3.5
 1.0  2.0