21 #ifndef EIGEN_SPARSE_AMD_H
22 #define EIGEN_SPARSE_AMD_H
28 template<
typename T>
inline T amd_flip(
const T&
i) {
return -
i-2; }
30 template<
typename T0,
typename T1>
inline bool amd_marked(
const T0*
w,
const T1&
j) {
return w[
j]<0; }
34 template<
typename StorageIndex>
35 static StorageIndex
cs_wclear (StorageIndex mark, StorageIndex lemax, StorageIndex *
w, StorageIndex
n)
38 if(mark < 2 || (mark + lemax < 0))
40 for(k = 0; k <
n; k++)
49 template<
typename StorageIndex>
50 StorageIndex
cs_tdfs(StorageIndex
j, StorageIndex k, StorageIndex *
head,
const StorageIndex *next, StorageIndex *post, StorageIndex *
stack)
52 StorageIndex
i,
p, top = 0;
53 if(!
head || !next || !post || !
stack)
return (-1);
83 template<
typename Scalar,
typename StorageIndex>
88 StorageIndex
d, dk, dext, lemax = 0,
e, elenk, eln,
i,
j, k,
k1,
89 k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi,
90 ok, nel = 0,
p,
p1,
p2,
p3,
p4, pj, pk, pk1, pk2, pn,
q,
t,
h;
92 StorageIndex
n = StorageIndex(
C.
cols());
93 dense = std::max<StorageIndex> (16, StorageIndex(10 *
sqrt(
double(
n))));
96 StorageIndex cnz = StorageIndex(
C.nonZeros());
98 t = cnz + cnz/5 + 2*
n;
103 StorageIndex*
len =
W;
104 StorageIndex* nv =
W + (
n+1);
105 StorageIndex* next =
W + 2*(
n+1);
106 StorageIndex*
head =
W + 3*(
n+1);
107 StorageIndex* elen =
W + 4*(
n+1);
109 StorageIndex*
w =
W + 6*(
n+1);
110 StorageIndex* hhead =
W + 7*(
n+1);
111 StorageIndex*
last =
perm.indices().data();
114 StorageIndex* Cp =
C.outerIndexPtr();
115 StorageIndex* Ci =
C.innerIndexPtr();
116 for(k = 0; k <
n; k++)
117 len[k] = Cp[k+1] - Cp[k];
121 for(
i = 0;
i <=
n;
i++)
132 mark = internal::cs_wclear<StorageIndex>(0, 0,
w,
n);
135 for(
i = 0;
i <
n;
i++)
137 bool has_diag =
false;
138 for(
p = Cp[
i];
p<Cp[
i+1]; ++
p)
146 if(
d == 1 && has_diag)
153 else if(
d > dense || !has_diag)
176 for(k = -1; mindeg <
n && (k =
head[mindeg]) == -1; mindeg++) {}
177 if(next[k] != -1)
last[next[k]] = -1;
178 head[mindeg] = next[k];
184 if(elenk > 0 && cnz + mindeg >= nzmax)
186 for(
j = 0;
j <
n;
j++)
194 for(
q = 0,
p = 0;
p < cnz; )
200 for(k3 = 0; k3 <
len[
j]-1; k3++) Ci[
q++] = Ci[
p++];
210 pk1 = (elenk == 0) ?
p : cnz;
212 for(
k1 = 1;
k1 <= elenk + 1;
k1++)
226 for(k2 = 1; k2 <= ln; k2++)
229 if((nvi = nv[
i]) <= 0)
continue;
249 if(elenk != 0) cnz = pk2;
256 mark = internal::cs_wclear<StorageIndex>(mark, lemax,
w,
n);
257 for(pk = pk1; pk < pk2; pk++)
260 if((eln = elen[
i]) <= 0)
continue;
263 for(
p = Cp[
i];
p <= Cp[
i] + eln - 1;
p++)
278 for(pk = pk1; pk < pk2; pk++)
282 p2 =
p1 + elen[
i] - 1;
303 elen[
i] = pn -
p1 + 1;
309 if((nvj = nv[
j]) <= 0)
continue;
338 lemax = std::max<StorageIndex>(lemax, dk);
339 mark = internal::cs_wclear<StorageIndex>(mark+lemax, lemax,
w,
n);
342 for(pk = pk1; pk < pk2; pk++)
345 if(nv[
i] >= 0)
continue;
349 for(;
i != -1 && next[
i] != -1;
i = next[
i], mark++)
353 for(
p = Cp[
i]+1;
p <= Cp[
i] + ln-1;
p++)
w[Ci[
p]] = mark;
355 for(
j = next[
i];
j != -1; )
357 ok = (
len[
j] == ln) && (elen[
j] == eln);
358 for(
p = Cp[
j] + 1; ok &&
p <= Cp[
j] + ln - 1;
p++)
360 if(
w[Ci[
p]] != mark) ok = 0;
381 for(
p = pk1, pk = pk1; pk < pk2; pk++)
384 if((nvi = -nv[
i]) <= 0)
continue;
387 d = std::min<StorageIndex> (
d,
n - nel - nvi);
392 mindeg = std::min<StorageIndex> (mindeg,
d);
397 if((
len[k] =
p-pk1) == 0)
402 if(elenk != 0) cnz =
p;
408 for(
j =
n;
j >= 0;
j--)
410 if(nv[
j] > 0)
continue;
414 for(
e =
n;
e >= 0;
e--)
416 if(nv[
e] <= 0)
continue;
423 for(k = 0,
i = 0;
i <=
n;
i++)
425 if(Cp[
i] == -1) k = internal::cs_tdfs<StorageIndex>(
i, k,
head, next,
perm.indices().data(),
w);
428 perm.indices().conservativeResize(
n);
435 #endif // EIGEN_SPARSE_AMD_H