Rev 4565 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/*------ Definition of a template for [diln]gCMatrix_colsums(...) : ** -------- ~~~~~~~~~~~~~~~~~~~~~~* i.e., included several times from ./dgCMatrix.c* ~~~~~~~~~~~~~*//* for all cases with an 'x' slot -- i.e. almost all cases ;* just redefine this in the other cases:*/#ifdef _dgC_# define gCMatrix_colSums dgCMatrix_colSums# define _DOUBLE_ans# define _has_x_slot_/*Future? # define _has_x_d_slot_ */# undef _dgC_#elif defined (_igC_)# define gCMatrix_colSums igCMatrix_colSums# define _DOUBLE_ans# define _has_x_slot_/*Future? # define _has_x_d_slot_ */# undef _igC_#elif defined (_lgC_)# define gCMatrix_colSums lgCMatrix_colSums_i# define _INT_ans# define _has_x_slot_/*Future? # define _has_x_l_slot_ */# undef _lgC_#elif defined (_lgC_mn)# define gCMatrix_colSums lgCMatrix_colSums_d# define _DOUBLE_ans# define _has_x_slot_/*Future? # define _has_x_l_slot_ */# undef _lgC_mn#elif defined (_ngC_)# define gCMatrix_colSums ngCMatrix_colSums_i# define _INT_ans/* withOUT 'x' slot */# undef _ngC_#elif defined (_ngC_mn)# define gCMatrix_colSums ngCMatrix_colSums_d# define _DOUBLE_ans/* withOUT 'x' slot */# undef _ngC_mn#elif defined (_zgC_)# error "zgC* not yet implemented"#else# error "no valid _[dilnz]gC_ option"#endif/* - - - - - - - - - - - - - - - - - - - - *//* Most of this is maybe for the future,* when cholmod has integer 'x' slot :*/#ifdef _has_x_d_slot_# define Type_x_ double# define STYP_x_ REAL# define _has_x_slot_# undef _has_x_d_slot_#elif defined (_has_x_i_slot_)# define Type_x_ int# define STYP_x_ INTEGER# define _has_x_slot_# undef _has_x_i_slot_#elif defined (_has_x_l_slot_)# define Type_x_ int# define STYP_x_ LOGICAL# define _has_x_slot_# undef _has_x_l_slot_#endif/* - - - - - - - - - - - - - - - - - - - - */#ifdef _DOUBLE_ans# define SparseResult_class "dsparseVector"# define Type_ans double# define STYP_ans REAL# define NA_ans NA_REAL# define SXP_ans REALSXP# define COERCED(x) (x)#undef _DOUBLE_ans#elif defined (_INT_ans)# define SparseResult_class "isparseVector"# define Type_ans int# define STYP_ans INTEGER# define NA_ans NA_INTEGER# define SXP_ans INTSXP# define COERCED(x) (Type_ans)(x != 0)#undef _INT_ans#else# error "invalid macro logic"#endif/* - - - - - - - - - - - - - - - - - - - - */#ifdef _has_x_slot_/* currently have x slot always double (cholmod restriction): */# define is_NA_x_(u) ISNAN(u)# define ColSUM_column(_i1_,_i2_,_SUM_) \if(mn) dnm = cx->nrow; /* denominator for means */ \for(i = _i1_, _SUM_ = 0; i < _i2_; i++) { \if (is_NA_x_(xx[i])) { \if(!na_rm) { \_SUM_ = NA_ans; \break; \} \/* else: na_rm : skip NAs , */ \if(mn) /* but decrement denominator */ \dnm--; \} else _SUM_ += COERCED(xx[i]); \} \if(mn) _SUM_ = (dnm > 0) ? _SUM_/dnm : NA_ans#else /* no 'x' slot -> no NAs ... */# define ColSUM_column(_i1_,_i2_,_SUM_) \_SUM_ = _i2_ - _i1_; \if(mn) _SUM_ /= cx->nrow#endif/* Now the template which depends on the above macros : */SEXP gCMatrix_colSums(SEXP x, SEXP NArm, SEXP spRes, SEXP trans, SEXP means){int mn = asLogical(means), sp = asLogical(spRes), tr = asLogical(trans);/* cholmod_sparse: drawback of coercing lgC to double: */CHM_SP cx = AS_CHM_SP(x);R_CheckStack();if (tr) {cholmod_sparse *cxt = cholmod_transpose(cx, (int)cx->xtype, &c);cx = cxt;}/* everything else *after* the above potential transpose : *//* Don't declarations here require the C99 standard? Can we assume C99? */int j, nc = cx->ncol;int *xp = (int *)(cx -> p);#ifdef _has_x_slot_int na_rm = asLogical(NArm), i, dnm = 0/*Wall*/;double *xx = (double *)(cx -> x);#endifSEXP ans = PROTECT(sp ? NEW_OBJECT(MAKE_CLASS(SparseResult_class)): allocVector(SXP_ans, nc));if (sp) { /* sparseResult - never allocating length-nc ... */int nza, i1, i2, p, *ai;Type_ans *ax;for (j = 0, nza = 0; j < nc; j++)if(xp[j] < xp[j + 1])nza++;ai = INTEGER(ALLOC_SLOT(ans, Matrix_iSym, INTSXP, nza));ax = STYP_ans(ALLOC_SLOT(ans, Matrix_xSym, SXP_ans, nza));SET_SLOT(ans, Matrix_lengthSym, ScalarInteger(nc));i2 = xp[0];for (j = 1, p = 0; j <= nc; j++) {/* j' =j+1, since 'i' slot will be 1-based */i1 = i2; i2 = xp[j];if(i1 < i2) {Type_ans sum;ColSUM_column(i1,i2, sum);ai[p] = j;ax[p++] = sum;}}}else { /* "numeric" (non sparse) result */Type_ans *a = STYP_ans(ans);for (j = 0; j < nc; j++) {ColSUM_column(xp[j], xp[j + 1], a[j]);}}if (tr) cholmod_free_sparse(&cx, &c);UNPROTECT(1);return ans;}#undef ColSUM_column#undef NA_ans#undef STYP_ans#undef SXP_ans#undef SparseResult_class#undef Type_ans#undef COERCED#ifdef _has_x_slot_# undef NA_x_# undef Type_x_# undef STYP_x_# undef _has_x_slot_#endif#undef gCMatrix_colSums