The R Project SVN R-packages

Rev

Rev 3518 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2304 bates 1
			/* Sparse matrices in compressed column-oriented form */
1830 bates 2
#include "Csparse.h"
3
#include "chm_common.h"
4
 
5
SEXP Csparse_validate(SEXP x)
6
{
7
    SEXP pslot = GET_SLOT(x, Matrix_pSym),
8
	islot = GET_SLOT(x, Matrix_iSym);
9
    int j, ncol = length(pslot) - 1,
10
	*dims = INTEGER(GET_SLOT(x, Matrix_DimSym)),
11
	nrow, *xp = INTEGER(pslot),
12
	*xi = INTEGER(islot);
13
 
14
    nrow = dims[0];
15
    if (length(pslot) <= 0)
16
	return mkString(_("slot p must have length > 0"));
17
    if (xp[0] != 0)
18
	return mkString(_("first element of slot p must be zero"));
19
    if (length(islot) != xp[ncol])
20
	return mkString(_("last element of slot p must match length of slots i and x"));
21
    for (j = 0; j < ncol; j++) {
22
	if (xp[j] > xp[j+1])
23
	    return mkString(_("slot p must be non-decreasing"));
24
    }
25
    for (j = 0; j < length(islot); j++) {
26
	if (xi[j] < 0 || xi[j] >= nrow)
27
	    return mkString(_("all row indices must be between 0 and nrow-1"));
28
    }
29
    return ScalarLogical(1);
30
}
31
 
2022 bates 32
SEXP Csparse_to_dense(SEXP x)
33
{
34
    cholmod_sparse *chxs = as_cholmod_sparse(x);
35
    cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c);
36
 
2172 bates 37
    Free(chxs);
2022 bates 38
    return chm_dense_to_SEXP(chxd, 1);
39
}
40
 
3406 bates 41
SEXP Csparse_to_logical(SEXP x, SEXP tri)
42
{
43
    cholmod_sparse *chxs = as_cholmod_sparse(x);
44
    cholmod_sparse
45
	*chxcp = cholmod_copy(chxs, chxs->stype, CHOLMOD_PATTERN, &c);
46
    int uploT = 0; char *diag = "";
47
 
48
    Free(chxs);
49
    if (asLogical(tri)) {	/* triangular sparse matrices */
50
	uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ?
51
	    -1 : 1;
52
	diag = CHAR(asChar(GET_SLOT(x, Matrix_diagSym)));
53
    }
54
    return chm_sparse_to_SEXP(chxcp, 1, uploT, diag,
55
				GET_SLOT(x, Matrix_DimNamesSym));
56
}
57
 
3401 bates 58
SEXP Csparse_to_matrix(SEXP x)
1830 bates 59
{
1833 maechler 60
    cholmod_sparse *chxs = as_cholmod_sparse(x);
3401 bates 61
    cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c);
62
 
63
    Free(chxs);
64
    return chm_dense_to_matrix(chxd, 1,
65
			       GET_SLOT(x, Matrix_DimNamesSym));
66
}
67
 
68
SEXP Csparse_to_Tsparse(SEXP x, SEXP tri)
69
{
70
    cholmod_sparse *chxs = as_cholmod_sparse(x);
1830 bates 71
    cholmod_triplet *chxt = cholmod_sparse_to_triplet(chxs, &c);
3401 bates 72
    int uploT = 0; char *diag = "";
1830 bates 73
 
2172 bates 74
    Free(chxs);
3401 bates 75
    if (asLogical(tri)) {	/* triangular sparse matrices */
3466 bates 76
	uploT = (*uplo_P(x) == 'U') ? -1 : 1;
77
	diag = diag_P(x);
3401 bates 78
    }
79
    return chm_triplet_to_SEXP(chxt, 1, uploT, diag,
3406 bates 80
			       GET_SLOT(x, Matrix_DimNamesSym));
1830 bates 81
}
82
 
3502 bates 83
/* this used to be called  sCMatrix_to_gCMatrix(..)   [in ./dsCMatrix.c ]: */
3406 bates 84
SEXP Csparse_symmetric_to_general(SEXP x)
85
{
86
    cholmod_sparse *chx = as_cholmod_sparse(x), *chgx;
87
 
88
    if (!(chx->stype))
89
	error(_("Nonsymmetric matrix in Csparse_symmeteric_to_general"));
3410 maechler 90
    chgx = cholmod_copy(chx, /* stype: */ 0, chx->xtype, &c);
91
    /* xtype: pattern, "real", complex or .. */
3406 bates 92
    Free(chx);
93
    return chm_sparse_to_SEXP(chgx, 1, 0, "",
94
			      GET_SLOT(x, Matrix_DimNamesSym));
95
}
96
 
