はじめに
Juliaには多次元配列が用意されているが、CやJava育ちの人間からするとインデックスの付け方がとてもわかりにくいのでまとめてみた。
Javaの場合
Javaには多次元配列はなく、配列の配列が書けるだけだ。3次元の配列(というか配列の配列の配列)は
次のように書く。
int [][][] a = new int[2][3][4];
この場合、最内周になるのは一番右のインデックス(この場合は長さ4のもの)だ。
Cの場合
Cでは多次元配列も配列の配列も書ける。宣言の仕方は全然違うのだけど、使い方はおなじなので大変紛らわしい。
まず配列の配列。宣言はポインタのポインタのポインタとして定義して、malloc
で中身を個別に確保する。面倒くさい。
char ***array2;
int counter = 0;
array2 = (char ***) malloc(sizeof(char**) * 2);
for (int i = 0; i < 2; i++) {
array2[i] = (char **)malloc(sizeof(char*) * 3);
for (int j = 0; j < 3; j++) {
array2[i][j] = (char *)malloc(sizeof(char) * 4);
for (int k = 0; k < 4; k++) {
array2[i][j][k] = counter++;
}
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
printf("%d ", array2[i][j][k]);
}
printf("\n");
}
printf("\n");
}
malloc
の返り値チェックしていないとかは気にしないでほしい。
多次元配列の場合は、もう少し楽。メモリ領域が連続しているので一括で確保できる。注目してほしいのは出力部分でのアクセスの仕方が全く同じ形array[i][j][k]
になっていること。
char array[2][3][4];
char * v =(char*) array;
for (int i = 0; i < 24; i++)
*v++ = i;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
printf("%d ", array[i][j][k]);
}
printf("\n");
}
printf("\n");
}
出力はいずれの場合も
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
となる。いずれにしろ、最内周に対応するのは、1番右側のインデックスだ。
Python numpyの場合
numpy の場合もCやJavaと同じ。つまり最内周のインデックスは一番右。
>>> np.arange(0, 24).reshape(2,3,4)
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
Juliaの場合
これがJuliaだと逆になる。つまり最内周に対応するのは、一番左のインデックスだ。全く同じような感じでreshape
しても結果がnumpyの場合と全く違うのがわかる。
julia> reshape(0:23, (2, 3, 4))
2×3×4 reshape(::UnitRange{Int64}, 2, 3, 4) with eltype Int64:
[:, :, 1] =
0 2 4
1 3 5
[:, :, 2] =
6 8 10
7 9 11
[:, :, 3] =
12 14 16
13 15 17
[:, :, 4] =
18 20 22
19 21 23
また、2次元配列を書く際の順番もカラム優先になっていることがわかる。
JuliaはPyCallでPythonのライブラリが呼び出せるのだけど、その時の値の受け渡しで、いろいろ面倒なことが起きそうな気がする。。
所感
多次元配列の場合には、どのインデックスを内周にするのかは言語設計者が任意に決められそうなのだけど、配列の配列を書く場合には、必然的に後ろ(右側)のインデックスが内周にならざるを得ない。
Juliaで最初のインデックスが内周になっているのはFortranの伝統なのだろうと思うのだけど、なんでFortranはそうしたんだろう。なにか必然性があるのか、ただ偶然そうしただけなのか。偶然だとするとかなり不幸な偶然だな。。