The R Project SVN R-packages

Rev

Rev 4529 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4529 Rev 4530
Line 37... Line 37...
37
		else if (xi[k] == xi[k - 1])
37
		else if (xi[k] == xi[k - 1])
38
		    strictly = FALSE;
38
		    strictly = FALSE;
39
	    }
39
	    }
40
    }
40
    }
41
    if (!sorted) {
41
    if (!sorted) {
42
	cholmod_sparse *chx = as_cholmod_sparse(x);
42
	CHM_SP chx = AS_CHM_SP(x);
-
 
43
 
43
	cholmod_sort(chx, &c);
44
	cholmod_sort(chx, &c);
44
	Free(chx);
-
 
45
	/* Now re-check that row indices are *strictly* increasing
45
	/* Now re-check that row indices are *strictly* increasing
46
	 * (and not just increasing) within each column : */
46
	 * (and not just increasing) within each column : */
47
	for (j = 0; j < ncol; j++) {
47
	for (j = 0; j < ncol; j++) {
48
	    for (k = xp[j] + 1; k < xp[j + 1]; k++)
48
	    for (k = xp[j] + 1; k < xp[j + 1]; k++)
49
		if (xi[k] == xi[k - 1])
49
		if (xi[k] == xi[k - 1])
Line 59... Line 59...
59
/* Called from ../R/Csparse.R : */
59
/* Called from ../R/Csparse.R : */
60
/* Can only return [dln]geMatrix (no symm/triang);
60
/* Can only return [dln]geMatrix (no symm/triang);
61
 * FIXME: replace by non-CHOLMOD code ! */
61
 * FIXME: replace by non-CHOLMOD code ! */
62
SEXP Csparse_to_dense(SEXP x)
62
SEXP Csparse_to_dense(SEXP x)
63
{
63
{
64
    cholmod_sparse *chxs = as_cholmod_sparse(x);
64
    CHM_SP chxs = AS_CHM_SP(x);
65
    /* This loses the symmetry property, since cholmod_dense has none,
65
    /* This loses the symmetry property, since cholmod_dense has none,
66
     * BUT, much worse (FIXME!), it also transforms CHOLMOD_PATTERN ("n") matrices
66
     * BUT, much worse (FIXME!), it also transforms CHOLMOD_PATTERN ("n") matrices
67
     * to numeric (CHOLMOD_REAL) ones : */
67
     * to numeric (CHOLMOD_REAL) ones : */
68
    cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c);
68
    CHM_DN chxd = cholmod_sparse_to_dense(chxs, &c);
69
    int Rkind = (chxs->xtype == CHOLMOD_PATTERN)? -1 : Real_kind(x);
69
    int Rkind = (chxs->xtype == CHOLMOD_PATTERN)? -1 : Real_kind(x);
70
 
70
 
71
    Free(chxs);
-
 
72
    return chm_dense_to_SEXP(chxd, 1, Rkind, GET_SLOT(x, Matrix_DimNamesSym));
71
    return chm_dense_to_SEXP(chxd, 1, Rkind, GET_SLOT(x, Matrix_DimNamesSym));
73
}
72
}
74
 
73
 
75
SEXP Csparse_to_nz_pattern(SEXP x, SEXP tri)
74
SEXP Csparse_to_nz_pattern(SEXP x, SEXP tri)
76
{
75
{
77
    cholmod_sparse *chxs = as_cholmod_sparse(x);
76
    CHM_SP chxs = AS_CHM_SP(x);
78
    cholmod_sparse
-
 
79
	*chxcp = cholmod_copy(chxs, chxs->stype, CHOLMOD_PATTERN, &c);
77
    CHM_SP chxcp = cholmod_copy(chxs, chxs->stype, CHOLMOD_PATTERN, &c);
80
    int tr = asLogical(tri);
78
    int tr = asLogical(tri);
81
 
79
 
82
    Free(chxs);
-
 
83
    return chm_sparse_to_SEXP(chxcp, 1,
80
    return chm_sparse_to_SEXP(chxcp, 1/*do_free*/,
84
			      tr ? ((*uplo_P(x) == 'U') ? 1 : -1) : 0,
81
			      tr ? ((*uplo_P(x) == 'U') ? 1 : -1) : 0,
85
			      0, tr ? diag_P(x) : "",
82
			      0, tr ? diag_P(x) : "",
86
			      GET_SLOT(x, Matrix_DimNamesSym));
83
			      GET_SLOT(x, Matrix_DimNamesSym));
87
}
84
}
88
 
85
 
89
SEXP Csparse_to_matrix(SEXP x)
86
SEXP Csparse_to_matrix(SEXP x)
90
{
87
{
91
    cholmod_sparse *chxs = as_cholmod_sparse(x);
-
 
92
    cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c);
88
    return chm_dense_to_matrix(cholmod_sparse_to_dense(AS_CHM_SP(x), &c),
93
 
-
 
94
    Free(chxs);
-
 
95
    return chm_dense_to_matrix(chxd, 1,
-
 
96
			       GET_SLOT(x, Matrix_DimNamesSym));
89
			       1 /*do_free*/, GET_SLOT(x, Matrix_DimNamesSym));
97
}
90
}
98
 
91
 
99
SEXP Csparse_to_Tsparse(SEXP x, SEXP tri)
92
SEXP Csparse_to_Tsparse(SEXP x, SEXP tri)
100
{
93
{
101
    cholmod_sparse *chxs = as_cholmod_sparse(x);
94
    CHM_SP chxs = AS_CHM_SP(x);
102
    cholmod_triplet *chxt = cholmod_sparse_to_triplet(chxs, &c);
95
    CHM_TR chxt = cholmod_sparse_to_triplet(chxs, &c);
103
    int tr = asLogical(tri);
96
    int tr = asLogical(tri);
104
    int Rkind = (chxs->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
97
    int Rkind = (chxs->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
105
 
98
 
106
    Free(chxs);
-
 
107
    return chm_triplet_to_SEXP(chxt, 1,
99
    return chm_triplet_to_SEXP(chxt, 1,
108
			       tr ? ((*uplo_P(x) == 'U') ? 1 : -1) : 0,
100
			       tr ? ((*uplo_P(x) == 'U') ? 1 : -1) : 0,
109
			       Rkind, tr ? diag_P(x) : "",
101
			       Rkind, tr ? diag_P(x) : "",
110
			       GET_SLOT(x, Matrix_DimNamesSym));
102
			       GET_SLOT(x, Matrix_DimNamesSym));
111
}
103
}
112
 
104
 
113
/* this used to be called  sCMatrix_to_gCMatrix(..)   [in ./dsCMatrix.c ]: */
105
/* this used to be called  sCMatrix_to_gCMatrix(..)   [in ./dsCMatrix.c ]: */
114
SEXP Csparse_symmetric_to_general(SEXP x)
106
SEXP Csparse_symmetric_to_general(SEXP x)
115
{
107
{
116
    cholmod_sparse *chx = as_cholmod_sparse(x), *chgx;
108
    CHM_SP chx = AS_CHM_SP(x), chgx;
117
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
109
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
118
 
110
 
119
    if (!(chx->stype))
111
    if (!(chx->stype))
120
	error(_("Nonsymmetric matrix in Csparse_symmetric_to_general"));
112
	error(_("Nonsymmetric matrix in Csparse_symmetric_to_general"));
121
    chgx = cholmod_copy(chx, /* stype: */ 0, chx->xtype, &c);
113
    chgx = cholmod_copy(chx, /* stype: */ 0, chx->xtype, &c);
122
    /* xtype: pattern, "real", complex or .. */
114
    /* xtype: pattern, "real", complex or .. */
123
    Free(chx);
-
 
124
    return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "",
115
    return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "",
125
			      GET_SLOT(x, Matrix_DimNamesSym));
116
			      GET_SLOT(x, Matrix_DimNamesSym));
126
}
117
}
127
 
118
 
128
SEXP Csparse_general_to_symmetric(SEXP x, SEXP uplo)
119
SEXP Csparse_general_to_symmetric(SEXP x, SEXP uplo)
129
{
120
{
130
    cholmod_sparse *chx = as_cholmod_sparse(x), *chgx;
121
    CHM_SP chx = AS_CHM_SP(x), chgx;
131
    int uploT = (*CHAR(asChar(uplo)) == 'U') ? 1 : -1;
122
    int uploT = (*CHAR(asChar(uplo)) == 'U') ? 1 : -1;
132
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
123
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
133
 
124
 
134
    chgx = cholmod_copy(chx, /* stype: */ uploT, chx->xtype, &c);
125
    chgx = cholmod_copy(chx, /* stype: */ uploT, chx->xtype, &c);
135
    /* xtype: pattern, "real", complex or .. */
126
    /* xtype: pattern, "real", complex or .. */
136
    Free(chx);
-
 
137
    return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "",
127
    return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "",
138
			      GET_SLOT(x, Matrix_DimNamesSym));
128
			      GET_SLOT(x, Matrix_DimNamesSym));
139
}
129
}
140
 
