Warning, file /include/eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 #include "../../../../Eigen/src/Core/util/NonMPL2.h"
0030
0031 #ifndef EIGEN_CONSTRAINEDCG_H
0032 #define EIGEN_CONSTRAINEDCG_H
0033
0034 #include "../../../../Eigen/Core"
0035
0036 namespace Eigen {
0037
0038 namespace internal {
0039
0040
0041
0042
0043
0044
0045
0046 template <typename CMatrix, typename CINVMatrix>
0047 void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV)
0048 {
0049
0050 typedef typename CMatrix::Scalar Scalar;
0051 typedef typename CMatrix::Index Index;
0052
0053 typedef Matrix<Scalar,Dynamic,1> TmpVec;
0054
0055 Index rows = C.rows(), cols = C.cols();
0056
0057 TmpVec d(rows), e(rows), l(cols), p(rows), q(rows), r(rows);
0058 Scalar rho, rho_1, alpha;
0059 d.setZero();
0060
0061 typedef Triplet<double> T;
0062 std::vector<T> tripletList;
0063
0064 for (Index i = 0; i < rows; ++i)
0065 {
0066 d[i] = 1.0;
0067 rho = 1.0;
0068 e.setZero();
0069 r = d;
0070 p = d;
0071
0072 while (rho >= 1e-38)
0073 {
0074
0075 l = C.transpose() * p;
0076 q = C * l;
0077 alpha = rho / p.dot(q);
0078 e += alpha * p;
0079 r += -alpha * q;
0080 rho_1 = rho;
0081 rho = r.dot(r);
0082 p = (rho/rho_1) * p + r;
0083 }
0084
0085 l = C.transpose() * e;
0086
0087 for (Index j=0; j<l.size(); ++j)
0088 if (l[j]<1e-15)
0089 tripletList.push_back(T(i,j,l(j)));
0090
0091
0092 d[i] = 0.0;
0093 }
0094 CINV.setFromTriplets(tripletList.begin(), tripletList.end());
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104 template<typename TMatrix, typename CMatrix,
0105 typename VectorX, typename VectorB, typename VectorF>
0106 void constrained_cg(const TMatrix& A, const CMatrix& C, VectorX& x,
0107 const VectorB& b, const VectorF& f, IterationController &iter)
0108 {
0109 using std::sqrt;
0110 typedef typename TMatrix::Scalar Scalar;
0111 typedef typename TMatrix::Index Index;
0112 typedef Matrix<Scalar,Dynamic,1> TmpVec;
0113
0114 Scalar rho = 1.0, rho_1, lambda, gamma;
0115 Index xSize = x.size();
0116 TmpVec p(xSize), q(xSize), q2(xSize),
0117 r(xSize), old_z(xSize), z(xSize),
0118 memox(xSize);
0119 std::vector<bool> satured(C.rows());
0120 p.setZero();
0121 iter.setRhsNorm(sqrt(b.dot(b)));
0122 if (iter.rhsNorm() == 0.0) iter.setRhsNorm(1.0);
0123
0124 SparseMatrix<Scalar,RowMajor> CINV(C.rows(), C.cols());
0125 pseudo_inverse(C, CINV);
0126
0127 while(true)
0128 {
0129
0130 old_z = z;
0131 memox = x;
0132 r = b;
0133 r += A * -x;
0134 z = r;
0135 bool transition = false;
0136 for (Index i = 0; i < C.rows(); ++i)
0137 {
0138 Scalar al = C.row(i).dot(x) - f.coeff(i);
0139 if (al >= -1.0E-15)
0140 {
0141 if (!satured[i])
0142 {
0143 satured[i] = true;
0144 transition = true;
0145 }
0146 Scalar bb = CINV.row(i).dot(z);
0147 if (bb > 0.0)
0148
0149 for (typename CMatrix::InnerIterator it(C,i); it; ++it)
0150 z.coeffRef(it.index()) -= bb*it.value();
0151 }
0152 else
0153 satured[i] = false;
0154 }
0155
0156
0157 rho_1 = rho;
0158 rho = r.dot(z);
0159
0160 if (iter.finished(rho)) break;
0161 if (transition || iter.first()) gamma = 0.0;
0162 else gamma = (std::max)(0.0, (rho - old_z.dot(z)) / rho_1);
0163 p = z + gamma*p;
0164
0165 ++iter;
0166
0167 q = A * p;
0168 lambda = rho / q.dot(p);
0169 for (Index i = 0; i < C.rows(); ++i)
0170 {
0171 if (!satured[i])
0172 {
0173 Scalar bb = C.row(i).dot(p) - f[i];
0174 if (bb > 0.0)
0175 lambda = (std::min)(lambda, (f.coeff(i)-C.row(i).dot(x)) / bb);
0176 }
0177 }
0178 x += lambda * p;
0179 memox -= x;
0180 }
0181 }
0182
0183 }
0184
0185 }
0186
0187 #endif