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
00031 #ifndef SPARSELU_PANEL_BMOD_H
00032 #define SPARSELU_PANEL_BMOD_H
00033
00034 namespace Eigen {
00035 namespace internal {
00036
00055 template <typename Scalar, typename Index>
00056 void SparseLUImpl<Scalar,Index>::panel_bmod(const Index m, const Index w, const Index jcol,
00057 const Index nseg, ScalarVector& dense, ScalarVector& tempv,
00058 IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu)
00059 {
00060
00061 Index ksub,jj,nextl_col;
00062 Index fsupc, nsupc, nsupr, nrow;
00063 Index krep, kfnz;
00064 Index lptr;
00065 Index luptr;
00066 Index segsize,no_zeros ;
00067
00068 Index k = nseg - 1;
00069 const Index PacketSize = internal::packet_traits<Scalar>::size;
00070
00071 for (ksub = 0; ksub < nseg; ksub++)
00072 {
00073
00074
00075
00076
00077
00078 krep = segrep(k); k--;
00079 fsupc = glu.xsup(glu.supno(krep));
00080 nsupc = krep - fsupc + 1;
00081 nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc);
00082 nrow = nsupr - nsupc;
00083 lptr = glu.xlsub(fsupc);
00084
00085
00086 Index u_rows = 0;
00087 Index u_cols = 0;
00088 for (jj = jcol; jj < jcol + w; jj++)
00089 {
00090 nextl_col = (jj-jcol) * m;
00091 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
00092
00093 kfnz = repfnz_col(krep);
00094 if ( kfnz == emptyIdxLU )
00095 continue;
00096
00097 segsize = krep - kfnz + 1;
00098 u_cols++;
00099 u_rows = (std::max)(segsize,u_rows);
00100 }
00101
00102 if(nsupc >= 2)
00103 {
00104 Index ldu = internal::first_multiple<Index>(u_rows, PacketSize);
00105 Map<Matrix<Scalar,Dynamic,Dynamic>, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu));
00106
00107
00108 Index u_col = 0;
00109 for (jj = jcol; jj < jcol + w; jj++)
00110 {
00111 nextl_col = (jj-jcol) * m;
00112 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
00113 VectorBlock<ScalarVector> dense_col(dense, nextl_col, m);
00114
00115 kfnz = repfnz_col(krep);
00116 if ( kfnz == emptyIdxLU )
00117 continue;
00118
00119 segsize = krep - kfnz + 1;
00120 luptr = glu.xlusup(fsupc);
00121 no_zeros = kfnz - fsupc;
00122
00123 Index isub = lptr + no_zeros;
00124 Index off = u_rows-segsize;
00125 for (Index i = 0; i < off; i++) U(i,u_col) = 0;
00126 for (Index i = 0; i < segsize; i++)
00127 {
00128 Index irow = glu.lsub(isub);
00129 U(i+off,u_col) = dense_col(irow);
00130 ++isub;
00131 }
00132 u_col++;
00133 }
00134
00135 luptr = glu.xlusup(fsupc);
00136 Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc);
00137 no_zeros = (krep - u_rows + 1) - fsupc;
00138 luptr += lda * no_zeros + no_zeros;
00139 Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) );
00140 U = A.template triangularView<UnitLower>().solve(U);
00141
00142
00143 luptr += u_rows;
00144 Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) );
00145 eigen_assert(tempv.size()>w*ldu + nrow*w + 1);
00146
00147 Index ldl = internal::first_multiple<Index>(nrow, PacketSize);
00148 Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize;
00149 Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl));
00150
00151 L.setZero();
00152 internal::sparselu_gemm<Scalar>(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride());
00153
00154
00155 u_col = 0;
00156 for (jj = jcol; jj < jcol + w; jj++)
00157 {
00158 nextl_col = (jj-jcol) * m;
00159 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
00160 VectorBlock<ScalarVector> dense_col(dense, nextl_col, m);
00161
00162 kfnz = repfnz_col(krep);
00163 if ( kfnz == emptyIdxLU )
00164 continue;
00165
00166 segsize = krep - kfnz + 1;
00167 no_zeros = kfnz - fsupc;
00168 Index isub = lptr + no_zeros;
00169
00170 Index off = u_rows-segsize;
00171 for (Index i = 0; i < segsize; i++)
00172 {
00173 Index irow = glu.lsub(isub++);
00174 dense_col(irow) = U.coeff(i+off,u_col);
00175 U.coeffRef(i+off,u_col) = 0;
00176 }
00177
00178
00179 for (Index i = 0; i < nrow; i++)
00180 {
00181 Index irow = glu.lsub(isub++);
00182 dense_col(irow) -= L.coeff(i,u_col);
00183 L.coeffRef(i,u_col) = 0;
00184 }
00185 u_col++;
00186 }
00187 }
00188 else
00189 {
00190
00191 for (jj = jcol; jj < jcol + w; jj++)
00192 {
00193 nextl_col = (jj-jcol) * m;
00194 VectorBlock<IndexVector> repfnz_col(repfnz, nextl_col, m);
00195 VectorBlock<ScalarVector> dense_col(dense, nextl_col, m);
00196
00197 kfnz = repfnz_col(krep);
00198 if ( kfnz == emptyIdxLU )
00199 continue;
00200
00201 segsize = krep - kfnz + 1;
00202 luptr = glu.xlusup(fsupc);
00203
00204 Index lda = glu.xlusup(fsupc+1)-glu.xlusup(fsupc);
00205
00206
00207
00208 no_zeros = kfnz - fsupc;
00209 if(segsize==1) LU_kernel_bmod<1>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
00210 else if(segsize==2) LU_kernel_bmod<2>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
00211 else if(segsize==3) LU_kernel_bmod<3>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
00212 else LU_kernel_bmod<Dynamic>::run(segsize, dense_col, tempv, glu.lusup, luptr, lda, nrow, glu.lsub, lptr, no_zeros);
00213 }
00214 }
00215
00216 }
00217 }
00218
00219 }
00220
00221 }
00222
00223 #endif // SPARSELU_PANEL_BMOD_H