|
Matrix $Rev: 2718 $ at $LastChangedDate: 2011-10-06 11:45:17 +0200 (Thu, 06 Oct 2011) $
|
00001 #ifndef MATRIX_MUTILS_H 00002 #define MATRIX_MUTILS_H 00003 00004 #undef Matrix_with_SPQR 00005 00006 #ifdef __cplusplus 00007 extern "C" { 00008 #endif 00009 00010 #include <stdint.h> // C99 for int64_t 00011 #include <ctype.h> 00012 #include <R.h> /* includes Rconfig.h */ 00013 #include <Rversion.h> 00014 #include <Rdefines.h> /* Rinternals.h + GET_SLOT etc */ 00015 00016 #ifdef ENABLE_NLS 00017 #include <libintl.h> 00018 #define _(String) dgettext ("Matrix", String) 00019 #else 00020 #define _(String) (String) 00021 /* Note that this is not yet supported (for Windows, e.g.) in R 2.9.0 : */ 00022 #define dngettext(pkg, String, StringP, N) (N > 1 ? StringP : String) 00023 #endif 00024 00025 #ifdef __GNUC__ 00026 # undef alloca 00027 # define alloca(x) __builtin_alloca((x)) 00028 #elif defined(__sun) || defined(_AIX) 00029 /* this is necessary (and sufficient) for Solaris 10 and AIX 6: */ 00030 # include <alloca.h> 00031 #endif 00032 00033 #define Alloca(n, t) (t *) alloca( (size_t) ( (n) * sizeof(t) ) ) 00034 00035 SEXP triangularMatrix_validate(SEXP obj); 00036 SEXP symmetricMatrix_validate(SEXP obj); 00037 SEXP dense_nonpacked_validate(SEXP obj); 00038 00039 /* enum constants from cblas.h and some short forms */ 00040 enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102}; 00041 enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113}; 00042 enum CBLAS_UPLO {CblasUpper=121, CblasLower=122}; 00043 enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132}; 00044 enum CBLAS_SIDE {CblasLeft=141, CblasRight=142}; 00045 #define RMJ CblasRowMajor 00046 #define CMJ CblasColMajor 00047 #define NTR CblasNoTrans 00048 #define TRN CblasTrans 00049 #define CTR CblasConjTrans 00050 #define UPP CblasUpper 00051 #define LOW CblasLower 00052 #define NUN CblasNonUnit 00053 #define UNT CblasUnit 00054 #define LFT CblasLeft 00055 #define RGT CblasRight 00056 00057 double get_double_by_name(SEXP obj, char *nm); 00058 SEXP set_double_by_name(SEXP obj, double val, char *nm); 00059 SEXP as_det_obj(double val, int log, int sign); 00060 SEXP get_factors(SEXP obj, char *nm); 00061 SEXP set_factors(SEXP obj, SEXP val, char *nm); 00062 00063 #if 0 00064 SEXP dgCMatrix_set_Dim(SEXP x, int nrow); 00065 #endif /* unused */ 00066 00067 /* int csc_unsorted_columns(int ncol, const int p[], const int i[]); */ 00068 /* void csc_sort_columns(int ncol, const int p[], int i[], double x[]); */ 00069 /* SEXP csc_check_column_sorting(SEXP A); */ 00070 00071 SEXP check_scalar_string(SEXP sP, char *vals, char *nm); 00072 Rboolean equal_string_vectors(SEXP s1, SEXP s2); 00073 00074 void d_packed_getDiag(double *dest, SEXP x, int n); 00075 void l_packed_getDiag( int *dest, SEXP x, int n); 00076 void tr_d_packed_getDiag(double *dest, SEXP x); 00077 void tr_l_packed_getDiag( int *dest, SEXP x); 00078 00079 SEXP Matrix_getElement(SEXP list, char *nm); 00080 00081 #define PACKED_TO_FULL(TYPE) \ 00082 TYPE *packed_to_full_ ## TYPE(TYPE *dest, const TYPE *src, \ 00083 int n, enum CBLAS_UPLO uplo) 00084 PACKED_TO_FULL(double); 00085 PACKED_TO_FULL(int); 00086 #undef PACKED_TO_FULL 00087 00088 #define FULL_TO_PACKED(TYPE) \ 00089 TYPE *full_to_packed_ ## TYPE(TYPE *dest, const TYPE *src, int n, \ 00090 enum CBLAS_UPLO uplo, enum CBLAS_DIAG diag) 00091 FULL_TO_PACKED(double); 00092 FULL_TO_PACKED(int); 00093 #undef FULL_TO_PACKED 00094 00095 00096 extern /* stored pointers to symbols initialized in R_init_Matrix */ 00097 #include "Syms.h" 00098 00099 /* zero an array */ 00100 #define AZERO(x, n) {int _I_, _SZ_ = (n); for(_I_ = 0; _I_ < _SZ_; _I_++) (x)[_I_] = 0;} 00101 00102 /* number of elements in one triangle of a square matrix of order n */ 00103 #define PACKED_LENGTH(n) ((n) * ((n) + 1))/2 00104 00105 /* duplicate the slot with name given by sym from src to dest */ 00106 00107 #define slot_dup(dest, src, sym) SET_SLOT(dest, sym, duplicate(GET_SLOT(src, sym))) 00108 00109 /* is not yet used: */ 00110 #define slot_nonNull_dup(dest, src, sym) \ 00111 if(GET_SLOT(src, sym) != R_NilValue) \ 00112 SET_SLOT(dest, sym, duplicate(GET_SLOT(src, sym))) 00113 00114 #define slot_dup_if_has(dest, src, sym) \ 00115 if(R_has_slot(src, sym)) \ 00116 SET_SLOT(dest, sym, duplicate(GET_SLOT(src, sym))) 00117 00118 /* TODO: Make this faster for the case where dimnames = list(NULL,NULL) 00119 * and hence don't have to be set ! */ 00120 #define SET_DimNames(dest, src) slot_dup(dest, src, Matrix_DimNamesSym) 00121 00122 00123 #define uplo_P(_x_) CHAR(STRING_ELT(GET_SLOT(_x_, Matrix_uploSym), 0)) 00124 #define diag_P(_x_) CHAR(STRING_ELT(GET_SLOT(_x_, Matrix_diagSym), 0)) 00125 #define class_P(_x_) CHAR(asChar(getAttrib(_x_, R_ClassSymbol))) 00126 00127 // Define this "Cholmod compatible" to some degree 00128 enum x_slot_kind {x_pattern=-1, x_double=0, x_logical=1, x_integer=2, x_complex=3}; 00129 // n d l i z 00130 00131 /* should also work for "matrix" matrices: */ 00132 #define Real_KIND(_x_) (IS_S4_OBJECT(_x_) ? Real_kind(_x_) : \ 00133 (isReal(_x_) ? x_double : (isLogical(_x_) ? x_logical : -1))) 00134 /* This one gives '0' also for integer "matrix" :*/ 00135 #define Real_KIND2(_x_) (IS_S4_OBJECT(_x_) ? Real_kind(_x_) : \ 00136 (isLogical(_x_) ? x_logical : 0)) 00137 00138 /* requires 'x' slot: */ 00139 #define Real_kind(_x_) (isReal(GET_SLOT(_x_, Matrix_xSym)) ? 0 : \ 00140 (isLogical(GET_SLOT(_x_, Matrix_xSym)) ? 1 : -1)) 00141 00142 #define DECLARE_AND_GET_X_SLOT(__C_TYPE, __SEXP) \ 00143 __C_TYPE *xx = __SEXP(GET_SLOT(x, Matrix_xSym)) 00144 00145 00154 static R_INLINE 00155 int packed_ncol(int len) 00156 { 00157 int disc = 8 * len + 1; /* discriminant */ 00158 int sqrtd = (int) sqrt((double) disc); 00159 00160 if (len < 0 || disc != sqrtd * sqrtd) 00161 error(_("invalid 'len' = %d in packed_ncol")); 00162 return (sqrtd - 1)/2; 00163 } 00164 00183 static R_INLINE 00184 SEXP ALLOC_SLOT(SEXP obj, SEXP nm, SEXPTYPE type, int length) 00185 { 00186 SEXP val = allocVector(type, length); 00187 00188 SET_SLOT(obj, nm, val); 00189 return val; 00190 } 00191 00202 static R_INLINE 00203 int* expand_cmprPt(int ncol, const int mp[], int mj[]) 00204 { 00205 int j; 00206 for (j = 0; j < ncol; j++) { 00207 int j2 = mp[j+1], jj; 00208 for (jj = mp[j]; jj < j2; jj++) mj[jj] = j; 00209 } 00210 return mj; 00211 } 00212 00220 static R_INLINE 00221 Rboolean any_NA_in_x(SEXP obj) 00222 { 00223 double *x = REAL(GET_SLOT(obj, Matrix_xSym)); 00224 int i, n = LENGTH(GET_SLOT(obj, Matrix_xSym)); 00225 for(i=0; i < n; i++) 00226 if(ISNAN(x[i])) return TRUE; 00227 /* else */ 00228 return FALSE; 00229 } 00230 00231 00232 void make_d_matrix_triangular(double *x, SEXP from); 00233 void make_i_matrix_triangular( int *x, SEXP from); 00234 00235 void make_d_matrix_symmetric(double *to, SEXP from); 00236 void make_i_matrix_symmetric( int *to, SEXP from); 00237 00238 SEXP Matrix_expand_pointers(SEXP pP); 00239 00240 SEXP dup_mMatrix_as_dgeMatrix(SEXP A); 00241 SEXP dup_mMatrix_as_geMatrix (SEXP A); 00242 00243 SEXP new_dgeMatrix(int nrow, int ncol); 00244 SEXP m_encodeInd (SEXP ij, SEXP di, SEXP chk_bnds); 00245 SEXP m_encodeInd2(SEXP i, SEXP j, SEXP di, SEXP chk_bnds); 00246 00247 00248 static R_INLINE SEXP 00249 mMatrix_as_dgeMatrix(SEXP A) 00250 { 00251 return strcmp(class_P(A), "dgeMatrix") ? dup_mMatrix_as_dgeMatrix(A) : A; 00252 } 00253 00254 static R_INLINE SEXP 00255 mMatrix_as_geMatrix(SEXP A) 00256 { 00257 return strcmp(class_P(A) + 1, "geMatrix") ? dup_mMatrix_as_geMatrix(A) : A; 00258 } 00259 00260 // Keep centralized --- *and* in sync with ../inst/include/Matrix.h : 00261 #define MATRIX_VALID_dense \ 00262 "dmatrix", "dgeMatrix", \ 00263 "lmatrix", "lgeMatrix", \ 00264 "nmatrix", "ngeMatrix", \ 00265 "zmatrix", "zgeMatrix" 00266 00267 #define MATRIX_VALID_Csparse \ 00268 "dgCMatrix", "dsCMatrix", "dtCMatrix", \ 00269 "lgCMatrix", "lsCMatrix", "ltCMatrix", \ 00270 "ngCMatrix", "nsCMatrix", "ntCMatrix", \ 00271 "zgCMatrix", "zsCMatrix", "ztCMatrix" 00272 00273 #define MATRIX_VALID_Tsparse \ 00274 "dgTMatrix", "dsTMatrix", "dtTMatrix", \ 00275 "lgTMatrix", "lsTMatrix", "ltTMatrix", \ 00276 "ngTMatrix", "nsTMatrix", "ntTMatrix", \ 00277 "zgTMatrix", "zsTMatrix", "ztTMatrix" 00278 00279 #define MATRIX_VALID_Rsparse \ 00280 "dgRMatrix", "dsRMatrix", "dtRMatrix", \ 00281 "lgRMatrix", "lsRMatrix", "ltRMatrix", \ 00282 "ngRMatrix", "nsRMatrix", "ntRMatrix", \ 00283 "zgRMatrix", "zsRMatrix", "ztRMatrix" 00284 00285 #define MATRIX_VALID_CHMfactor "dCHMsuper", "dCHMsimpl", "nCHMsuper", "nCHMsimpl" 00286 00296 static R_INLINE int 00297 Matrix_check_class(char *class, const char **valid) 00298 { 00299 int ans; 00300 for (ans = 0; ; ans++) { 00301 if (!strlen(valid[ans])) return -1; 00302 if (!strcmp(class, valid[ans])) return ans; 00303 } 00304 } 00305 00310 int Matrix_check_class_etc(SEXP x, const char **valid); 00311 #if R_VERSION < R_Version(2, 13, 0) 00312 int Matrix_check_class_and_super(SEXP x, const char **valid, SEXP rho); 00313 #else 00314 # define Matrix_check_class_and_super R_check_class_and_super 00315 #endif 00316 00317 00321 // Type_ans sparseVector_sub(int64_t i, int nnz_v, int* v_i, Type_ans* v_x, int len_v): 00322 00323 /* Define all of 00324 * dsparseVector_sub(....) 00325 * isparseVector_sub(....) 00326 * lsparseVector_sub(....) 00327 * nsparseVector_sub(....) 00328 * zsparseVector_sub(....) 00329 */ 00330 #define _dspV_ 00331 #include "t_sparseVector.c" 00332 00333 #define _ispV_ 00334 #include "t_sparseVector.c" 00335 00336 #define _lspV_ 00337 #include "t_sparseVector.c" 00338 00339 #define _nspV_ 00340 #include "t_sparseVector.c" 00341 00342 #define _zspV_ 00343 #include "t_sparseVector.c" 00344 00345 00346 #ifdef __cplusplus 00347 } 00348 #endif 00349 00350 #endif /* MATRIX_MUTILS_H_ */