130
 
141
SEXP Csparse_transpose(SEXP x, SEXP tri)
131
SEXP Csparse_transpose(SEXP x, SEXP tri)
142
{
132
{
143
    /* TODO: lgCMatrix & igC* currently go via double prec. cholmod -
133
    /* TODO: lgCMatrix & igC* currently go via double prec. cholmod -
144
     *       since cholmod (& cs) lacks sparse 'int' matrices */
134
     *       since cholmod (& cs) lacks sparse 'int' matrices */
145
    cholmod_sparse *chx = as_cholmod_sparse(x);
135
    CHM_SP chx = AS_CHM_SP(x);
146
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
136
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
147
    cholmod_sparse *chxt = cholmod_transpose(chx, (int) chx->xtype, &c);
137
    CHM_SP chxt = cholmod_transpose(chx, chx->xtype, &c);
148
    SEXP dn = PROTECT(duplicate(GET_SLOT(x, Matrix_DimNamesSym))), tmp;
138
    SEXP dn = PROTECT(duplicate(GET_SLOT(x, Matrix_DimNamesSym))), tmp;
149
    int tr = asLogical(tri);
139
    int tr = asLogical(tri);
150
 
140
 
151
    Free(chx);
-
 
152
    tmp = VECTOR_ELT(dn, 0);	/* swap the dimnames */
141
    tmp = VECTOR_ELT(dn, 0);	/* swap the dimnames */
153
    SET_VECTOR_ELT(dn, 0, VECTOR_ELT(dn, 1));
142
    SET_VECTOR_ELT(dn, 0, VECTOR_ELT(dn, 1));
154
    SET_VECTOR_ELT(dn, 1, tmp);
143
    SET_VECTOR_ELT(dn, 1, tmp);
155
    UNPROTECT(1);
144
    UNPROTECT(1);
156
    return chm_sparse_to_SEXP(chxt, 1, /* SWAP 'uplo' for triangular */
145
    return chm_sparse_to_SEXP(chxt, 1, /* SWAP 'uplo' for triangular */
Line 158... Line 147...
158
			      Rkind, tr ? diag_P(x) : "", dn);
147
			      Rkind, tr ? diag_P(x) : "", dn);
159
}
148
}
160
 
