static VALUE //iter_struct_inspect(na_loop_t *const lp) iter_struct_inspect(char *ptr, size_t pos, VALUE opt) { VALUE types, defs, def, name, elmt, vary, v, x; size_t ofs; long i, len; narray_view_t *ne; types = RARRAY_AREF(opt,0); defs = RARRAY_AREF(opt,1); len = RARRAY_LEN(types); vary = rb_ary_new2(len); for (i=0; i<len; i++) { def = RARRAY_AREF(defs,i); name = RARRAY_AREF(def,0); ofs = NUM2SIZET(RARRAY_AREF(def,2)); elmt = RARRAY_AREF(types,i); GetNArrayView(elmt,ne); ne->offset = pos + ofs; v = rb_str_concat(rb_sym_to_s(name), rb_str_new2(": ")); x = rb_funcall(elmt, rb_intern("format_to_a"), 0); // <-- fix me if (ne->base.ndim==0) { x = rb_funcall(x, rb_intern("first"), 0); } x = rb_funcall(x, rb_intern("to_s"), 0); v = rb_str_concat(v, x); rb_ary_push(vary, v); } v = rb_ary_join(vary, rb_str_new2(", ")); v = rb_str_concat(rb_str_new2("["), v); v = rb_str_concat(v, rb_str_new2("]")); return v; }
VALUE na_make_view_struct(VALUE self, VALUE dtype, VALUE offset) { size_t i, n; int j, k, ndim; size_t *shape; size_t *idx1, *idx2; ssize_t stride; stridx_t *stridx; narray_t *na, *nt; narray_view_t *na1, *na2; VALUE klass; volatile VALUE view; GetNArray(self,na); // build from Numo::Struct if (rb_obj_is_kind_of(dtype,cNArray)) { GetNArray(dtype,nt); ndim = na->ndim + nt->ndim; shape = ALLOCA_N(size_t,ndim); // struct dimensions for (j=0; j<na->ndim; j++) { shape[j] = na->shape[j]; } // member dimension for (j=na->ndim,k=0; j<ndim; j++,k++) { shape[j] = nt->shape[k]; } klass = CLASS_OF(dtype); stridx = ALLOC_N(stridx_t, ndim); stride = na_dtype_elmsz(klass); for (j=ndim,k=nt->ndim; k; ) { SDX_SET_STRIDE(stridx[--j],stride); stride *= nt->shape[--k]; } } else { ndim = na->ndim; shape = ALLOCA_N(size_t,ndim); for (j=0; j<ndim; j++) { shape[j] = na->shape[j]; } klass = CLASS_OF(self); if (TYPE(dtype)==T_CLASS) { if (RTEST(rb_class_inherited_p(dtype,cNArray))) { klass = dtype; } } stridx = ALLOC_N(stridx_t, ndim); } view = na_s_allocate_view(klass); na_copy_flags(self, view); GetNArrayView(view, na2); na_setup_shape((narray_t*)na2, ndim, shape); na2->stridx = stridx; switch(na->type) { case NARRAY_DATA_T: case NARRAY_FILEMAP_T: stride = na_get_elmsz(self); for (j=na->ndim; j--;) { SDX_SET_STRIDE(na2->stridx[j], stride); stride *= na->shape[j]; } na2->offset = 0; na2->data = self; break; case NARRAY_VIEW_T: GetNArrayView(self, na1); for (j=na1->base.ndim; j--; ) { if (SDX_IS_INDEX(na1->stridx[j])) { n = na1->base.shape[j]; idx1 = SDX_GET_INDEX(na1->stridx[j]); idx2 = ALLOC_N(size_t, na1->base.shape[j]); for (i=0; i<n; i++) { idx2[i] = idx1[i]; } SDX_SET_INDEX(na2->stridx[j],idx2); } else { na2->stridx[j] = na1->stridx[j]; } } na2->offset = na1->offset; na2->data = na1->data; break; } if (RTEST(offset)) { na2->offset += NUM2SIZET(offset); } return view; }
/* * call-seq: * narray.reverse([dim0,dim1,..]) => narray * * Return reversed view along specified dimeinsion */ VALUE nary_reverse(int argc, VALUE *argv, VALUE self) { int i, nd; size_t j, n; size_t offset; size_t *idx1, *idx2; ssize_t stride; ssize_t sign; narray_t *na; narray_view_t *na1, *na2; VALUE view; VALUE reduce; reduce = na_reduce_dimension(argc, argv, 1, &self); GetNArray(self,na); nd = na->ndim; view = na_s_allocate_view(CLASS_OF(self)); na_copy_flags(self, view); GetNArrayView(view, na2); na_setup_shape((narray_t*)na2, nd, na->shape); na2->stridx = ALLOC_N(stridx_t,nd); switch(na->type) { case NARRAY_DATA_T: case NARRAY_FILEMAP_T: stride = na_get_elmsz(self); offset = 0; for (i=nd; i--;) { if (na_test_reduce(reduce,i)) { offset += (na->shape[i]-1)*stride; sign = -1; } else { sign = 1; } SDX_SET_STRIDE(na2->stridx[i],stride*sign); stride *= na->shape[i]; } na2->offset = offset; na2->data = self; break; case NARRAY_VIEW_T: GetNArrayView(self, na1); offset = na1->offset; for (i=0; i<nd; i++) { n = na1->base.shape[i]; if (SDX_IS_INDEX(na1->stridx[i])) { idx1 = SDX_GET_INDEX(na1->stridx[i]); idx2 = ALLOC_N(size_t,n); if (na_test_reduce(reduce,i)) { for (j=0; j<n; j++) { idx2[n-1-j] = idx1[j]; } } else { for (j=0; j<n; j++) { idx2[j] = idx1[j]; } } SDX_SET_INDEX(na2->stridx[i],idx2); } else { stride = SDX_GET_STRIDE(na1->stridx[i]); if (na_test_reduce(reduce,i)) { offset += (n-1)*stride; SDX_SET_STRIDE(na2->stridx[i],-stride); } else { na2->stridx[i] = na1->stridx[i]; } } } na2->offset = offset; na2->data = na1->data; break; } return view; }
static VALUE nstruct_add_type(VALUE type, int argc, VALUE *argv, VALUE nst) { VALUE ofs, size; ID id; int i; VALUE name=Qnil; size_t *shape=NULL; int ndim=0; ssize_t stride; narray_view_t *nt; int j; for (i=0; i<argc; i++) { switch(TYPE(argv[i])) { case T_STRING: case T_SYMBOL: if (NIL_P(name)) { name = argv[i]; break; } rb_raise(rb_eArgError,"multiple name in struct definition"); case T_ARRAY: if (shape) { rb_raise(rb_eArgError,"multiple shape in struct definition"); } ndim = RARRAY_LEN(argv[i]); if (ndim > NA_MAX_DIMENSION) { rb_raise(rb_eArgError,"too large number of dimensions"); } if (ndim == 0) { rb_raise(rb_eArgError,"array is empty"); } shape = ALLOCA_N(size_t, ndim); na_array_to_internal_shape(Qnil, argv[i], shape); break; } } id = rb_to_id(name); name = ID2SYM(id); if (rb_obj_is_kind_of(type,cNArray)) { narray_t *na; GetNArray(type,na); type = CLASS_OF(type); ndim = na->ndim; shape = na->shape; } type = rb_narray_view_new(type,ndim,shape); GetNArrayView(type,nt); nt->stridx = ALLOC_N(stridx_t,ndim); stride = na_dtype_elmsz(CLASS_OF(type)); for (j=ndim; j--; ) { SDX_SET_STRIDE(nt->stridx[j], stride); stride *= shape[j]; } ofs = rb_iv_get(nst, "__offset__"); nt->offset = NUM2SIZET(ofs); size = rb_funcall(type, rb_intern("byte_size"), 0); rb_iv_set(nst, "__offset__", rb_funcall(ofs,'+',1,size)); rb_ary_push(rb_iv_get(nst,"__members__"), rb_ary_new3(4,name,type,ofs,size)); // <- field definition return Qnil; }
int na_get_result_dimension(VALUE self, int argc, VALUE *argv, ssize_t stride, size_t *pos_idx) { int i, j; int count_new=0; int count_rest=0; ssize_t x, s, m, pos, *idx; narray_t *na; narray_view_t *nv; stridx_t sdx; VALUE a; GetNArray(self,na); if (na->size == 0) { rb_raise(nary_eShapeError, "cannot get element of empty array"); } idx = ALLOCA_N(ssize_t, argc); for (i=j=0; i<argc; i++) { a = argv[i]; switch(TYPE(a)) { case T_FIXNUM: idx[j++] = FIX2LONG(a); break; case T_BIGNUM: case T_FLOAT: idx[j++] = NUM2SSIZET(a); break; case T_FALSE: case T_SYMBOL: if (a==sym_rest || a==sym_tilde || a==Qfalse) { argv[i] = Qfalse; count_rest++; break; } else if (a==sym_new || a==sym_minus) { argv[i] = sym_new; count_new++; } } } if (j != argc) { return check_index_count(argc, na->ndim, count_new, count_rest); } switch(na->type) { case NARRAY_VIEW_T: GetNArrayView(self,nv); pos = nv->offset; if (j == na->ndim) { for (i=j-1; i>=0; i--) { x = na_range_check(idx[i], na->shape[i], i); sdx = nv->stridx[i]; if (SDX_IS_INDEX(sdx)) { pos += SDX_GET_INDEX(sdx)[x]; } else { pos += SDX_GET_STRIDE(sdx)*x; } } *pos_idx = pos; return 0; } if (j == 1) { x = na_range_check(idx[0], na->size, 0); for (i=na->ndim-1; i>=0; i--) { s = na->shape[i]; m = x % s; x = x / s; sdx = nv->stridx[i]; if (SDX_IS_INDEX(sdx)) { pos += SDX_GET_INDEX(sdx)[m]; } else { pos += SDX_GET_STRIDE(sdx)*m; } } *pos_idx = pos; return 0; } break; default: if (!stride) { stride = nary_element_stride(self); } if (j == 1) { x = na_range_check(idx[0], na->size, 0); *pos_idx = stride * x; return 0; } if (j == na->ndim) { pos = 0; for (i=j-1; i>=0; i--) { x = na_range_check(idx[i], na->shape[i], i); pos += stride * x; stride *= na->shape[i]; } *pos_idx = pos; return 0; } } rb_raise(rb_eIndexError,"# of index(=%i) should be " "equal to ndim(=%i) or 1", argc,na->ndim); return -1; }