File indexing completed on 2025-04-19 09:06:43
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 #ifndef SPARSELU_PANEL_DFS_H
0031 #define SPARSELU_PANEL_DFS_H
0032
0033 namespace RivetEigen {
0034
0035 namespace internal {
0036
0037 template<typename IndexVector>
0038 struct panel_dfs_traits
0039 {
0040 typedef typename IndexVector::Scalar StorageIndex;
0041 panel_dfs_traits(Index jcol, StorageIndex* marker)
0042 : m_jcol(jcol), m_marker(marker)
0043 {}
0044 bool update_segrep(Index krep, StorageIndex jj)
0045 {
0046 if(m_marker[krep]<m_jcol)
0047 {
0048 m_marker[krep] = jj;
0049 return true;
0050 }
0051 return false;
0052 }
0053 void mem_expand(IndexVector& , Index , Index ) {}
0054 enum { ExpandMem = false };
0055 Index m_jcol;
0056 StorageIndex* m_marker;
0057 };
0058
0059
0060 template <typename Scalar, typename StorageIndex>
0061 template <typename Traits>
0062 void SparseLUImpl<Scalar,StorageIndex>::dfs_kernel(const StorageIndex jj, IndexVector& perm_r,
0063 Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
0064 Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
0065 IndexVector& xplore, GlobalLU_t& glu,
0066 Index& nextl_col, Index krow, Traits& traits
0067 )
0068 {
0069
0070 StorageIndex kmark = marker(krow);
0071
0072
0073 marker(krow) = jj;
0074 StorageIndex kperm = perm_r(krow);
0075 if (kperm == emptyIdxLU ) {
0076
0077 panel_lsub(nextl_col++) = StorageIndex(krow);
0078
0079 traits.mem_expand(panel_lsub, nextl_col, kmark);
0080 }
0081 else
0082 {
0083
0084
0085
0086 StorageIndex krep = glu.xsup(glu.supno(kperm)+1) - 1;
0087
0088 StorageIndex myfnz = repfnz_col(krep);
0089
0090 if (myfnz != emptyIdxLU )
0091 {
0092
0093 if (myfnz > kperm ) repfnz_col(krep) = kperm;
0094
0095 }
0096 else
0097 {
0098
0099 StorageIndex oldrep = emptyIdxLU;
0100 parent(krep) = oldrep;
0101 repfnz_col(krep) = kperm;
0102 StorageIndex xdfs = glu.xlsub(krep);
0103 Index maxdfs = xprune(krep);
0104
0105 StorageIndex kpar;
0106 do
0107 {
0108
0109 while (xdfs < maxdfs)
0110 {
0111 StorageIndex kchild = glu.lsub(xdfs);
0112 xdfs++;
0113 StorageIndex chmark = marker(kchild);
0114
0115 if (chmark != jj )
0116 {
0117 marker(kchild) = jj;
0118 StorageIndex chperm = perm_r(kchild);
0119
0120 if (chperm == emptyIdxLU)
0121 {
0122
0123 panel_lsub(nextl_col++) = kchild;
0124 traits.mem_expand(panel_lsub, nextl_col, chmark);
0125 }
0126 else
0127 {
0128
0129
0130
0131 StorageIndex chrep = glu.xsup(glu.supno(chperm)+1) - 1;
0132 myfnz = repfnz_col(chrep);
0133
0134 if (myfnz != emptyIdxLU)
0135 {
0136 if (myfnz > chperm)
0137 repfnz_col(chrep) = chperm;
0138 }
0139 else
0140 {
0141 xplore(krep) = xdfs;
0142 oldrep = krep;
0143 krep = chrep;
0144 parent(krep) = oldrep;
0145 repfnz_col(krep) = chperm;
0146 xdfs = glu.xlsub(krep);
0147 maxdfs = xprune(krep);
0148
0149 }
0150 }
0151
0152 }
0153 }
0154
0155
0156
0157
0158
0159
0160 if(traits.update_segrep(krep,jj))
0161
0162 {
0163 segrep(nseg) = krep;
0164 ++nseg;
0165
0166 }
0167
0168 kpar = parent(krep);
0169 if (kpar == emptyIdxLU)
0170 break;
0171 krep = kpar;
0172 xdfs = xplore(krep);
0173 maxdfs = xprune(krep);
0174
0175 } while (kpar != emptyIdxLU);
0176
0177 }
0178
0179 }
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 template <typename Scalar, typename StorageIndex>
0219 void SparseLUImpl<Scalar,StorageIndex>::panel_dfs(const Index m, const Index w, const Index jcol, MatrixType& A, IndexVector& perm_r, Index& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu)
0220 {
0221 Index nextl_col;
0222
0223
0224 VectorBlock<IndexVector> marker1(marker, m, m);
0225 nseg = 0;
0226
0227 panel_dfs_traits<IndexVector> traits(jcol, marker1.data());
0228
0229
0230 for (StorageIndex jj = StorageIndex(jcol); jj < jcol + w; jj++)
0231 {
0232 nextl_col = (jj - jcol) * m;
0233
0234 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
0235 VectorBlock<ScalarVector> dense_col(dense,nextl_col, m);
0236
0237
0238
0239 for (typename MatrixType::InnerIterator it(A, jj); it; ++it)
0240 {
0241 Index krow = it.row();
0242 dense_col(krow) = it.value();
0243
0244 StorageIndex kmark = marker(krow);
0245 if (kmark == jj)
0246 continue;
0247
0248 dfs_kernel(jj, perm_r, nseg, panel_lsub, segrep, repfnz_col, xprune, marker, parent,
0249 xplore, glu, nextl_col, krow, traits);
0250 }
0251
0252 }
0253 }
0254
0255 }
0256 }
0257
0258 #endif