33#include "../../../../Eigen/src/Core/util/NonMPL2.h"
35#ifndef EIGEN_CONSTRAINEDCG_H
36#define EIGEN_CONSTRAINEDCG_H
50template <
typename CMatrix,
typename CINVMatrix>
51void pseudo_inverse(
const CMatrix &C, CINVMatrix &CINV)
54 typedef typename CMatrix::Scalar Scalar;
55 typedef typename CMatrix::Index Index;
57 typedef Matrix<Scalar,Dynamic,1> TmpVec;
59 Index rows = C.rows(), cols = C.cols();
61 TmpVec d(rows), e(rows), l(cols), p(rows), q(rows), r(rows);
62 Scalar rho, rho_1, alpha;
65 typedef Triplet<double> T;
66 std::vector<T> tripletList;
68 for (Index i = 0; i < rows; ++i)
79 l = C.transpose() * p;
81 alpha = rho / p.dot(q);
86 p = (rho/rho_1) * p + r;
89 l = C.transpose() * e;
91 for (Index j=0; j<l.size(); ++j)
93 tripletList.push_back(T(i,j,l(j)));
98 CINV.setFromTriplets(tripletList.begin(), tripletList.end());
108template<
typename TMatrix,
typename CMatrix,
109 typename VectorX,
typename VectorB,
typename VectorF>
110void constrained_cg(
const TMatrix& A,
const CMatrix& C, VectorX& x,
111 const VectorB& b,
const VectorF& f, IterationController &iter)
114 typedef typename TMatrix::Scalar Scalar;
115 typedef typename TMatrix::Index Index;
116 typedef Matrix<Scalar,Dynamic,1> TmpVec;
118 Scalar rho = 1.0, rho_1, lambda, gamma;
119 Index xSize = x.size();
120 TmpVec p(xSize), q(xSize), q2(xSize),
121 r(xSize), old_z(xSize), z(xSize),
123 std::vector<bool> satured(C.rows());
125 iter.setRhsNorm(sqrt(b.dot(b)));
126 if (iter.rhsNorm() == 0.0) iter.setRhsNorm(1.0);
128 SparseMatrix<Scalar,RowMajor> CINV(C.rows(), C.cols());
129 pseudo_inverse(C, CINV);
139 bool transition =
false;
140 for (Index i = 0; i < C.rows(); ++i)
142 Scalar al = C.row(i).dot(x) - f.coeff(i);
150 Scalar bb = CINV.row(i).dot(z);
153 for (
typename CMatrix::InnerIterator it(C,i); it; ++it)
154 z.coeffRef(it.index()) -= bb*it.value();
164 if (iter.finished(rho))
break;
166 if (iter.noiseLevel() > 0 && transition) std::cerr <<
"CCG: transition\n";
167 if (transition || iter.first()) gamma = 0.0;
168 else gamma = (std::max)(0.0, (rho - old_z.dot(z)) / rho_1);
174 lambda = rho / q.dot(p);
175 for (Index i = 0; i < C.rows(); ++i)
179 Scalar bb = C.row(i).dot(p) - f[i];
181 lambda = (std::min)(lambda, (f.coeff(i)-C.row(i).dot(x)) / bb);