6 if (mark < 2 || (mark + lemax < 0))
8 for (k = 0 ; k < n ; k++)
if (w [k] != 0) w [k] = 1 ;
21 CS_INT *Cp, *Ci, *last, *W, *len, *nv, *next, *P, *head, *elen, *degree, *w,
22 *hhead, *ATp, *ATi, d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1,
23 k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi,
24 ok, cnz, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, n, m, t ;
27 if (!
CS_CSC (A) || order <= 0 || order > 3)
return (NULL) ;
29 if (!AT)
return (NULL) ;
31 dense =
CS_MAX (16, 10 * sqrt ((
double) n)) ;
32 dense =
CS_MIN (n-2, dense) ;
33 if (order == 1 && n == m)
41 for (p2 = 0, j = 0 ; j < m ; j++)
45 if (ATp [j+1] - p > dense) continue ;
46 for ( ; p < ATp [j+1] ; p++) ATi [p2++] = ATi [p] ;
58 if (!C)
return (NULL) ;
64 t = cnz + cnz/5 + 2*n ;
66 len = W ; nv = W + (n+1) ; next = W + 2*(n+1) ;
67 head = W + 3*(n+1) ; elen = W + 4*(n+1) ; degree = W + 5*(n+1) ;
68 w = W + 6*(n+1) ; hhead = W + 7*(n+1) ;
71 for (k = 0 ; k < n ; k++) len [k] = Cp [k+1] - Cp [k] ;
75 for (i = 0 ; i <= n ; i++)
84 degree [i] = len [i] ;
86 mark = cs_wclear (0, 0, w, n) ;
91 for (i = 0 ; i < n ; i++)
111 if (head [d] != -1) last [head [d]] = i ;
112 next [i] = head [d] ;
119 for (k = -1 ; mindeg < n && (k = head [mindeg]) == -1 ; mindeg++) ;
120 if (next [k] != -1) last [next [k]] = -1 ;
121 head [mindeg] = next [k] ;
126 if (elenk > 0 && cnz + mindeg >= nzmax)
128 for (j = 0 ; j < n ; j++)
130 if ((p = Cp [j]) >= 0)
136 for (q = 0, p = 0 ; p < cnz ; )
138 if ((j =
CS_FLIP (Ci [p++])) >= 0)
142 for (k3 = 0 ; k3 < len [j]-1 ; k3++) Ci [q++] = Ci [p++] ;
151 pk1 = (elenk == 0) ? p : cnz ;
153 for (k1 = 1 ; k1 <= elenk + 1 ; k1++)
159 ln = len [k] - elenk ;
167 for (k2 = 1 ; k2 <= ln ; k2++)
170 if ((nvi = nv [i]) <= 0)
continue ;
174 if (next [i] != -1) last [next [i]] = last [i] ;
177 next [last [i]] = next [i] ;
181 head [degree [i]] = next [i] ;
190 if (elenk != 0) cnz = pk2 ;
193 len [k] = pk2 - pk1 ;
196 mark = cs_wclear (mark, lemax, w, n) ;
197 for (pk = pk1 ; pk < pk2 ; pk++)
200 if ((eln = elen [i]) <= 0) continue ;
203 for (p = Cp [i] ; p <= Cp [i] + eln - 1 ; p++)
212 w [e] = degree [e] + wnvi ;
217 for (pk = pk1 ; pk < pk2 ; pk++)
221 p2 = p1 + elen [i] - 1 ;
223 for (h = 0, d = 0, p = p1 ; p <= p2 ; p++)
228 dext = w [e] - mark ;
242 elen [i] = pn - p1 + 1 ;
245 for (p = p2 + 1 ; p < p4 ; p++)
248 if ((nvj = nv [j]) <= 0) continue ;
265 degree [i] =
CS_MIN (degree [i], d) ;
269 len [i] = pn - p1 + 1 ;
270 h = ((h<0) ? (-h):h) % n ;
271 next [i] = hhead [h] ;
277 lemax =
CS_MAX (lemax, dk) ;
278 mark = cs_wclear (mark+lemax, lemax, w, n) ;
280 for (pk = pk1 ; pk < pk2 ; pk++)
283 if (nv [i] >= 0) continue ;
287 for ( ; i != -1 && next [i] != -1 ; i = next [i], mark++)
291 for (p = Cp [i]+1 ; p <= Cp [i] + ln-1 ; p++) w [Ci [p]] = mark;
293 for (j = next [i] ; j != -1 ; )
295 ok = (len [j] == ln) && (elen [j] == eln) ;
296 for (p = Cp [j] + 1 ; ok && p <= Cp [j] + ln - 1 ; p++)
298 if (w [Ci [p]] != mark) ok = 0 ;
318 for (p = pk1, pk = pk1 ; pk < pk2 ; pk++)
321 if ((nvi = -nv [i]) <= 0) continue ;
323 d = degree [i] + dk - nvi ;
324 d =
CS_MIN (d, n - nel - nvi) ;
325 if (head [d] != -1) last [head [d]] = i ;
326 next [i] = head [d] ;
329 mindeg =
CS_MIN (mindeg, d) ;
334 if ((len [k] = p-pk1) == 0)
339 if (elenk != 0) cnz = p ;
342 for (i = 0 ; i < n ; i++) Cp [i] =
CS_FLIP (Cp [i]) ;
343 for (j = 0 ; j <= n ; j++) head [j] = -1 ;
344 for (j = n ; j >= 0 ; j--)
346 if (nv [j] > 0) continue ;
347 next [j] = head [Cp [j]] ;
350 for (e = n ; e >= 0 ; e--)
352 if (nv [e] <= 0) continue ;
355 next [e] = head [Cp [e]] ;
359 for (k = 0, i = 0 ; i <= n ; i++)
361 if (Cp [i] == -1) k =
cs_tdfs (i, k, head, next, P, w) ;
CS_INT cs_tdfs(CS_INT j, CS_INT k, CS_INT *head, const CS_INT *next, CS_INT *post, CS_INT *stack)
cs * cs_add(const cs *A, const cs *B, CS_ENTRY alpha, CS_ENTRY beta)
CS_INT * cs_amd(CS_INT order, const cs *A)
CS_INT cs_fkeep(cs *A, CS_INT(*fkeep)(CS_INT, CS_INT, CS_ENTRY, void *), void *other)
cs * cs_multiply(const cs *A, const cs *B)
cs * cs_transpose(const cs *A, CS_INT values)
CS_INT cs_sprealloc(cs *A, CS_INT nzmax)
void * cs_malloc(CS_INT n, size_t size)
CS_INT * cs_idone(CS_INT *p, cs *C, void *w, CS_INT ok)