149
 
161
SEXP Csparse_Csparse_prod(SEXP a, SEXP b)
150
SEXP Csparse_Csparse_prod(SEXP a, SEXP b)
162
{
151
{
163
    cholmod_sparse
-
 
164
	*cha = as_cholmod_sparse(a),
-
 
165
	*chb = as_cholmod_sparse(b);
152
    CHM_SP cha = AS_CHM_SP(a), chb = AS_CHM_SP(b);
166
    cholmod_sparse *chc = cholmod_ssmult(cha, chb, 0, cha->xtype, 1, &c);
153
    CHM_SP chc = cholmod_ssmult(cha, chb, 0, cha->xtype, 1, &c);
167
    SEXP dn = allocVector(VECSXP, 2);
154
    SEXP dn = allocVector(VECSXP, 2);
168
 
155
 
169
    Free(cha); Free(chb);
-
 
170
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
156
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
171
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0)));
157
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0)));
172
    SET_VECTOR_ELT(dn, 1,
158
    SET_VECTOR_ELT(dn, 1,
173
		   duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1)));
159
		   duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1)));
174
    return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn);
160
    return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn);
175
}
161
}
176
 
162
 
177
SEXP Csparse_Csparse_crossprod(SEXP a, SEXP b, SEXP trans)
163
SEXP Csparse_Csparse_crossprod(SEXP a, SEXP b, SEXP trans)
178
{
164
{
179
    int tr = asLogical(trans);
165
    int tr = asLogical(trans);
180
    cholmod_sparse
-
 
181
	*cha = as_cholmod_sparse(a),
-
 
182
	*chb = as_cholmod_sparse(b);
-
 
183
    cholmod_sparse *chTr, *chc;
166
    CHM_SP cha = AS_CHM_SP(a), chb = AS_CHM_SP(b), chTr, chc;
184
    SEXP dn = allocVector(VECSXP, 2);
167
    SEXP dn = allocVector(VECSXP, 2);
185
 
168
 
186
/*     cholmod_sparse *chTr = cholmod_transpose(cha, 1, &c); */
-
 
187
/*     cholmod_sparse *chc = cholmod_ssmult(chTr, chb, 0, cha->xtype, 1, &c); */
-
 
188
 
-
 
189
    if (tr)
-
 
190
	chTr = cholmod_transpose(chb, chb->xtype, &c);
169
    chTr = cholmod_transpose((tr) ? chb : cha, chb->xtype, &c);
191
    else
-
 
192
	chTr = cholmod_transpose(cha, cha->xtype, &c);
-
 
193
    chc = cholmod_ssmult((tr) ? cha : chTr, (tr) ? chTr : chb,
170
    chc = cholmod_ssmult((tr) ? cha : chTr, (tr) ? chTr : chb,
194
			 0, cha->xtype, 1, &c);
171
			 0, cha->xtype, 1, &c);
195
 
-
 
196
    Free(cha); Free(chb); cholmod_free_sparse(&chTr, &c);
172
    cholmod_free_sparse(&chTr, &c);
197
 
173
 
198
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
174
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
199
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), (tr) ? 0 : 1)));
175
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), (tr) ? 0 : 1)));
200
    SET_VECTOR_ELT(dn, 1,
176
    SET_VECTOR_ELT(dn, 1,
201
		   duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), (tr) ? 0 : 1)));
