File indexing completed on 2025-01-18 09:57:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef EIGEN_LMQRSOLV_H
0016 #define EIGEN_LMQRSOLV_H
0017
0018 namespace Eigen {
0019
0020 namespace internal {
0021
0022 template <typename Scalar,int Rows, int Cols, typename PermIndex>
0023 void lmqrsolv(
0024 Matrix<Scalar,Rows,Cols> &s,
0025 const PermutationMatrix<Dynamic,Dynamic,PermIndex> &iPerm,
0026 const Matrix<Scalar,Dynamic,1> &diag,
0027 const Matrix<Scalar,Dynamic,1> &qtb,
0028 Matrix<Scalar,Dynamic,1> &x,
0029 Matrix<Scalar,Dynamic,1> &sdiag)
0030 {
0031
0032 Index i, j, k;
0033 Scalar temp;
0034 Index n = s.cols();
0035 Matrix<Scalar,Dynamic,1> wa(n);
0036 JacobiRotation<Scalar> givens;
0037
0038
0039
0040
0041
0042
0043
0044 x = s.diagonal();
0045 wa = qtb;
0046
0047
0048 s.topLeftCorner(n,n).template triangularView<StrictlyLower>() = s.topLeftCorner(n,n).transpose();
0049
0050 for (j = 0; j < n; ++j) {
0051
0052
0053
0054 const PermIndex l = iPerm.indices()(j);
0055 if (diag[l] == 0.)
0056 break;
0057 sdiag.tail(n-j).setZero();
0058 sdiag[j] = diag[l];
0059
0060
0061
0062
0063 Scalar qtbpj = 0.;
0064 for (k = j; k < n; ++k) {
0065
0066
0067 givens.makeGivens(-s(k,k), sdiag[k]);
0068
0069
0070
0071 s(k,k) = givens.c() * s(k,k) + givens.s() * sdiag[k];
0072 temp = givens.c() * wa[k] + givens.s() * qtbpj;
0073 qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;
0074 wa[k] = temp;
0075
0076
0077 for (i = k+1; i<n; ++i) {
0078 temp = givens.c() * s(i,k) + givens.s() * sdiag[i];
0079 sdiag[i] = -givens.s() * s(i,k) + givens.c() * sdiag[i];
0080 s(i,k) = temp;
0081 }
0082 }
0083 }
0084
0085
0086
0087 Index nsing;
0088 for(nsing=0; nsing<n && sdiag[nsing]!=0; nsing++) {}
0089
0090 wa.tail(n-nsing).setZero();
0091 s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));
0092
0093
0094 sdiag = s.diagonal();
0095 s.diagonal() = x;
0096
0097
0098 x = iPerm * wa;
0099 }
0100
0101 template <typename Scalar, int _Options, typename Index>
0102 void lmqrsolv(
0103 SparseMatrix<Scalar,_Options,Index> &s,
0104 const PermutationMatrix<Dynamic,Dynamic> &iPerm,
0105 const Matrix<Scalar,Dynamic,1> &diag,
0106 const Matrix<Scalar,Dynamic,1> &qtb,
0107 Matrix<Scalar,Dynamic,1> &x,
0108 Matrix<Scalar,Dynamic,1> &sdiag)
0109 {
0110
0111 typedef SparseMatrix<Scalar,RowMajor,Index> FactorType;
0112 Index i, j, k, l;
0113 Scalar temp;
0114 Index n = s.cols();
0115 Matrix<Scalar,Dynamic,1> wa(n);
0116 JacobiRotation<Scalar> givens;
0117
0118
0119
0120
0121
0122
0123 wa = qtb;
0124 FactorType R(s);
0125
0126 for (j = 0; j < n; ++j)
0127 {
0128
0129
0130 l = iPerm.indices()(j);
0131 if (diag(l) == Scalar(0))
0132 break;
0133 sdiag.tail(n-j).setZero();
0134 sdiag[j] = diag[l];
0135
0136
0137
0138
0139 Scalar qtbpj = 0;
0140
0141 for (k = j; k < n; ++k)
0142 {
0143 typename FactorType::InnerIterator itk(R,k);
0144 for (; itk; ++itk){
0145 if (itk.index() < k) continue;
0146 else break;
0147 }
0148
0149
0150
0151 givens.makeGivens(-itk.value(), sdiag(k));
0152
0153
0154
0155 itk.valueRef() = givens.c() * itk.value() + givens.s() * sdiag(k);
0156 temp = givens.c() * wa(k) + givens.s() * qtbpj;
0157 qtbpj = -givens.s() * wa(k) + givens.c() * qtbpj;
0158 wa(k) = temp;
0159
0160
0161 for (++itk; itk; ++itk)
0162 {
0163 i = itk.index();
0164 temp = givens.c() * itk.value() + givens.s() * sdiag(i);
0165 sdiag(i) = -givens.s() * itk.value() + givens.c() * sdiag(i);
0166 itk.valueRef() = temp;
0167 }
0168 }
0169 }
0170
0171
0172
0173 Index nsing;
0174 for(nsing = 0; nsing<n && sdiag(nsing) !=0; nsing++) {}
0175
0176 wa.tail(n-nsing).setZero();
0177
0178 wa.head(nsing) = R.topLeftCorner(nsing,nsing).template triangularView<Upper>().solve(wa.head(nsing));
0179
0180 sdiag = R.diagonal();
0181
0182 x = iPerm * wa;
0183 }
0184 }
0185
0186 }
0187
0188 #endif