ごとけんです

伊藤彰則さん作の mdarray にひとつクラスメソッドを足しました.

  mda = MDArray.from_flat(size1,size2, ..., sizeN){ary}

は大雑把に言って次の逆に相当します:

  ary = []; mda.each{|i| ary.push i}

要するに, ary = [e1,e2,...,eM] という平らな配列から,
全部でM個の要素からなるN次元配列 mda を作るものです.
ただし,M == size1 × … × sizeN でなければ例外が
発生します.

pbm(5) を矩形として読むようなときに便利だと思います.
気に入りそうなら使ってください.

# あと,いくつかキャストが抜けてたので足しました.

-- gotoken

diff -u0r ext/mdarray.orig/README ext/mdarray/README --- ext/mdarray.orig/README Sun Jan 24 09:36:46 1999 +++ ext/mdarray/README Sun Jan 24 09:48:12 1999 @@ -80,0 +81,6 @@ + from_flat(size1, size2, ..., sizeN){array} + N次元配列を作り,ブロックを評価した値で初期化します. + ブロックを評価した値が配列でなければ例外が発生します. + 初期化は,array.each の順に取り出され,each の + 順に代入されます.作ったN次元配列の要素の総数と, + array の総数が一致しないときは例外が発生します. diff -u0r ext/mdarray.orig/mdarray.c ext/mdarray/mdarray.c --- ext/mdarray.orig/mdarray.c Tue Aug 26 13:48:13 1997 +++ ext/mdarray/mdarray.c Sun Jan 24 09:31:15 1999 @@ -163,0 +164,30 @@ + +/* class method: from_flat(array){array} */ +static VALUE +mda_from_flat(argc, argv) + int argc; + VALUE *argv; +{ + struct MD_ARRAY *mda; + VALUE ary; + int *args; + int i; + + if (!iterator_p()) + Fail("missing block"); + + if (argc == 0) + Fail("argument mismatch"); + else { + args = ALLOCA_N(int,argc); + for (i = 0; i < argc; i++) + args[i] = NUM2INT(argv[i]); + mda = alloc_MD_ARRAY(argc,args); + } + + ary = rb_yield(Qnil); + if (TYPE(ary) != T_ARRAY) + Fail("block value isn't Array"); + mda->ptr = RARRAY(ary)->ptr; + return Data_Wrap_Struct(cMDArray,mda_mark,mda_free,mda); +} @@ -301 +331 @@ - ary_store(vsize,i,INT2FIX(0)); + ary_store((VALUE)vsize,i,INT2FIX(0)); @@ -304 +334 @@ - rb_yield(vsize); + rb_yield((VALUE)vsize); @@ -311 +341 @@ - ary_store(vsize,i,INT2FIX(0)); + ary_store((VALUE)vsize,i,INT2FIX(0)); @@ -316 +346 @@ - ary_store(vsize,i,INT2FIX(size[i])); + ary_store((VALUE)vsize,i,INT2FIX(size[i])); @@ -438,0 +469 @@ + rb_define_singleton_method(cMDArray,"from_flat",mda_from_flat,-1);