177
		   duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), (tr) ? 0 : 1)));
202
    return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn);
178
    return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn);
203
}
179
}
204
 
180
 
205
SEXP Csparse_dense_prod(SEXP a, SEXP b)
181
SEXP Csparse_dense_prod(SEXP a, SEXP b)
206
{
182
{
207
    cholmod_sparse *cha = as_cholmod_sparse(a);
183
    CHM_SP cha = AS_CHM_SP(a);
208
    SEXP b_M = PROTECT(mMatrix_as_dgeMatrix(b));
184
    SEXP b_M = PROTECT(mMatrix_as_dgeMatrix(b));
209
    cholmod_dense *chb = as_cholmod_dense(b_M);
185
    CHM_DN chb = AS_CHM_DN(b_M);
210
    cholmod_dense *chc =
-
 
211
	cholmod_allocate_dense(cha->nrow, chb->ncol, cha->nrow, chb->xtype, &c);
186
    CHM_DN chc = cholmod_allocate_dense(cha->nrow, chb->ncol, cha->nrow,
-
 
187
					chb->xtype, &c);
212
    SEXP dn = allocVector(VECSXP, 2);
188
    SEXP dn = PROTECT(allocVector(VECSXP, 2));
213
    double alpha[] = {1,0}, beta[] = {0,0};
189
    double one[] = {1,0}, zero[] = {0,0};
214
 
190
 
215
    cholmod_sdmult(cha, 0, alpha, beta, chb, chc, &c);
191
    cholmod_sdmult(cha, 0, one, zero, chb, chc, &c);
216
    Free(cha); Free(chb);
-
 
217
    UNPROTECT(1);
-
 
218
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
192
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
219
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0)));
193
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0)));
220
    SET_VECTOR_ELT(dn, 1,
194
    SET_VECTOR_ELT(dn, 1,
221
		   duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1)));
195
		   duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1)));
-
 
196
    UNPROTECT(2);
222
    return chm_dense_to_SEXP(chc, 1, 0, dn);
