ext/numo/narray/ndloop.c in numo-narray-0.9.0.3 vs ext/numo/narray/ndloop.c in numo-narray-0.9.0.4

- old
+ new

@@ -1,14 +1,9 @@ /* ndloop.c Numerical Array Extension for Ruby (C) Copyright 1999-2016 by Masahiro TANAKA - - This program is free software. - You can distribute/modify this program - under the same terms as Ruby itself. - NO WARRANTY. */ #include <ruby.h> #include "numo/narray.h" @@ -512,11 +507,11 @@ if (n != 1) { if (lp->n[i] == 1) { lp->n[i] = n; } else if (lp->n[i] != n) { // inconsistent array shape - rb_raise(rb_eTypeError,"shape1[%d](=%"SZF"u) != shape2[%d](=%"SZF"u)", + rb_raise(nary_eShapeError,"shape1[%d](=%"SZF"u) != shape2[%d](=%"SZF"u)", i, lp->n[i], k, n); } } } } @@ -1614,11 +1609,11 @@ rb_str_cat(buf,"...",3); goto loop_end; } } } - loop_end: + loop_end: ; } VALUE @@ -1655,12 +1650,68 @@ //---------------------------------------------------------------------- static void -loop_rarray_to_narray(ndfunc_t *nf, na_md_loop_t *lp) +loop_store_subnarray(ndfunc_t *nf, na_md_loop_t *lp, int i0, size_t *c, VALUE a) { + int nd = lp->ndim; + int i, j; + narray_t *na; + int *dim_map; + VALUE a_type; + + a_type = CLASS_OF(LARG(lp,0).value); + if (CLASS_OF(a) != a_type) { + a = rb_funcall(a_type, rb_intern("cast"), 1, a); + } + GetNArray(a,na); + if (na->ndim != nd-i0+1) { + rb_raise(nary_eShapeError, "mismatched dimension of sub-narray: " + "nd_src=%d, nd_dst=%d", na->ndim, nd-i0+1); + } + dim_map = ALLOCA_N(int, na->ndim); + for (i=0; i<na->ndim; i++) { + dim_map[i] = lp->trans_map[i+i0]; + //printf("dim_map[i=%d] = %d, i0=%d\n", i, dim_map[i], i0); + } + ndloop_set_stepidx(lp, 1, a, dim_map, NDL_READ); + LARG(lp,1).shape = &(na->shape[na->ndim-1]); + + // loop body + for (i=i0;;) { + LARG(lp,1).value = Qtrue; + for (; i<nd; i++) { + for (j=0; j<2; j++) { + if (LITER(lp,i,j).idx) { + LITER(lp,i+1,j).pos = LITER(lp,i,j).pos + LITER(lp,i,j).idx[c[i]]; + } else { + LITER(lp,i+1,j).pos = LITER(lp,i,j).pos + LITER(lp,i,j).step*c[i]; + } + } + if (c[i] >= na->shape[i-i0]) { + LARG(lp,1).value = Qfalse; + } + } + + (*(nf->func))(&(lp->user)); + + for (;;) { + if (i<=i0) goto loop_end; + i--; c[i]++; + if (c[i] < lp->n[i]) break; + c[i] = 0; + } + } + loop_end: + LARG(lp,1).ptr = NULL; +} + + +static void +loop_store_rarray(ndfunc_t *nf, na_md_loop_t *lp) +{ size_t *c; int i; VALUE *a; int nd = lp->ndim; @@ -1668,90 +1719,99 @@ c = ALLOCA_N(size_t, nd+1); for (i=0; i<=nd; i++) c[i]=0; // array at each dimension a = ALLOCA_N(VALUE, nd+1); - a[0] = LARG(lp,0).value; + a[0] = LARG(lp,1).value; + //print_ndloop(lp); + // loop body for (i=0;;) { for (; i<nd; i++) { - if (LITER(lp,i,1).idx) { - LITER(lp,i+1,1).pos = LITER(lp,i,1).pos + LITER(lp,i,1).idx[c[i]]; + if (LITER(lp,i,0).idx) { + LITER(lp,i+1,0).pos = LITER(lp,i,0).pos + LITER(lp,i,0).idx[c[i]]; } else { - LITER(lp,i+1,1).pos = LITER(lp,i,1).pos + LITER(lp,i,1).step*c[i]; + LITER(lp,i+1,0).pos = LITER(lp,i,0).pos + LITER(lp,i,0).step*c[i]; } - //LITER(lp,i+1,0).pos = LITER(lp,i,0).pos + c[i]; if (TYPE(a[i])==T_ARRAY) { if (c[i] < (size_t)RARRAY_LEN(a[i])) { a[i+1] = RARRAY_AREF(a[i],c[i]); } else { a[i+1] = Qnil; } - } else { // not Array -- what about narray? + } else if (IsNArray(a[i])) { + //printf("a[i=%d]=0x%lx\n",i,a[i]); + loop_store_subnarray(nf,lp,i,c,a[i]); + goto loop_next; + } else { if (c[i]==0) { a[i+1] = a[i]; } else { a[i+1] = Qnil; } } - //printf("c[i]=%d, i=%d\n",c[i],i); + //printf("c[%d]=%lu\n",i,c[i]); } - //printf("a[i]=0x%x, i=%d\n",a[i],i); - LARG(lp,0).value = a[i]; + //printf("a[i=%d]=0x%lx\n",i,a[i]); + if (IsNArray(a[i])) { + loop_store_subnarray(nf,lp,i,c,a[i]); + } else { + LARG(lp,1).value = a[i]; + (*(nf->func))(&(lp->user)); + } - (*(nf->func))(&(lp->user)); - + loop_next: for (;;) { if (i<=0) goto loop_end; i--; c[i]++; if (c[i] < lp->n[i]) break; c[i] = 0; } } - loop_end: + loop_end: ; } VALUE -na_ndloop_cast_rarray_to_narray(ndfunc_t *nf, VALUE rary, VALUE nary) +na_ndloop_store_rarray(ndfunc_t *nf, VALUE nary, VALUE rary) { na_md_loop_t lp; VALUE args; //rb_p(args); if (na_debug_flag) print_ndfunc(nf); - args = rb_assoc_new(rary,nary); + args = rb_assoc_new(nary,rary); // cast arguments to NArray //ndloop_cast_args(nf, args); // allocate ndloop struct - ndloop_alloc(&lp, nf, args, NULL, 0, loop_rarray_to_narray); + ndloop_alloc(&lp, nf, args, NULL, 0, loop_store_rarray); return rb_ensure(ndloop_run, (VALUE)&lp, ndloop_release, (VALUE)&lp); } VALUE -na_ndloop_cast_rarray_to_narray2(ndfunc_t *nf, VALUE rary, VALUE nary, VALUE opt) +na_ndloop_store_rarray2(ndfunc_t *nf, VALUE nary, VALUE rary, VALUE opt) { na_md_loop_t lp; VALUE args; //rb_p(args); if (na_debug_flag) print_ndfunc(nf); //args = rb_assoc_new(rary,nary); - args = rb_ary_new3(3,rary,nary,opt); + args = rb_ary_new3(3,nary,rary,opt); // cast arguments to NArray //ndloop_cast_args(nf, args); // allocate ndloop struct - ndloop_alloc(&lp, nf, args, NULL, 0, loop_rarray_to_narray); + ndloop_alloc(&lp, nf, args, NULL, 0, loop_store_rarray); return rb_ensure(ndloop_run, (VALUE)&lp, ndloop_release, (VALUE)&lp); }