1 /* ========================================================================== */
2 /* === Tcov/unpack ========================================================== */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Tcov Module.  Copyright (C) 2005-2006, Timothy A. Davis
7  * http://www.suitesparse.com
8  * -------------------------------------------------------------------------- */
9 
10 /* Create an unpacked, unsorted version of a matrix, with random-sized gaps in
11  * each column. */
12 
13 #include "cm.h"
14 
15 
16 /* ========================================================================== */
17 /* === unpack =============================================================== */
18 /* ========================================================================== */
19 
unpack(cholmod_sparse * A)20 cholmod_sparse *unpack (cholmod_sparse *A)
21 {
22     double x ;
23     double *Ax, *Cx, *Az, *Cz ;
24     Int *Ap, *Ai, *Anz, *Cp, *Ci, *Cnz ;
25     cholmod_sparse *C ;
26     Int i, j, p, q, pdest, pend, nrow, ncol, nzmax, sorted, packed, stype,
27 	extra ;
28 
29     if (A == NULL)
30     {
31 	return (NULL) ;
32     }
33 
34     extra = 10 ;
35 
36     nrow = A->nrow ;
37     ncol = A->ncol ;
38     nzmax = A->nzmax ;
39     sorted = A->sorted ;
40     packed = A->packed ;
41     stype = A->stype ;
42 
43     C = CHOLMOD(allocate_sparse) (nrow, ncol, nzmax + extra*ncol, FALSE,
44 	FALSE, stype, A->xtype, cm) ;
45 
46     if (C == NULL)
47     {
48 	return (NULL) ;
49     }
50 
51     Ap = A->p ;
52     Ai = A->i ;
53     Ax = A->x ;
54     Az = A->z ;
55     Anz = A->nz ;
56 
57     Cp = C->p ;
58     Ci = C->i ;
59     Cx = C->x ;
60     Cz = C->z ;
61     Cnz = C->nz ;
62     nzmax = C->nzmax ;
63     nzmax = MAX (1, nzmax) ;
64 
65     for (p = 0 ; p < nzmax ; p++)
66     {
67 	Ci [p] = 0 ;
68     }
69     if (A->xtype == CHOLMOD_REAL)
70     {
71 	for (p = 0 ; p < nzmax ; p++)
72 	{
73 	    Cx [p] = 0 ;
74 	}
75     }
76     else if (A->xtype == CHOLMOD_COMPLEX)
77     {
78 	for (p = 0 ; p < 2*nzmax ; p++)
79 	{
80 	    Cx [p] = 0 ;
81 	}
82     }
83     else if (A->xtype == CHOLMOD_ZOMPLEX)
84     {
85 	for (p = 0 ; p < nzmax ; p++)
86 	{
87 	    Cx [p] = 0 ;
88 	    Cz [p] = 0 ;
89 	}
90     }
91 
92     pdest = 0 ;
93     for (j = 0 ; j < ncol ; j++)
94     {
95 	/* copy the column into C */
96 	p = Ap [j] ;
97 	Cp [j] = pdest ;
98 	pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
99 	Cnz [j] = pend - p ;
100 	for ( ; p < pend ; p++)
101 	{
102 	    Ci [pdest] = Ai [p] ;
103 	    if (A->xtype == CHOLMOD_REAL)
104 	    {
105 		Cx [pdest] = Ax [p] ;
106 	    }
107 	    else if (A->xtype == CHOLMOD_COMPLEX)
108 	    {
109 		Cx [2*pdest  ] = Ax [2*p] ;
110 		Cx [2*pdest+1] = Ax [2*p+1] ;
111 	    }
112 	    else if (A->xtype == CHOLMOD_ZOMPLEX)
113 	    {
114 		Cx [pdest] = Ax [p] ;
115 		Cz [pdest] = Az [p] ;
116 	    }
117 	    pdest++ ;
118 	}
119 
120 	/* jumble the column */
121 	p = Cp [j] ;
122 	pend = p + Cnz [j] ;
123 	for ( ; p < pend-1 ; p++)
124 	{
125 	    q = p + nrand (pend-p) ;				/* RAND */
126 	    i = Ci [p] ;
127 	    Ci [p] = Ci [q] ;
128 	    Ci [q] = i ;
129 
130 	    if (A->xtype == CHOLMOD_REAL)
131 	    {
132 		x = Cx [p] ;
133 		Cx [p] = Cx [q] ;
134 		Cx [q] = x ;
135 	    }
136 	    else if (A->xtype == CHOLMOD_COMPLEX)
137 	    {
138 		x = Cx [2*p] ;
139 		Cx [2*p] = Cx [2*q] ;
140 		Cx [2*q] = x ;
141 
142 		x = Cx [2*p+1] ;
143 		Cx [2*p+1] = Cx [2*q+1] ;
144 		Cx [2*q+1] = x ;
145 	    }
146 	    else if (A->xtype == CHOLMOD_ZOMPLEX)
147 	    {
148 		x = Cx [p] ;
149 		Cx [p] = Cx [q] ;
150 		Cx [q] = x ;
151 
152 		x = Cz [p] ;
153 		Cz [p] = Cz [q] ;
154 		Cz [q] = x ;
155 	    }
156 	}
157 
158 	/* add some random blank space */
159 	pdest += nrand (extra) ;				/* RAND */
160 	for (p = pend ; p < pdest ; p++)
161 	{
162 	    Ci [p] = 0 ;
163 	    if (A->xtype == CHOLMOD_REAL)
164 	    {
165 		Cx [p] = 0 ;
166 	    }
167 	    else if (A->xtype == CHOLMOD_COMPLEX)
168 	    {
169 		Cx [2*p] = 0 ;
170 		Cx [2*p+1] = 0 ;
171 	    }
172 	    else if (A->xtype == CHOLMOD_ZOMPLEX)
173 	    {
174 		Cx [p] = 0 ;
175 		Cz [p] = 0 ;
176 	    }
177 	}
178     }
179     Cp [ncol] = pdest ;
180 
181     return (C) ;
182 }
183