197
    return chm_dense_to_SEXP(chc, 1, 0, dn);
223
}
198
}
224
 
199
 
225
SEXP Csparse_dense_crossprod(SEXP a, SEXP b)
200
SEXP Csparse_dense_crossprod(SEXP a, SEXP b)
226
{
201
{
227
    cholmod_sparse *cha = as_cholmod_sparse(a);
202
    CHM_SP cha = AS_CHM_SP(a);
228
    SEXP b_M = PROTECT(mMatrix_as_dgeMatrix(b));
203
    SEXP b_M = PROTECT(mMatrix_as_dgeMatrix(b));
229
    cholmod_dense *chb = as_cholmod_dense(b_M);
204
    CHM_DN chb = AS_CHM_DN(b_M);
230
    cholmod_dense *chc =
-
 
231
	cholmod_allocate_dense(cha->ncol, chb->ncol, cha->ncol, chb->xtype, &c);
205
    CHM_DN chc = cholmod_allocate_dense(cha->ncol, chb->ncol, cha->ncol,
-
 
206
					chb->xtype, &c);
232
    SEXP dn = allocVector(VECSXP, 2);
207
    SEXP dn = PROTECT(allocVector(VECSXP, 2));
233
    double alpha[] = {1,0}, beta[] = {0,0};
208
    double one[] = {1,0}, zero[] = {0,0};
234
 
209
 
235
    cholmod_sdmult(cha, 1, alpha, beta, chb, chc, &c);
210
    cholmod_sdmult(cha, 1, one, zero, chb, chc, &c);
236
    Free(cha); Free(chb);
-
 
237
    UNPROTECT(1);
-
 
238
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
211
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
239
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 1)));
212
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 1)));
240
    SET_VECTOR_ELT(dn, 1,
213
    SET_VECTOR_ELT(dn, 1,
241
		   duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1)));
214
		   duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1)));
-
 
215
    UNPROTECT(2);
242
    return chm_dense_to_SEXP(chc, 1, 0, dn);
216
    return chm_dense_to_SEXP(chc, 1, 0, dn);
243
}
217
}
244
 
218
 
245
/* Computes   x'x  or  x x'  -- see Csparse_Csparse_crossprod above for  x'y and x y' */
219
/* Computes   x'x  or  x x'  -- see Csparse_Csparse_crossprod above for  x'y and x y' */
246
SEXP Csparse_crossprod(SEXP x, SEXP trans, SEXP triplet)
220
SEXP Csparse_crossprod(SEXP x, SEXP trans, SEXP triplet)
247
{
221
{
248
    int trip = asLogical(triplet),
222
    int trip = asLogical(triplet),
249
	tr   = asLogical(trans); /* gets reversed because _aat is tcrossprod */
223
	tr   = asLogical(trans); /* gets reversed because _aat is tcrossprod */
250
    cholmod_triplet
-
 
251
	*cht = trip ? as_cholmod_triplet(x) : (cholmod_triplet*) NULL;
224
    CHM_TR cht = trip ? AS_CHM_TR(x) : (CHM_TR) NULL;
252
    cholmod_sparse *chcp, *chxt,
225
    CHM_SP chcp, chxt,
253
	*chx = trip ? cholmod_triplet_to_sparse(cht, cht->nnz, &c)
226
	chx = trip ? cholmod_triplet_to_sparse(cht, cht->nnz, &c) : AS_CHM_SP(x);
254
	: as_cholmod_sparse(x);
-
 
255
    SEXP dn = PROTECT(allocVector(VECSXP, 2));
227
    SEXP dn = PROTECT(allocVector(VECSXP, 2));
256
 
228
 
257
    if (!tr)
-
 
258
	chxt = cholmod_transpose(chx, chx->xtype, &c);
229
    if (!tr) chxt = cholmod_transpose(chx, chx->xtype, &c);
259
    chcp = cholmod_aat((!tr) ? chxt : chx, (int *) NULL, 0, chx->xtype, &c);
230
    chcp = cholmod_aat((!tr) ? chxt : chx, (int *) NULL, 0, chx->xtype, &c);
260
    if(!chcp)
-
 
261
	error(_("Csparse_crossprod(): error return from cholmod_aat()"));
231
    if(!chcp) error(_("Csparse_crossprod(): error return from cholmod_aat()"));
262
    cholmod_band_inplace(0, chcp->ncol, chcp->xtype, chcp, &c);
232
    cholmod_band_inplace(0, chcp->ncol, chcp->xtype, chcp, &c);
263
    chcp->stype = 1;
233
    chcp->stype = 1;
264
    if (trip) {
-
 
265
	cholmod_free_sparse(&chx, &c);
234
    if (trip) cholmod_free_sparse(&chx, &c);
266
	Free(cht);
-
 
267
    } else {
-
 
268
	Free(chx);
-
 
269
    }
-
 
270
    if (!tr) cholmod_free_sparse(&chxt, &c);
235
    if (!tr) cholmod_free_sparse(&chxt, &c);
271
				/* create dimnames */
-
 
272
    SET_VECTOR_ELT(dn, 0,
236
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
273
		   duplicate(VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym),
237
		   duplicate(VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym),
274
					(tr) ? 0 : 1)));
