Esempio n. 1
0
VALUE
na_reduce_dimension(int argc, VALUE *argv, int naryc, VALUE *naryv)
{
    int ndim, ndim0;
    int row_major;
    int i, r;
    size_t j;
    size_t len;
    ssize_t beg, step;
    VALUE v;
    narray_t *na;
    size_t m;
    VALUE reduce;

    if (naryc<1) {
        rb_raise(rb_eRuntimeError,"must be positive: naryc=%d", naryc);
    }
    GetNArray(naryv[0],na);
    reduce = na->reduce;
    if (argc==0) {
        //printf("pass argc=0 reduce=%d\n",NUM2INT(reduce));
        return reduce;
    }
    ndim = ndim0 = na->ndim;
    row_major = TEST_COLUMN_MAJOR(naryv[0]);
    for (i=1; i<naryc; i++) {
        GetNArray(naryv[i],na);
        if (TEST_COLUMN_MAJOR(naryv[i]) != row_major) {
            rb_raise(nary_eDimensionError,"dimension order is different");
        }
        if (na->ndim > ndim) {
            ndim = na->ndim;
        }
    }
    if (ndim != ndim0) {
        j = FIX2ULONG(reduce) << (ndim-ndim0);
        reduce = ULONG2NUM(j);
        if (!FIXNUM_P(reduce)) {
            rb_raise(nary_eDimensionError,"reduce has too many bits");
        }
    }
    //printf("argc=%d\n",argc);

    m = 0;
    reduce = Qnil;
    for (i=0; i<argc; i++) {
        v = argv[i];
        //printf("argv[%d]=",i);rb_p(v);
        if (TYPE(v)==T_FIXNUM) {
            beg = FIX2INT(v);
            if (beg<0) beg+=ndim;
            if (beg>=ndim || beg<0) {
                rb_raise(nary_eDimensionError,"dimension is out of range");
            }
            len = 1;
            step = 0;
            //printf("beg=%d step=%d len=%d\n",beg,step,len);
        } else if (rb_obj_is_kind_of(v,rb_cRange) ||
                   rb_obj_is_kind_of(v,na_cStep)) {
            nary_step_array_index( v, ndim, &len, &beg, &step );
        } else {
            rb_raise(nary_eDimensionError, "invalid dimension argument %s",
                     rb_obj_classname(v));
        }
        for (j=0; j<len; j++) {
            r = beg + step*j;
            if (row_major)
                r = ndim-1-r;
            if (reduce==Qnil) {
              if ( r < (ssize_t)sizeof(size_t) ) {
                    m |= ((size_t)1) << r;
                    continue;
                } else {
                    reduce = SIZE2NUM(m);
                }
            }
            v = rb_funcall( INT2FIX(1), rb_intern("<<"), 1, INT2FIX(r) );
            reduce = rb_funcall( reduce, rb_intern("|"), 1, v );
        }
    }
    if (reduce==Qnil) reduce = SIZE2NUM(m);
    return reduce;
}
Esempio n. 2
0
File: index.c Progetto: kou/narray
// Analyze *a* which is *i*-th index object and store the information to q
//
// a: a ruby object of i-th index
// size: size of i-th dimension of original NArray
// i: parse i-th index
// q: parsed information is stored to *q
static void
na_index_parse_each(volatile VALUE a, ssize_t size, int i, na_index_arg_t *q)
{
    switch(TYPE(a)) {

    case T_FIXNUM:
        na_index_set_scalar(q,i,size,FIX2LONG(a));
        break;

    case T_BIGNUM:
        na_index_set_scalar(q,i,size,NUM2SSIZET(a));
        break;

    case T_FLOAT:
        na_index_set_scalar(q,i,size,NUM2SSIZET(a));
        break;

    case T_NIL:
    case T_TRUE:
        na_index_set_step(q,i,size,0,1);
        break;

    case T_SYMBOL:
        if (a==sym_all || a==sym_ast) {
            na_index_set_step(q,i,size,0,1);
        }
        else if (a==sym_reverse) {
            na_index_set_step(q,i,size,size-1,-1);
        }
        else if (a==sym_new) {
            na_index_set_step(q,i,1,0,1);
        }
        else if (a==sym_reduce || a==sym_sum || a==sym_plus) {
            na_index_set_step(q,i,size,0,1);
            q->reduce = 1;
        } else {
            rb_raise(rb_eIndexError, "invalid symbol for index");
        }
        break;

    case T_ARRAY:
        na_parse_array(a, i, size, q);
        break;

    default:
        if (rb_obj_is_kind_of(a, rb_cRange)) {
            na_parse_range(a, 1, i, size, q);
        }
        else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
            na_parse_enumerator(a, i, size, q);
        }
        else if (rb_obj_is_kind_of(a, na_cStep)) {
            ssize_t beg, step, n;
            nary_step_array_index(a, size, (size_t*)(&n), &beg, &step);
            na_index_set_step(q,i,n,beg,step);
        }
        // NArray index
        else if (NA_IsNArray(a)) {
            na_parse_narray_index(a, i, size, q);
        }
        else {
            rb_raise(rb_eIndexError, "not allowed type");
        }
    }
}