void na_array_to_internal_shape(VALUE self, VALUE ary, size_t *shape) { size_t i, n, c, s; VALUE v; narray_t *na; int flag = 0; n = RARRAY_LEN(ary); if (RTEST(self)) { GetNArray(self, na); flag = TEST_COLUMN_MAJOR(na); } if (flag) { c = n-1; s = -1; } else { c = 0; s = 1; } for (i=0; i<n; i++) { v = RARRAY_AREF(ary,i); if (!FIXNUM_P(v) && !rb_obj_is_kind_of(v, rb_cInteger)) { rb_raise(rb_eTypeError, "array size must be Integer"); } if (RTEST(rb_funcall(v, rb_intern("<"), 1, INT2FIX(0)))) { rb_raise(rb_eArgError,"size must be non-negative"); } shape[c] = NUM2SIZE(v); c += s; } }
// ------ static void iter_nstruct_from_a(na_loop_t *const lp) { long i, len; VALUE ary; VALUE types, defs, def; VALUE elmt, velm, item; size_t ofs; narray_view_t *ne; types = RARRAY_PTR(lp->option)[0]; defs = RARRAY_PTR(lp->option)[1]; len = RARRAY_LEN(types); ary = lp->args[0].value; //rb_p(CLASS_OF(ary));rb_p(ary); for (i=0; i<len; i++) { def = RARRAY_PTR(defs)[i]; ofs = NUM2SIZE(RARRAY_PTR(def)[2]); elmt = RARRAY_PTR(types)[i]; GetNArrayView(elmt,ne); ne->offset = lp->iter[1].pos + ofs; item = RARRAY_PTR(ary)[i]; //rb_p(ary); //rb_p(item); //rb_p(elmt); //abort(); velm = rb_funcall(elmt, rb_intern("store"), 1, item); } }
static void iter_nstruct_to_a(na_loop_t *const lp) { long i, len; VALUE opt, types, defs, def; VALUE elmt, velm, vary; size_t ofs, pos; narray_view_t *ne; opt = lp->option; types = RARRAY_PTR(opt)[0]; defs = RARRAY_PTR(opt)[1]; pos = lp->iter[0].pos; len = RARRAY_LEN(types); vary = rb_ary_new2(len); for (i=0; i<len; i++) { def = RARRAY_PTR(defs)[i]; ofs = NUM2SIZE(RARRAY_PTR(def)[2]); //ofs = NUM2SIZE(RARRAY_PTR(ofsts)[i]); elmt = RARRAY_PTR(types)[i]; GetNArrayView(elmt,ne); ne->offset = pos + ofs; if (ne->base.ndim==0) { velm = rb_funcall(elmt,rb_intern("extract"),0); } else { velm = rb_funcall(elmt,rb_intern("to_a"),0); } rb_ary_push(vary, velm); } rb_ary_push(lp->args[1].value, vary); }
static VALUE nst_allocate(VALUE self) { narray_t *na; char *ptr; VALUE velmsz; GetNArray(self,na); switch(NA_TYPE(na)) { case NARRAY_DATA_T: ptr = NA_DATA_PTR(na); if (na->size > 0 && ptr == NULL) { velmsz = rb_const_get(CLASS_OF(self), id_element_byte_size); ptr = xmalloc(NUM2SIZE(velmsz) * na->size); NA_DATA_PTR(na) = ptr; } break; case NARRAY_VIEW_T: rb_funcall(NA_VIEW_DATA(na), id_allocate, 0); break; case NARRAY_FILEMAP_T: //ptr = ((narray_filemap_t*)na)->ptr; // to be implemented default: rb_bug("invalid narray type : %d",NA_TYPE(na)); } return self; }
/* Returns total byte size of NArray. @return [Integer] byte size. */ static VALUE nary_byte_size(VALUE self) { VALUE velmsz; //klass, narray_t *na; size_t sz; GetNArray(self,na); velmsz = rb_const_get(CLASS_OF(self), rb_intern(ELEMENT_BYTE_SIZE)); sz = SIZE2NUM(NUM2SIZE(velmsz) * na->size); return sz; }
/* Returns a new 1-D array initialized from binary raw data in a string. @overload from_string(string,[shape]) @param [String] string Binary raw data. @param [Array] shape array of integers representing array shape. @return [Numo::NArray] NArray containing binary data. */ static VALUE nary_s_from_string(int argc, VALUE *argv, VALUE type) { size_t len, str_len, elmsz; size_t *shape; char *ptr; int i, nd, narg; VALUE vstr,vshape,vna; narg = rb_scan_args(argc,argv,"11",&vstr,&vshape); str_len = RSTRING_LEN(vstr); elmsz = na_dtype_elmsz(type); if (narg==2) { nd = RARRAY_LEN(vshape); if (nd == 0 || nd > NA_MAX_DIMENSION) { rb_raise(nary_eDimensionError,"too long or empty shape (%d)", nd); } shape = ALLOCA_N(size_t,nd); len = 1; for (i=0; i<nd; ++i) { len *= shape[i] = NUM2SIZE(RARRAY_AREF(vshape,i)); } if (len*elmsz != str_len) { rb_raise(rb_eArgError, "size mismatch"); } } else { nd = 1; shape = ALLOCA_N(size_t,nd); shape[0] = len = str_len / elmsz; if (len == 0) { rb_raise(rb_eArgError, "string is empty or too short"); } } vna = rb_narray_new(type, nd, shape); ptr = na_get_pointer_for_write(vna); memcpy(ptr, RSTRING_PTR(vstr), elmsz*len); return vna; }
static VALUE rb_ca_ubrep_bind (int argc, VALUE *argv, VALUE self) { CAUnboundRepeat *ca; ca_size_t rep_spec[CA_RANK_MAX]; int i; Data_Get_Struct(self, CAUnboundRepeat, ca); if ( ca->rep_rank != argc ) { rb_raise(rb_eArgError, "invalid new_rank"); } for (i=0; i<argc; i++) { if ( ca->rep_dim[i] == 0 ) { rep_spec[i] = NUM2SIZE(argv[i]); } else { rep_spec[i] = 0; } } return rb_ca_repeat_new(self, argc, rep_spec); }
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_PTR(opt)[0]; defs = RARRAY_PTR(opt)[1]; len = RARRAY_LEN(types); vary = rb_ary_new2(len); for (i=0; i<len; i++) { def = RARRAY_PTR(defs)[i]; name = RARRAY_PTR(def)[0]; ofs = NUM2SIZE(RARRAY_PTR(def)[2]); elmt = RARRAY_PTR(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; }
void nary_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep ) { VALUE vbeg, vend, vstep, vlen; double dbeg, dend, dstep=1, dsize, err; size_t size, n; //vbeg = rb_ivar_get(self, id_beg); vbeg = rb_funcall(self, id_beg, 0); dbeg = NUM2DBL(vbeg); //vend = rb_ivar_get(self, id_end); vend = rb_funcall(self, id_end, 0); vlen = rb_ivar_get(self, id_len); vstep = rb_ivar_get(self, id_step); //vlen = rb_funcall(self, id_len ,0); //vstep = rb_funcall(self, id_step,0); if (RTEST(vlen)) { size = NUM2SIZE(vlen); if (!RTEST(vstep)) { if (RTEST(vend)) { dend = NUM2DBL(vend); if (EXCL(self)) { n = size; } else { n = size-1; } if (n>0) { dstep = (dend-dbeg)/n; } else { dstep = 1; } } else { dstep = 1; } } } else { if (!RTEST(vstep)) { dstep = 1; } else { dstep = NUM2DBL(vstep); } if (RTEST(vend)) { dend = NUM2DBL(vend); err = (fabs(dbeg)+fabs(dend)+fabs(dend-dbeg))/fabs(dstep)*DBL_EPSILON; if (err>0.5) err=0.5; dsize = (dend-dbeg)/dstep; if (EXCL(self)) dsize -= err; else dsize += err; dsize = floor(dsize) + 1; if (dsize<0) dsize=0; if (isinf(dsize) || isnan(dsize)) { rb_raise(rb_eArgError, "not finite size"); } size = dsize; } else { rb_raise(rb_eArgError, "cannot determine length argument"); } } if (plen) *plen = size; if (pbeg) *pbeg = dbeg; if (pstep) *pstep = dstep; }
void nary_step_array_index(VALUE self, size_t ary_size, size_t *plen, ssize_t *pbeg, ssize_t *pstep) { size_t len; ssize_t beg=0, step=1; VALUE vbeg, vend, vstep, vlen; ssize_t end=ary_size; //vbeg = rb_ivar_get(self, id_beg); //vend = rb_ivar_get(self, id_end); vlen = rb_ivar_get(self, id_len); vstep = rb_ivar_get(self, id_step); vbeg = rb_funcall(self, id_beg, 0); vend = rb_funcall(self, id_end, 0); //vlen = rb_funcall(self, id_len, 0); //vstep = rb_funcall(self, id_step, 0); if (RTEST(vbeg)) { beg = NUM2SSIZE(vbeg); if (beg<0) { beg += ary_size; } } if (RTEST(vend)) { end = NUM2SSIZE(vend); if (end<0) { end += ary_size; } } //puts("pass 1"); if (RTEST(vlen)) { len = NUM2SIZE(vlen); if (len>0) { if (RTEST(vstep)) { step = NUM2SSIZE(step); if (RTEST(vbeg)) { if (RTEST(vend)) { rb_raise( rb_eStandardError, "verbose Step object" ); } else { end = beg + step*(len-1); } } else { if (RTEST(vend)) { if (EXCL(self)) { if (step>0) end--; if (step<0) end++; } beg = end - step*(len-1); } else { beg = 0; end = step*(len-1); } } } else { // no step step = 1; if (RTEST(vbeg)) { if (RTEST(vend)) { if (EXCL(self)) { if (beg<end) end--; if (beg>end) end++; } if (len>1) step = (end-beg)/(len-1); } else { end = beg + (len-1); } } else { if (RTEST(vend)) { if (EXCL(self)) { end--; } beg = end - (len-1); } else { beg = 0; end = len-1; } } } } } else { // no len if (RTEST(vstep)) { step = NUM2SSIZE(vstep); } else { step = 1; } if (step>0) { if (!RTEST(vbeg)) { beg = 0; } if (!RTEST(vend)) { end = ary_size-1; } else if (EXCL(self)) { end--; } if (beg<=end) { len = (end-beg)/step+1; } else { len = 0; } } else if (step<0) { if (!RTEST(vbeg)) { beg = ary_size-1; } if (!RTEST(vend)) { end = 0; } else if (EXCL(self)) { end++; } if (beg>=end) { len = (beg-end)/(-step)+1; } else { len = 0; } } else { rb_raise( rb_eStandardError, "step must be non-zero" ); } } //puts("pass 2"); if (beg<0 || beg>=(ssize_t)ary_size || end<0 || end>=(ssize_t)ary_size) { rb_raise( rb_eRangeError, "beg=%"SZF"d,end=%"SZF"d is out of array size (%"SZF"u)", beg, end, ary_size ); } if (plen) *plen = len; if (pbeg) *pbeg = beg; if (pstep) *pstep = step; }
size_t na_dtype_elmsz(VALUE klass) { return NUM2SIZE(rb_const_get(klass, id_contiguous_stride)); }
size_t na_get_elmsz(VALUE vna) { return NUM2SIZE(rb_const_get(CLASS_OF(vna), id_contiguous_stride)); }
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 NArray::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 += NUM2SIZE(offset); } 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 = NUM2SIZE(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; }