Matrix  $Rev: 3071 $ at $LastChangedDate: 2015-03-26 15:35:47 +0100 (Thu, 26 Mar 2015) $
t_sparseVector.c
Go to the documentation of this file.
1 /*------ Definition of a template for [dilnz]sparseVector_sub(...) : *
2  * -------- ~~~~~~~~~~~~~~~~~~~~~~
3  * i.e., included several times from ./Mutils.h
4  * ~~~~~~~~
5  */
6 
7 /* for all cases with an 'x' slot -- i.e. almost all cases ;
8  * just redefine this in the other cases:
9  */
10 
11 #ifdef _dspV_
12 
13 # define sparseVector_sub dsparseVector_sub
14 # define _DOUBLE_ans
15 # define _has_x_slot_
16 # undef _dspV_
17 
18 #elif defined (_ispV_)
19 
20 # define sparseVector_sub isparseVector_sub
21 # define _INT_ans
22 # define _has_x_slot_
23 # undef _ispV_
24 
25 #elif defined (_lspV_)
26 
27 # define sparseVector_sub lsparseVector_sub
28 # define _LGL_ans
29 # define _has_x_slot_
30 # undef _lspV_
31 
32 #elif defined (_nspV_)
33 
34 # define sparseVector_sub nsparseVector_sub
35 # define _LGL_ans
36  /* withOUT 'x' slot */
37 # undef _nspV_
38 
39 #elif defined (_zspV_)
40 
41 # define sparseVector_sub zsparseVector_sub
42 # define _CPLX_ans
43 # define _has_x_slot_
44 # undef _zspV_
45 
46 #else
47 
48 # error "no valid _[dilnz]spV_ option"
49 
50 #endif
51 
52 /* - - - - - - - - - - - - - - - - - - - - */
53 
54 #ifdef _DOUBLE_ans
55 
56 # define Type_ans double
57 # define STYP_ans REAL
58 # define NA_ans NA_REAL
59 # define z_ans (0.)
60 # define SXP_ans REALSXP
61 #undef _DOUBLE_ans
62 
63 #elif defined (_INT_ans)
64 
65 # define Type_ans int
66 # define STYP_ans INTEGER
67 # define NA_ans NA_INTEGER
68 # define z_ans (0)
69 # define SXP_ans INTSXP
70 #undef _INT_ans
71 
72 #elif defined (_LGL_ans)
73 
74 # define Type_ans int
75 # define STYP_ans LOGICAL
76 # define NA_ans NA_LOGICAL
77 # define z_ans (0)
78 # define SXP_ans LGLSXP
79 #undef _LGL_ans
80 
81 #elif defined (_CPLX_ans)
82 
83 static Rcomplex cmplx_zero() {
84  Rcomplex z;
85  z.r = z.i = 0.;
86  return z;
87 }
88 #ifdef _using_NA_ans // <-- get rid of "non-used" warning message
89 static Rcomplex cmplx_NA() {
90  Rcomplex z;
91  z.r = z.i = NA_REAL;
92  return z;
93 }
94 #endif
95 
96 # define Type_ans Rcomplex
97 # define STYP_ans COMPLEX
98 # define NA_ans cmplx_NA(); // "FIXME": NA_COMPLEX does not yet exist
99 # define z_ans cmplx_zero();
100 # define SXP_ans CPLXSXP
101 #undef _CPLX_ans
102 
103 #else
104 # error "invalid macro logic"
105 #endif
106 
107 /* - - - - - - - - - - - - - - - - - - - - */
108 
109 #ifdef _has_x_slot_
110 
111 /* currently have x slot always double (cholmod restriction): */
112 # define is_NA_x_(u) ISNAN(u)
113 
114 #endif
115 
116 
117 /* Now the template which depends on the above macros : */
118 
131 static R_INLINE
132 Type_ans sparseVector_sub(int64_t i, int nnz_v, double* v_i, Type_ans* v_x, int64_t len_v)
133 {
134 // double *v_i = INTEGER(GET_SLOT(vec, Matrix_iSym));
135 // double *v_x = REAL (GET_SLOT(vec, Matrix_xSym)); -- try to be agnostic about type
136 // int64_t len_v = (int64_t) asReal(GET_SLOT(vec, Matrix_lengthSym));
137  int64_t i1 = (i % len_v) +1;
138  // NB: Rely on the "validity": the i-slot v_i[] is strictly sorted increasingly
139  for(int j=0; j < nnz_v; j++) {
140  if(i1 > v_i[j])
141  continue;
142  // else: i1 <= v_i[j]
143  if(i1 == v_i[j]) // have a match
144 #ifdef _has_x_slot_
145  return v_x[j];
146 #else
147  return 1;
148 #endif
149  else // no match: the element is zero
150  return z_ans;
151  }
152  return z_ans;
153 }
154 
155 #undef Type_ans
156 #undef STYP_ans
157 #undef NA_ans
158 #undef z_ans
159 #undef SXP_ans
160 
161 
162 #undef _has_x_slot_
163 #undef sparseVector_sub
static R_INLINE Type_ans sparseVector_sub(int64_t i, int nnz_v, double *v_i, Type_ans *v_x, int64_t len_v)
Indexing a sparseVector 'vec', including recycling it (conceptually), i.e.