Example #1
0
static VALUE
rb_narray_debug_info_naview(VALUE self)
{
    int i;
    narray_view_t *na;
    size_t *idx;
    size_t j;
    GetNArrayView(self,na);

    printf("  data   = 0x%"SZF"x\n", (size_t)na->data);
    printf("  offset = %"SZF"d\n", (size_t)na->offset);
    printf("  stridx = 0x%"SZF"x\n", (size_t)na->stridx);

    if (na->stridx) {
        printf("  stridx = [");
        for (i=0; i<na->base.ndim; i++) {
            if (SDX_IS_INDEX(na->stridx[i])) {

                idx = SDX_GET_INDEX(na->stridx[i]);
                printf("  index[%d]=[", i);
                for (j=0; j<na->base.shape[i]; j++) {
                    printf(" %"SZF"d", idx[j]);
                }
                printf(" ] ");

            } else {
                printf(" %"SZF"d", SDX_GET_STRIDE(na->stridx[i]));
            }
        }
        printf(" ]\n");
    }
    return Qnil;
}
Example #2
0
/*
 *  call-seq:
 *     narray.view => narray
 *
 *  Return view of NArray
 */
VALUE
na_make_view(VALUE self)
{
    int i, nd;
    size_t  j;
    size_t *idx1, *idx2;
    ssize_t stride;
    narray_t *na;
    narray_view_t *na1, *na2;
    volatile VALUE view;

    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);
        for (i=nd; i--;) {
            SDX_SET_STRIDE(na2->stridx[i],stride);
            stride *= na->shape[i];
        }
        na2->offset = 0;
        na2->data = self;
        break;
    case NARRAY_VIEW_T:
        GetNArrayView(self, na1);
        for (i=0; i<nd; i++) {
            if (SDX_IS_INDEX(na1->stridx[i])) {
                idx1 = SDX_GET_INDEX(na1->stridx[i]);
                idx2 = ALLOC_N(size_t,na1->base.shape[i]);
                for (j=0; j<na1->base.shape[i]; j++) {
                    idx2[j] = idx1[j];
                }
                SDX_SET_INDEX(na2->stridx[i],idx2);
            } else {
                na2->stridx[i] = na1->stridx[i];
            }
        }
        na2->offset = na1->offset;
        na2->data = na1->data;
        break;
    }

    return view;
}
Example #3
0
// fix name, ex, allow_stride_for_flatten_view
VALUE
na_check_ladder(VALUE self, int start_dim)
{
    int i;
    ssize_t st0, st1;
    narray_t *na1;
    narray_view_t *na;
    GetNArray(self,na1);

    //puts("pass ladder");

    if (start_dim < -na1->ndim || start_dim >= na1->ndim) {
        rb_bug("start_dim (%d) out of range",start_dim);
    }

    switch(na1->type) {
    case NARRAY_DATA_T:
    case NARRAY_FILEMAP_T:
        return Qtrue;
    case NARRAY_VIEW_T:
        GetNArrayView(self,na);
        // negative dim -> position from last dim
        if (start_dim < 0) {
            start_dim += na->base.ndim;
        }
        // not ladder if it has index
        for (i=start_dim; i<na->base.ndim; i++) {
            if (SDX_IS_INDEX(na->stridx[i]))
                return Qfalse;
        }
        // check stride
        i = start_dim;
        st0 = SDX_GET_STRIDE(na->stridx[i]);
        for (i++; i<na->base.ndim; i++) {
            st1 = SDX_GET_STRIDE(na->stridx[i]);
            if (st0 != (ssize_t)(st1*na->base.shape[i])) {
                return Qfalse;
            }
            st0 = st1;
        }
        return Qtrue;
    }
    return Qtrue;
}
Example #4
0
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;
}
Example #5
0
/*
 *  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;
}
Example #6
0
File: index.c Project: kou/narray
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;
}
Example #7
0
File: index.c Project: kou/narray
static void
na_index_aref_naview(narray_view_t *na1, narray_view_t *na2,
                     na_index_arg_t *q, ssize_t elmsz, int ndim, int keep_dim)
{
    int i, j;
    ssize_t total=1;

    for (i=j=0; i<ndim; i++) {
        stridx_t sdx1 = na1->stridx[q[i].orig_dim];
        ssize_t size;

        // numeric index -- trim dimension
        if (!keep_dim && q[i].n==1 && q[i].step==0) {
            if (SDX_IS_INDEX(sdx1)) {
                na2->offset += SDX_GET_INDEX(sdx1)[q[i].beg];
            } else {
                na2->offset += SDX_GET_STRIDE(sdx1)*q[i].beg;
            }
            continue;
        }

        na2->base.shape[j] = size = q[i].n;

        if (q[i].reduce != 0) {
            VALUE m = rb_funcall(INT2FIX(1),id_shift_left,1,INT2FIX(j));
            na2->base.reduce = rb_funcall(m,'|',1,na2->base.reduce);
        }

        if (q[i].orig_dim >= na1->base.ndim) {
            // new dimension
            SDX_SET_STRIDE(na2->stridx[j], elmsz);
        }
        else if (q[i].idx != NULL && SDX_IS_INDEX(sdx1)) {
            // index <- index
            int k;
            size_t *index = q[i].idx;
            SDX_SET_INDEX(na2->stridx[j], index);
            q[i].idx = NULL;

            for (k=0; k<size; k++) {
                index[k] = SDX_GET_INDEX(sdx1)[index[k]];
            }
        }
        else if (q[i].idx != NULL && SDX_IS_STRIDE(sdx1)) {
            // index <- step
            ssize_t stride1 = SDX_GET_STRIDE(sdx1);
            size_t *index = q[i].idx;
            SDX_SET_INDEX(na2->stridx[j],index);
            q[i].idx = NULL;

            if (stride1<0) {
                size_t  last;
                int k;
                stride1 = -stride1;
                last = na1->base.shape[q[i].orig_dim] - 1;
                if (na2->offset < last * stride1) {
                    rb_raise(rb_eStandardError,"bug: negative offset");
                }
                na2->offset -= last * stride1;
                for (k=0; k<size; k++) {
                    index[k] = (last - index[k]) * stride1;
                }
            } else {
                int k;
                for (k=0; k<size; k++) {
                    index[k] = index[k] * stride1;
                }
            }
        }
        else if (q[i].idx == NULL && SDX_IS_INDEX(sdx1)) {
            // step <- index
            int k;
            size_t beg  = q[i].beg;
            ssize_t step = q[i].step;
            size_t *index = ALLOC_N(size_t, size);
            SDX_SET_INDEX(na2->stridx[j],index);
            for (k=0; k<size; k++) {
                index[k] = SDX_GET_INDEX(sdx1)[beg+step*k];
            }
        }
        else if (q[i].idx == NULL && SDX_IS_STRIDE(sdx1)) {
            // step <- step
            size_t beg  = q[i].beg;
            ssize_t step = q[i].step;
            ssize_t stride1 = SDX_GET_STRIDE(sdx1);
            na2->offset += stride1*beg;
            SDX_SET_STRIDE(na2->stridx[j], stride1*step);
        }

        j++;
        total *= size;
    }
    na2->base.size = total;
}