配列
d:id:konnyakmannan:20091212 をみて。
彼が FORTRAN の配列をどこで便利に感じているのかはわからないのだけれど、
C で任意次元配列をサブルーチンで扱うために一次元配列を利用するのを思いだした。
やり方は Row- and column-major order - Wikipedia や
The N-dimensional array (ndarray) — NumPy v1.16 Manual
を見ればすぐわかる。
こんな指数を返す関数を作っておけばいい。C99 で書いてあるので注意。
// 総積の計算(多次元配列の全要素数を計算するのに使う) int prod(const int* N, int rank){ int prod = 1; for(int i=0; i<rank; ++i) prod *= N[i]; return prod; } // 一次元配列の指数から多次元配列の指数を計算 void index_to_ndindex(int index, int* ndindex, int rank, const int* N){ int base = index; for(int k=rank-1; k>=0; --k){ ndindex[k] = base % N[k]; base = (base - ndindex[k])/N[k]; } } // 多次元配列の指数から一次元配列の指数を計算 int index_from_ndindex(const int* ndindex, int rank, const int* N){ int index = 0; int stride = 1; for(int k=rank-1; k>=0; --k){ index += stride * ndindex[k]; stride *= N[k]; } return index; }
例えば、三次元配列 を用意して、 を出力ってのを書くと。
int main(){ const int rank = 3; const int N[] = {5, 6, 3}; int size = prod(N, rank); double A[size]; for(int i=0; i<size; ++i){ int k[rank]; index_to_ndindex(i, k, rank, N); A[i] = 1.0; for(int n=0; n<rank; ++n) A[i] *= k[n]; } int k[] = {4, 3, 1}; printf("%g\n", A[index_from_ndindex(k, rank, N)]); }
FORTRAN で書いたルーチンを使うために column-major にするには、指数を返す関数内のループを逆に回せばいい。