Matrix $Rev: 2718 $ at $LastChangedDate: 2011-10-06 11:45:17 +0200 (Thu, 06 Oct 2011) $
Mutils.h
Go to the documentation of this file.
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_ */