cs *cs_transpose(const cs *A, int values) { int p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w; double *Cx, *Ax; cs *C; if (!CS_CSC (A)) return (NULL); /* check inputs */ m = A->m; n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; C = cs_spalloc(n, m, Ap[n], values && Ax, 0); /* allocate result */ w = (int *) cs_calloc(m, sizeof(int)); /* get workspace */ if (!C || !w) return (cs_done(C, w, NULL, 0)); /* out of memory */ Cp = C->p; Ci = C->i; Cx = C->x; for (p = 0; p < Ap[n]; p++) w[Ai[p]]++; /* row counts */ cs_cumsum(Cp, w, m); /* row pointers */ for (j = 0; j < n; j++) { for (p = Ap[j]; p < Ap[j + 1]; p++) { Ci[q = w[Ai[p]]++] = j; /* place A(i,j) as entry C(j,i) */ if (Cx) Cx[q] = Ax[p]; } } return (cs_done(C, w, NULL, 1)); /* success; free w and return C */ }
css *cs_schol(int order, const cs *A) { int n, *c, *post, *P; cs *C; css *S; if (!CS_CSC (A)) return (NULL); /* check inputs */ n = A->n; S = (css *) cs_calloc(1, sizeof(css)); /* allocate result S */ if (!S) return (NULL); /* out of memory */ P = cs_amd(order, A); /* P = amd(A+A'), or natural */ S->pinv = cs_pinv(P, n); /* find inverse permutation */ cs_free(P); if (order && !S->pinv) return (cs_sfree(S)); C = cs_symperm(A, S->pinv, 0); /* C = spones(triu(A(P,P))) */ S->parent = cs_etree(C, 0); /* find etree of C */ post = cs_post(S->parent, n); /* postorder the etree */ c = cs_counts(C, S->parent, post, 0); /* find column counts of chol(C) */ cs_free(post); cs_spfree(C); S->cp = (int *) cs_malloc(n + 1, sizeof(int)); /* allocate result S->cp */ S->unz = S->lnz = cs_cumsum(S->cp, c, n); /* find column pointers for L */ cs_free(c); return ((S->lnz >= 0) ? S : cs_sfree(S)); }
cs *cs_compress(const cs *T) { int m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj; double *Cx, *Tx; cs *C; if (!CS_TRIPLET (T)) return (NULL); /* check inputs */ m = T->m; n = T->n; Ti = T->i; Tj = T->p; Tx = T->x; nz = T->nz; C = cs_spalloc(m, n, nz, Tx != NULL, 0); /* allocate result */ w = (int *) cs_calloc(n, sizeof(int)); /* get workspace */ if (!C || !w) return (cs_done(C, w, NULL, 0)); /* out of memory */ Cp = C->p; Ci = C->i; Cx = C->x; for (k = 0; k < nz; k++) w[Tj[k]]++; /* column counts */ cs_cumsum(Cp, w, n); /* column pointers */ for (k = 0; k < nz; k++) { Ci[p = w[Tj[k]]++] = Ti[k]; /* A(i,j) is the pth entry in C */ if (Cx) Cx[p] = Tx[k]; } return (cs_done(C, w, NULL, 1)); /* success; free w and return C */ }
cs *cs_symperm(const cs *A, const int *pinv, int values) { int i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w; double *Cx, *Ax; cs *C; if (!CS_CSC (A)) return (NULL); /* check inputs */ n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; C = cs_spalloc(n, n, Ap[n], values && (Ax != NULL), 0); /* alloc result*/ w = (int *) cs_calloc(n, sizeof(int)); /* get workspace */ if (!C || !w) return (cs_done(C, w, NULL, 0)); /* out of memory */ Cp = C->p; Ci = C->i; Cx = C->x; for (j = 0; j < n; j++) /* count entries in each column of C */ { j2 = pinv ? pinv[j] : j; /* column j of A is column j2 of C */ for (p = Ap[j]; p < Ap[j + 1]; p++) { i = Ai[p]; if (i > j) continue; /* skip lower triangular part of A */ i2 = pinv ? pinv[i] : i; /* row i of A is row i2 of C */ w[CS_MAX (i2, j2)]++; /* column count of C */ } } cs_cumsum(Cp, w, n); /* compute column pointers of C */ for (j = 0; j < n; j++) { j2 = pinv ? pinv[j] : j; /* column j of A is column j2 of C */ for (p = Ap[j]; p < Ap[j + 1]; p++) { i = Ai[p]; if (i > j) continue; /* skip lower triangular part of A*/ i2 = pinv ? pinv[i] : i; /* row i of A is row i2 of C */ Ci[q = w[CS_MAX (i2, j2)]++] = CS_MIN (i2, j2); if (Cx) Cx[q] = Ax[p]; } } return (cs_done(C, w, NULL, 1)); /* success; free workspace, return C */ }
static void transpose(const AMatrix * A, Priv * p) { scs_int * Ci = p->At->i; scs_int * Cp = p->At->p; scs_float * Cx = p->At->x; scs_int m = A->m; scs_int n = A->n; scs_int * Ap = A->p; scs_int * Ai = A->i; scs_float * Ax = A->x; scs_int i, j, q, *z, c1, c2; #if EXTRAVERBOSE > 0 timer transposeTimer; scs_printf("transposing A\n"); tic(&transposeTimer); #endif z = scs_calloc(m, sizeof(scs_int)); for (i = 0; i < Ap[n]; i++) z[Ai[i]]++; /* row counts */ cs_cumsum(Cp, z, m); /* row pointers */ for (j = 0; j < n; j++) { c1 = Ap[j]; c2 = Ap[j + 1]; for (i = c1; i < c2; i++) { q = z[Ai[i]]; Ci[q] = j; /* place A(i,j) as entry C(j,i) */ Cx[q] = Ax[i]; z[Ai[i]]++; } } scs_free(z); #if EXTRAVERBOSE > 0 scs_printf("finished transposing A, time: %1.2es\n", tocq(&transposeTimer) / 1e3); #endif }