238
					(tr) ? 0 : 1)));
275
    SET_VECTOR_ELT(dn, 1, duplicate(VECTOR_ELT(dn, 0)));
239
    SET_VECTOR_ELT(dn, 1, duplicate(VECTOR_ELT(dn, 0)));
276
    UNPROTECT(1);
240
    UNPROTECT(1);
277
    return chm_sparse_to_SEXP(chcp, 1, 0, 0, "", dn);
241
    return chm_sparse_to_SEXP(chcp, 1, 0, 0, "", dn);
278
}
242
}
279
 
243
 
280
SEXP Csparse_drop(SEXP x, SEXP tol)
244
SEXP Csparse_drop(SEXP x, SEXP tol)
281
{
245
{
282
    cholmod_sparse *chx = as_cholmod_sparse(x),
246
    CHM_SP chx = AS_CHM_SP(x);
283
	*ans = cholmod_copy(chx, chx->stype, chx->xtype, &c);
247
    CHM_SP ans = cholmod_copy(chx, chx->stype, chx->xtype, &c);
284
    double dtol = asReal(tol);
248
    double dtol = asReal(tol);
285
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
249
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
286
 
250
 
287
    if(!cholmod_drop(dtol, ans, &c))
251
    if(!cholmod_drop(dtol, ans, &c))
288
	error(_("cholmod_drop() failed"));
252
	error(_("cholmod_drop() failed"));
289
    Free(chx);
-
 
290
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "",
253
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "",
291
			      GET_SLOT(x, Matrix_DimNamesSym));
254
			      GET_SLOT(x, Matrix_DimNamesSym));
292
}
255
}
293
 
256
 
294
 
-
 
295
SEXP Csparse_horzcat(SEXP x, SEXP y)
257
SEXP Csparse_horzcat(SEXP x, SEXP y)
296
{
258
{
297
    cholmod_sparse *chx = as_cholmod_sparse(x),
259
    CHM_SP chx = AS_CHM_SP(x), chy = AS_CHM_SP(y);
298
	*chy = as_cholmod_sparse(y), *ans;
-
 
299
    int Rkind = 0; /* only for "d" - FIXME */
260
    int Rkind = 0; /* only for "d" - FIXME */
300
 
261
 
301
    ans = cholmod_horzcat(chx, chy, 1, &c);
-
 
302
    Free(chx); Free(chy);
-
 
303
    /* FIXME: currently drops dimnames */
262
    /* FIXME: currently drops dimnames */
304
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue);
263
    return chm_sparse_to_SEXP(cholmod_horzcat(chx, chy, 1, &c),
-
 
264
			      1, 0, Rkind, "", R_NilValue);
305
}
265
}
306
 
266
 
