00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef SPARSELU_PANEL_DFS_H
00031 #define SPARSELU_PANEL_DFS_H
00032
00033 namespace Eigen {
00034
00035 namespace internal {
00036
00037 template<typename IndexVector>
00038 struct panel_dfs_traits
00039 {
00040 typedef typename IndexVector::Scalar Index;
00041 panel_dfs_traits(Index jcol, Index* marker)
00042 : m_jcol(jcol), m_marker(marker)
00043 {}
00044 bool update_segrep(Index krep, Index jj)
00045 {
00046 if(m_marker[krep]<m_jcol)
00047 {
00048 m_marker[krep] = jj;
00049 return true;
00050 }
00051 return false;
00052 }
00053 void mem_expand(IndexVector& , Index , Index ) {}
00054 enum { ExpandMem = false };
00055 Index m_jcol;
00056 Index* m_marker;
00057 };
00058
00059
00060 template <typename Scalar, typename Index>
00061 template <typename Traits>
00062 void SparseLUImpl<Scalar,Index>::dfs_kernel(const Index jj, IndexVector& perm_r,
00063 Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
00064 Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
00065 IndexVector& xplore, GlobalLU_t& glu,
00066 Index& nextl_col, Index krow, Traits& traits
00067 )
00068 {
00069
00070 Index kmark = marker(krow);
00071
00072
00073 marker(krow) = jj;
00074 Index kperm = perm_r(krow);
00075 if (kperm == emptyIdxLU ) {
00076
00077 panel_lsub(nextl_col++) = krow;
00078
00079 traits.mem_expand(panel_lsub, nextl_col, kmark);
00080 }
00081 else
00082 {
00083
00084
00085
00086 Index krep = glu.xsup(glu.supno(kperm)+1) - 1;
00087
00088 Index myfnz = repfnz_col(krep);
00089
00090 if (myfnz != emptyIdxLU )
00091 {
00092
00093 if (myfnz > kperm ) repfnz_col(krep) = kperm;
00094
00095 }
00096 else
00097 {
00098
00099 Index oldrep = emptyIdxLU;
00100 parent(krep) = oldrep;
00101 repfnz_col(krep) = kperm;
00102 Index xdfs = glu.xlsub(krep);
00103 Index maxdfs = xprune(krep);
00104
00105 Index kpar;
00106 do
00107 {
00108
00109 while (xdfs < maxdfs)
00110 {
00111 Index kchild = glu.lsub(xdfs);
00112 xdfs++;
00113 Index chmark = marker(kchild);
00114
00115 if (chmark != jj )
00116 {
00117 marker(kchild) = jj;
00118 Index chperm = perm_r(kchild);
00119
00120 if (chperm == emptyIdxLU)
00121 {
00122
00123 panel_lsub(nextl_col++) = kchild;
00124 traits.mem_expand(panel_lsub, nextl_col, chmark);
00125 }
00126 else
00127 {
00128
00129
00130
00131 Index chrep = glu.xsup(glu.supno(chperm)+1) - 1;
00132 myfnz = repfnz_col(chrep);
00133
00134 if (myfnz != emptyIdxLU)
00135 {
00136 if (myfnz > chperm)
00137 repfnz_col(chrep) = chperm;
00138 }
00139 else
00140 {
00141 xplore(krep) = xdfs;
00142 oldrep = krep;
00143 krep = chrep;
00144 parent(krep) = oldrep;
00145 repfnz_col(krep) = chperm;
00146 xdfs = glu.xlsub(krep);
00147 maxdfs = xprune(krep);
00148
00149 }
00150 }
00151
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160 if(traits.update_segrep(krep,jj))
00161
00162 {
00163 segrep(nseg) = krep;
00164 ++nseg;
00165
00166 }
00167
00168 kpar = parent(krep);
00169 if (kpar == emptyIdxLU)
00170 break;
00171 krep = kpar;
00172 xdfs = xplore(krep);
00173 maxdfs = xprune(krep);
00174
00175 } while (kpar != emptyIdxLU);
00176
00177 }
00178
00179 }
00180 }
00181
00218 template <typename Scalar, typename Index>
00219 void SparseLUImpl<Scalar,Index>::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)
00220 {
00221 Index nextl_col;
00222
00223
00224 VectorBlock<IndexVector> marker1(marker, m, m);
00225 nseg = 0;
00226
00227 panel_dfs_traits<IndexVector> traits(jcol, marker1.data());
00228
00229
00230 for (Index jj = jcol; jj < jcol + w; jj++)
00231 {
00232 nextl_col = (jj - jcol) * m;
00233
00234 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
00235 VectorBlock<ScalarVector> dense_col(dense,nextl_col, m);
00236
00237
00238
00239 for (typename MatrixType::InnerIterator it(A, jj); it; ++it)
00240 {
00241 Index krow = it.row();
00242 dense_col(krow) = it.value();
00243
00244 Index kmark = marker(krow);
00245 if (kmark == jj)
00246 continue;
00247
00248 dfs_kernel(jj, perm_r, nseg, panel_lsub, segrep, repfnz_col, xprune, marker, parent,
00249 xplore, glu, nextl_col, krow, traits);
00250 }
00251
00252 }
00253 }
00254
00255 }
00256 }
00257
00258 #endif // SPARSELU_PANEL_DFS_H