Warning, file /include/eigen3/Eigen/src/SparseCore/SparseColEtree.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifndef SPARSE_COLETREE_H
0032 #define SPARSE_COLETREE_H
0033
0034 namespace Eigen {
0035
0036 namespace internal {
0037
0038
0039 template<typename Index, typename IndexVector>
0040 Index etree_find (Index i, IndexVector& pp)
0041 {
0042 Index p = pp(i);
0043 Index gp = pp(p);
0044 while (gp != p)
0045 {
0046 pp(i) = gp;
0047 i = gp;
0048 p = pp(i);
0049 gp = pp(p);
0050 }
0051 return p;
0052 }
0053
0054
0055
0056
0057
0058
0059
0060 template <typename MatrixType, typename IndexVector>
0061 int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowElt, typename MatrixType::StorageIndex *perm=0)
0062 {
0063 typedef typename MatrixType::StorageIndex StorageIndex;
0064 StorageIndex nc = convert_index<StorageIndex>(mat.cols());
0065 StorageIndex m = convert_index<StorageIndex>(mat.rows());
0066 StorageIndex diagSize = (std::min)(nc,m);
0067 IndexVector root(nc);
0068 root.setZero();
0069 IndexVector pp(nc);
0070 pp.setZero();
0071 parent.resize(mat.cols());
0072
0073 firstRowElt.resize(m);
0074 firstRowElt.setConstant(nc);
0075 firstRowElt.segment(0, diagSize).setLinSpaced(diagSize, 0, diagSize-1);
0076 bool found_diag;
0077 for (StorageIndex col = 0; col < nc; col++)
0078 {
0079 StorageIndex pcol = col;
0080 if(perm) pcol = perm[col];
0081 for (typename MatrixType::InnerIterator it(mat, pcol); it; ++it)
0082 {
0083 Index row = it.row();
0084 firstRowElt(row) = (std::min)(firstRowElt(row), col);
0085 }
0086 }
0087
0088
0089
0090
0091 StorageIndex rset, cset, rroot;
0092 for (StorageIndex col = 0; col < nc; col++)
0093 {
0094 found_diag = col>=m;
0095 pp(col) = col;
0096 cset = col;
0097 root(cset) = col;
0098 parent(col) = nc;
0099
0100
0101 StorageIndex pcol = col;
0102 if(perm) pcol = perm[col];
0103 for (typename MatrixType::InnerIterator it(mat, pcol); it||!found_diag; ++it)
0104 {
0105 Index i = col;
0106 if(it) i = it.index();
0107 if (i == col) found_diag = true;
0108
0109 StorageIndex row = firstRowElt(i);
0110 if (row >= col) continue;
0111 rset = internal::etree_find(row, pp);
0112 rroot = root(rset);
0113 if (rroot != col)
0114 {
0115 parent(rroot) = col;
0116 pp(cset) = rset;
0117 cset = rset;
0118 root(cset) = col;
0119 }
0120 }
0121 }
0122 return 0;
0123 }
0124
0125
0126
0127
0128
0129 template <typename IndexVector>
0130 void nr_etdfs (typename IndexVector::Scalar n, IndexVector& parent, IndexVector& first_kid, IndexVector& next_kid, IndexVector& post, typename IndexVector::Scalar postnum)
0131 {
0132 typedef typename IndexVector::Scalar StorageIndex;
0133 StorageIndex current = n, first, next;
0134 while (postnum != n)
0135 {
0136
0137 first = first_kid(current);
0138
0139
0140 if (first == -1)
0141 {
0142
0143 post(current) = postnum++;
0144
0145
0146 next = next_kid(current);
0147 while (next == -1)
0148 {
0149
0150 current = parent(current);
0151
0152 post(current) = postnum++;
0153
0154
0155 next = next_kid(current);
0156 }
0157
0158 if (postnum == n+1) return;
0159
0160
0161 current = next;
0162 }
0163 else
0164 {
0165 current = first;
0166 }
0167 }
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177 template <typename IndexVector>
0178 void treePostorder(typename IndexVector::Scalar n, IndexVector& parent, IndexVector& post)
0179 {
0180 typedef typename IndexVector::Scalar StorageIndex;
0181 IndexVector first_kid, next_kid;
0182 StorageIndex postnum;
0183
0184 first_kid.resize(n+1);
0185 next_kid.setZero(n+1);
0186 post.setZero(n+1);
0187
0188
0189 first_kid.setConstant(-1);
0190 for (StorageIndex v = n-1; v >= 0; v--)
0191 {
0192 StorageIndex dad = parent(v);
0193 next_kid(v) = first_kid(dad);
0194 first_kid(dad) = v;
0195 }
0196
0197
0198 postnum = 0;
0199 internal::nr_etdfs(n, parent, first_kid, next_kid, post, postnum);
0200 }
0201
0202 }
0203
0204 }
0205
0206 #endif