307
SEXP Csparse_vertcat(SEXP x, SEXP y)
267
SEXP Csparse_vertcat(SEXP x, SEXP y)
308
{
268
{
309
    cholmod_sparse *chx = as_cholmod_sparse(x),
269
    CHM_SP chx = AS_CHM_SP(x), chy = AS_CHM_SP(y);
310
	*chy = as_cholmod_sparse(y), *ans;
-
 
311
    int Rkind = 0; /* only for "d" - FIXME */
270
    int Rkind = 0; /* only for "d" - FIXME */
312
 
271
 
313
    ans = cholmod_vertcat(chx, chy, 1, &c);
-
 
314
    Free(chx); Free(chy);
-
 
315
    /* FIXME: currently drops dimnames */
272
    /* FIXME: currently drops dimnames */
316
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue);
273
    return chm_sparse_to_SEXP(cholmod_vertcat(chx, chy, 1, &c),
-
 
274
			      1, 0, Rkind, "", R_NilValue);
317
}
275
}
318
 
276
 
319
SEXP Csparse_band(SEXP x, SEXP k1, SEXP k2)
277
SEXP Csparse_band(SEXP x, SEXP k1, SEXP k2)
320
{
278
{
321
    cholmod_sparse *chx = as_cholmod_sparse(x), *ans;
279
    CHM_SP chx = AS_CHM_SP(x);
322
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
280
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
-
 
281
    CHM_SP ans = cholmod_band(chx, asInteger(k1), asInteger(k2), chx->xtype, &c);
323
 
282
 
324
    ans = cholmod_band(chx, asInteger(k1), asInteger(k2), chx->xtype, &c);
-
 
325
    Free(chx);
-
 
326
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "",
283
    return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "",
327
			      GET_SLOT(x, Matrix_DimNamesSym));
284
			      GET_SLOT(x, Matrix_DimNamesSym));
328
}
285
}
329
 
286
 
330
SEXP Csparse_diagU2N(SEXP x)
287
SEXP Csparse_diagU2N(SEXP x)
331
{
288
{
332
    if (*diag_P(x) != 'U') {/* "trivially fast" when there's no 'diag' slot at all */
289
    if (*diag_P(x) != 'U') {/* "trivially fast" when there's no 'diag' slot at all */
333
	return (x);
290
	return (x);
334
    }
291
    }
335
    else {
292
    else {
336
	cholmod_sparse *chx = as_cholmod_sparse(x);
293
	CHM_SP chx = AS_CHM_SP(x);
337
	cholmod_sparse *eye = cholmod_speye(chx->nrow, chx->ncol, chx->xtype, &c);
294
	CHM_SP eye = cholmod_speye(chx->nrow, chx->ncol, chx->xtype, &c);
338
	double one[] = {1, 0};
295
	double one[] = {1, 0};
339
	cholmod_sparse *ans = cholmod_add(chx, eye, one, one, TRUE, TRUE, &c);
296
	CHM_SP ans = cholmod_add(chx, eye, one, one, TRUE, TRUE, &c);
340
	int uploT = (*uplo_P(x) == 'U') ? 1 : -1;
297
	int uploT = (*uplo_P(x) == 'U') ? 1 : -1;
341
	int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
298
	int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
342
 
299
 
343
	Free(chx); cholmod_free_sparse(&eye, &c);
300
	cholmod_free_sparse(&eye, &c);
344
	return chm_sparse_to_SEXP(ans, 1, uploT, Rkind, "N",
301
	return chm_sparse_to_SEXP(ans, 1, uploT, Rkind, "N",
345
				  GET_SLOT(x, Matrix_DimNamesSym));
302
				  GET_SLOT(x, Matrix_DimNamesSym));
346
    }
303
    }
347
}
304
}
348
 
305
 
349
SEXP Csparse_submatrix(SEXP x, SEXP i, SEXP j)
306
SEXP Csparse_submatrix(SEXP x, SEXP i, SEXP j)
350
{
307
{
351
    cholmod_sparse *chx = as_cholmod_sparse(x);
308
    CHM_SP chx = AS_CHM_SP(x);
352
    int rsize = (isNull(i)) ? -1 : LENGTH(i),
309
    int rsize = (isNull(i)) ? -1 : LENGTH(i),
353
	csize = (isNull(j)) ? -1 : LENGTH(j);
310
	csize = (isNull(j)) ? -1 : LENGTH(j);
354
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
311
    int Rkind = (chx->xtype != CHOLMOD_PATTERN) ? Real_kind(x) : 0;
355
 
312
 
356
    if (rsize >= 0 && !isInteger(i))
313
    if (rsize >= 0 && !isInteger(i))