4 struct SimplicialInverseSubset {
6 typedef SimplicialLLT<SparseMatrix<T> > Base;
7 typedef SimplicialLLT<SparseMatrix<double> > BaseD;
8 typedef typename Base::StorageIndex StorageIndex;
9 typedef typename Base::Scalar Scalar;
10 typedef SparseMatrix<T> SpMat;
18 std::shared_ptr<Base>
factor;
19 std::vector<StorageIndex> idg;
20 std::vector<StorageIndex> index_gather(
const SpMat &mat) {
21 SpMat L = factor->matrixL();
22 const StorageIndex* Lp = L.outerIndexPtr();
23 const StorageIndex* Li = L.innerIndexPtr();
24 std::vector<StorageIndex> ans;
25 const StorageIndex *Perm = factor->permutationP().indices().data();
26 std::vector<StorageIndex> wrk(mat.rows());
27 for (StorageIndex k=0; k<mat.outerSize(); ++k) {
29 StorageIndex j = Perm[k];
30 for (StorageIndex l=Lp[j]; l<Lp[j+1]; l++) {
31 StorageIndex i = Li[l];
34 for (
typename SpMat::InnerIterator it(mat, k); it; ++it) {
35 if (Perm[it.row()] < Perm[it.col()]) ans.push_back(-1);
36 else ans.push_back( wrk[Perm[it.row()]] );
41 void valuesGet(SpMat &mat,
const SpMat &S) {
43 idg = index_gather(mat);
44 T* vptr = mat.valuePtr();
45 const T* ans = S.valuePtr();
46 for (
size_t i=0; i<idg.size(); i++) {
48 vptr[i] = ans[idg[i]];
52 template<Operation Op,
class Scalar_,
class Scalar>
53 Scalar column(SparseMatrix<Scalar_> &L,
56 const StorageIndex* Lp = L.outerIndexPtr();
57 const StorageIndex* Li = L.innerIndexPtr();
58 Scalar_* Lx = L.valuePtr();
60 for (StorageIndex k=Lp[j]; k<Lp[j+1]; k++) {
61 StorageIndex i = Li[k];
71 if (Op == InnerProduct) {
77 Eigen::SparseMatrix<StorageIndex> LT;
78 void init_transpose(SpMat L) {
79 if (LT.rows() > 0)
return;
80 std::vector<StorageIndex> x(L.nonZeros());
81 for (
size_t i=0; i<x.size(); i++) x[i] = i;
82 Eigen::SparseMatrix<StorageIndex> TMP =
83 Eigen::Map<const Eigen::SparseMatrix<StorageIndex> > (L.rows(),
93 SpMat L = factor->matrixL();
97 for (StorageIndex i=0; i<S.nonZeros(); i++)
99 const StorageIndex ncol = L.cols();
101 const StorageIndex* Lp = L.outerIndexPtr();
102 Scalar* Lx = L.valuePtr();
104 Scalar* Sx = S.valuePtr();
106 const StorageIndex* LTp = LT.outerIndexPtr();
107 StorageIndex* LTi = LT.innerIndexPtr();
108 StorageIndex* LTx = LT.valuePtr();
110 std::vector<T> wrk(ncol, 0);
111 T* S_row = wrk.data();
113 for (StorageIndex j = ncol; j > 0; ) {
116 column<Scatter> (S, j, S_row);
119 for (StorageIndex k = Lp[j] + 1; k < Lp[j+1]; k++) {
120 Sjj += Lx[k] * Sx[k];
122 Scalar Ljj_inv = 1. / Lx[Lp[j]];
123 S_row[j] = -Ljj_inv * Sjj + Ljj_inv * Ljj_inv;
125 for (StorageIndex k = LTp[j+1]-1; k > LTp[j]; ) {
127 StorageIndex i = LTi[k];
128 S_row[i] = (-1. / Lx[Lp[i]]) * column<InnerProduct> (L, i, S_row);
130 for (StorageIndex k = LTp[j]; k < LTp[j+1]; k++) {
132 StorageIndex i = LTi[k];
133 StorageIndex kT = LTx[k];
137 column<Zero> (L, j, S_row);
138 column<Zero> (LT, j, S_row);
142 SpMat operator()(SpMat x) {
145 factor = std::make_shared<Base>(x);
148 factor->factorize(x);
150 SpMat S = chol2inv();
159 SimplicialInverseSubset(std::shared_ptr<BaseD> factor) { }
std::vector< I > factor(const std::vector< T > &x)
Replace each element in a vector by an integer code such that x[i] == x[j] implies f[i] == f[j] ...