The R Project SVN R-packages

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1820 bates 1
#include "Pattern.h"
2
 
3
cholmod_sparse *factor_to_pattern(SEXP fact)
4
{
5
    int *vals = INTEGER(fact), i, n = LENGTH(fact),
6
	nlev = LENGTH(getAttrib(fact, R_LevelsSymbol));
7
    cholmod_sparse *A;
8
 
9
    if (!isFactor(fact))
10
	error("`fact' must be a factor");
11
    A = cholmod_allocate_sparse((size_t) nlev, (size_t) n, (size_t) n,
12
				TRUE, TRUE, 0, CHOLMOD_PATTERN, &c);
13
    for (i = 0; i <= n; i++) ((int *) (A->p))[i] = i;
14
    for (i = 0; i < n; i++) ((int *) (A->i))[i] = vals[i] - 1;
15
    if (cholmod_check_sparse(A, &c) < 0)
16
	error("sparse Pattern matrix has invalid structure");
17
    return A;
18
}
19
 
20
SEXP factor_prod(SEXP f1, SEXP f2)
21
{
22
    SEXP ans = PROTECT(allocVector(VECSXP, 3));
1830 bates 23
    int *dims, n = LENGTH(f1), i, nl1, nl2, nmax, super;
1820 bates 24
    cholmod_triplet *A;
25
    cholmod_sparse *B;
26
    cholmod_factor *F;
27
 
28
    if (!isFactor(f1) || !isFactor(f2) || LENGTH(f2) != n)
29
	error("f1 and f2 must be factors of the same length");
30
    nl1 = LENGTH(getAttrib(f1, R_LevelsSymbol));
31
    nl2 = LENGTH(getAttrib(f2, R_LevelsSymbol));
32
 
33
    A = cholmod_allocate_triplet((size_t) nl1, (size_t) nl2, (size_t) n,
34
				 0, CHOLMOD_PATTERN, &c);
35
    for (i = 0; i < n; i++) {
36
	((int *)(A->i))[i] = INTEGER(f1)[i] - 1;
37
	((int *)(A->j))[i] = INTEGER(f2)[i] - 1;
38
    }
39
    A->nnz = n;
40
    nmax = nl1 * nl2;
41
    if (n < nmax) nmax = n;
42
    B = cholmod_triplet_to_sparse(A, nmax, &c);
43
    cholmod_free_triplet(&A, &c);
44
				/*  force a simplicial factorization */
45
    super = c.supernodal;
46
    c.supernodal = CHOLMOD_SIMPLICIAL;
47
    F = cholmod_analyze(B, &c); 
48
    c.supernodal = super;
49
 
50
    SET_VECTOR_ELT(ans, 0, allocVector(INTSXP, 2));
51
    dims = INTEGER(VECTOR_ELT(ans, 0));
52
    dims[0] = nl1; dims[1] = nl2;
53
    SET_VECTOR_ELT(ans, 1, allocVector(INTSXP, nl1));
54
    Memcpy(INTEGER(VECTOR_ELT(ans, 1)), (int *) F->Perm, nl1);
55
    SET_VECTOR_ELT(ans, 2, allocVector(INTSXP, nl1));
56
    Memcpy(INTEGER(VECTOR_ELT(ans, 2)), (int *) F->ColCount, nl1);
57
    Rprintf("Ordering used: %d\n", F->ordering);
58
    Rprintf("is_super: %d\n", F->is_super);
59
 
60
    cholmod_free_sparse(&B, &c);
61
    cholmod_free_factor(&F, &c);
62
 
63
    UNPROTECT(1);
64
    return ans;
65
}
66