3404 bates 97
SEXP Csparse_transpose(SEXP x, SEXP tri)
1830 bates 98
{
99
    cholmod_sparse *chx = as_cholmod_sparse(x);
100
    cholmod_sparse *chxt = cholmod_transpose(chx, (int) chx->xtype, &c);
3401 bates 101
    SEXP dn = PROTECT(duplicate(GET_SLOT(x, Matrix_DimNamesSym))), tmp;
3404 bates 102
    int uploT = 0; char *diag = "";
103
 
2172 bates 104
    Free(chx);
3401 bates 105
    tmp = VECTOR_ELT(dn, 0);	/* swap the dimnames */
106
    SET_VECTOR_ELT(dn, 0, VECTOR_ELT(dn, 1));
107
    SET_VECTOR_ELT(dn, 1, tmp);
108
    UNPROTECT(1);
3404 bates 109
    if (asLogical(tri)) {	/* triangular sparse matrices */
3466 bates 110
	uploT = (*uplo_P(x) == 'U') ? -1 : 1;
111
	diag = diag_P(x);
3404 bates 112
    }
113
    return chm_sparse_to_SEXP(chxt, 1, uploT, diag, dn);
1830 bates 114
}
115
 
116
SEXP Csparse_Csparse_prod(SEXP a, SEXP b)
117
{
2022 bates 118
    cholmod_sparse *cha = as_cholmod_sparse(a),
119
	*chb = as_cholmod_sparse(b);
120
    cholmod_sparse *chc = cholmod_ssmult(cha, chb, 0, cha->xtype, 1, &c);
3401 bates 121
    SEXP dn = allocVector(VECSXP, 2);
1830 bates 122
 
2172 bates 123
    Free(cha); Free(chb);
3401 bates 124
    SET_VECTOR_ELT(dn, 0,	/* establish dimnames */
125
		   duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0)));
126
    SET_VECTOR_ELT(dn, 1,
127
		   duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1)));
128
    return chm_sparse_to_SEXP(chc, 1, 0, "", dn);
1830 bates 129
}
130
 
131
SEXP Csparse_dense_prod(SEXP a, SEXP b)
132
{
133
    cholmod_sparse *cha = as_cholmod_sparse(a);
3518 bates 134
    cholmod_dense *chb = as_cholmod_dense(PROTECT(mMatrix_as_dgeMatrix(b)));
3502 bates 135
    cholmod_dense *chc = 
136
	cholmod_allocate_dense(cha->nrow, chb->ncol, cha->nrow, chb->xtype, &c);
137
    double alpha[] = {1,0}, beta[] = {0,0};
1830 bates 138
 
3502 bates 139
    cholmod_sdmult(cha, 0, alpha, beta, chb, chc, &c);
2172 bates 140
    Free(cha); Free(chb);
3518 bates 141
    UNPROTECT(1);
1831 bates 142
    return chm_dense_to_SEXP(chc, 1);
1830 bates 143
}
1833 maechler 144
 
2030 bates 145
SEXP Csparse_dense_crossprod(SEXP a, SEXP b)
146
{
147
    cholmod_sparse *cha = as_cholmod_sparse(a);
3518 bates 148
    cholmod_dense *chb = as_cholmod_dense(PROTECT(mMatrix_as_dgeMatrix(b)));
3502 bates 149
    cholmod_dense *chc =
150
	cholmod_allocate_dense(cha->ncol, chb->ncol, cha->ncol, chb->xtype, &c);
151
    double alpha[] = {1,0}, beta[] = {0,0};
2030 bates 152
 
3502 bates 153
    cholmod_sdmult(cha, 1, alpha, beta, chb, chc, &c);
2030 bates 154
    Free(cha); Free(chb);
3518 bates 155
    UNPROTECT(1);
2030 bates 156
    return chm_dense_to_SEXP(chc, 1);
157
}
158
 
1836 bates 159
SEXP Csparse_crossprod(SEXP x, SEXP trans, SEXP triplet)
1830 bates 160
{
1870 maechler 161
    int trip = asLogical(triplet),
162
	tr   = asLogical(trans); /* gets reversed because _aat is tcrossprod */
1836 bates 163
    cholmod_triplet
164
	*cht = trip ? as_cholmod_triplet(x) : (cholmod_triplet*) NULL;
165
    cholmod_sparse *chcp, *chxt,
166
	*chx = trip ? cholmod_triplet_to_sparse(cht, cht->nnz, &c)
167
	: as_cholmod_sparse(x);
3401 bates 168
    SEXP dn = PROTECT(allocVector(VECSXP, 2));
1830 bates 169
 
1831 bates 170
    if (!tr)
3380 bates 171
	chxt = cholmod_transpose(chx, chx->xtype, &c);
1836 bates 172
    chcp = cholmod_aat((!tr) ? chxt : chx, (int *) NULL, 0, chx->xtype, &c);
1870 maechler 173
    if(!chcp)
174
	error("Csparse_crossprod(): error return from cholmod_aat()");
3388 bates 175
    cholmod_band_inplace(0, chcp->ncol, chcp->xtype, chcp, &c);
176
    chcp->stype = 1;
1838 bates 177
    if (trip) {
178
	cholmod_free_sparse(&chx, &c);
2172 bates 179
	Free(cht);
1838 bates 180
    } else {
2172 bates 181
	Free(chx);
1838 bates 182
    }
1831 bates 183
    if (!tr) cholmod_free_sparse(&chxt, &c);
3401 bates 184
				/* create dimnames */
185
    SET_VECTOR_ELT(dn, 0,
186
		   duplicate(VECTOR_ELT(GET_SLOT(x, Matrix_DimNamesSym),
187
					(tr) ? 1 : 0)));
188
    SET_VECTOR_ELT(dn, 1, duplicate(VECTOR_ELT(dn, 0)));
189
    UNPROTECT(1);
190
    return chm_sparse_to_SEXP(chcp, 1, 0, "", dn);
1830 bates 191
}
1831 bates 192
 
2304 bates 193
SEXP Csparse_horzcat(SEXP x, SEXP y)
194
{
195
    cholmod_sparse *chx = as_cholmod_sparse(x),
196
	*chy = as_cholmod_sparse(y), *ans;
3410 maechler 197
 
2304 bates 198
    ans = cholmod_horzcat(chx, chy, 1, &c);
199
    Free(chx); Free(chy);
3401 bates 200
    /* FIXME: currently drops dimnames */
201
    return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue);
2304 bates 202
}
203
 
204
SEXP Csparse_vertcat(SEXP x, SEXP y)
205
{
206
    cholmod_sparse *chx = as_cholmod_sparse(x),
207
	*chy = as_cholmod_sparse(y), *ans;
3410 maechler 208
 
2304 bates 209
    ans = cholmod_vertcat(chx, chy, 1, &c);
210
    Free(chx); Free(chy);
3401 bates 211
    /* FIXME: currently drops dimnames */
212
    return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue);
2304 bates 213
}
3134 bates 214
 
215
SEXP Csparse_band(SEXP x, SEXP k1, SEXP k2)
216
{
217
    cholmod_sparse *chx = as_cholmod_sparse(x), *ans;
218
 
219
    ans = cholmod_band(chx, asInteger(k1), asInteger(k2), chx->xtype, &c);
220
    Free(chx);
3401 bates 221
    return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue);
3134 bates 222
}
3401 bates 223
 
224
SEXP Csparse_diagU2N(SEXP x)
225
{
226
    cholmod_sparse *chx = as_cholmod_sparse(x);
227
    cholmod_sparse *eye = cholmod_speye(chx->nrow, chx->ncol, chx->xtype, &c);
228
    double one[] = {1, 0};
229
    cholmod_sparse *ans = cholmod_add(chx, eye, one, one, TRUE, TRUE, &c);
230
    int uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ?
231
	-1 : 1;
232
 
233
    Free(chx); cholmod_free_sparse(&eye, &c);
234
    return chm_sparse_to_SEXP(ans, 1, uploT, "N",
235
			      duplicate(GET_SLOT(x, Matrix_DimNamesSym)));
236
}
237
 
238
SEXP Csparse_submatrix(SEXP x, SEXP i, SEXP j)
239
{
240
    cholmod_sparse *chx = as_cholmod_sparse(x);
241
    int rsize = (isNull(i)) ? -1 : LENGTH(i),
242
	csize = (isNull(j)) ? -1 : LENGTH(j);
243
 
244
    if (rsize >= 0 && !isInteger(i))
245
	error(_("Index i must be NULL or integer"));
246
    if (csize >= 0 && !isInteger(j))
247
	error(_("Index j must be NULL or integer"));
248
    return chm_sparse_to_SEXP(cholmod_submatrix(chx, INTEGER(i), rsize,
3410 maechler 249
						INTEGER(j), csize,
3401 bates 250
						TRUE, TRUE, &c),
251
			      1, 0, "", R_NilValue);
252
}