3
template <typename Scalar>
5
Matrix< Scalar, Dynamic, Dynamic > &r,
7
const Matrix< Scalar, Dynamic, 1 > &diag,
8
const Matrix< Scalar, Dynamic, 1 > &qtb,
11
Matrix< Scalar, Dynamic, 1 > &x)
13
typedef DenseIndex Index;
26
const Scalar dwarf = std::numeric_limits<Scalar>::min();
27
const Index n = r.cols();
28
assert(n==diag.size());
29
assert(n==qtb.size());
32
Matrix< Scalar, Dynamic, 1 > wa1, wa2;
34
/* compute and store in x the gauss-newton direction. if the */
35
/* jacobian is rank-deficient, obtain a least squares solution. */
38
for (j = 0; j < n; ++j) {
39
if (r(j,j) == 0. && nsing == n-1)
44
for (j = nsing; j>=0; --j) {
47
for (i = 0; i < j ; ++i)
48
wa1[i] -= r(i,j) * temp;
51
for (j = 0; j < n; ++j)
54
/* initialize the iteration counter. */
55
/* evaluate the function at the origin, and test */
56
/* for acceptance of the gauss-newton direction. */
58
wa2 = diag.cwiseProduct(x);
59
dxnorm = wa2.blueNorm();
61
if (fp <= Scalar(0.1) * delta) {
66
/* if the jacobian is not rank deficient, the newton */
67
/* step provides a lower bound, parl, for the zero of */
68
/* the function. otherwise set this bound to zero. */
71
for (j = 0; j < n; ++j) {
73
wa1[j] = diag[l] * (wa2[l] / dxnorm);
75
// it's actually a triangularView.solveInplace(), though in a weird
77
for (j = 0; j < n; ++j) {
79
for (i = 0; i < j; ++i)
80
sum += r(i,j) * wa1[i];
81
wa1[j] = (wa1[j] - sum) / r(j,j);
83
temp = wa1.blueNorm();
84
parl = fp / delta / temp / temp;
87
/* calculate an upper bound, paru, for the zero of the function. */
88
for (j = 0; j < n; ++j)
89
wa1[j] = r.col(j).head(j+1).dot(qtb.head(j+1)) / diag[ipvt[j]];
91
gnorm = wa1.stableNorm();
94
paru = dwarf / (std::min)(delta,Scalar(0.1));
96
/* if the input par lies outside of the interval (parl,paru), */
97
/* set par to the closer endpoint. */
98
par = (std::max)(par,parl);
99
par = (std::min)(par,paru);
101
par = gnorm / dxnorm;
103
/* beginning of an iteration. */
107
/* evaluate the function at the current value of par. */
109
par = (std::max)(dwarf,Scalar(.001) * paru); /* Computing MAX */
110
wa1 = sqrt(par)* diag;
112
Matrix< Scalar, Dynamic, 1 > sdiag(n);
113
qrsolv<Scalar>(r, ipvt, wa1, qtb, x, sdiag);
115
wa2 = diag.cwiseProduct(x);
116
dxnorm = wa2.blueNorm();
120
/* if the function is small enough, accept the current value */
121
/* of par. also test for the exceptional cases where parl */
122
/* is zero or the number of iterations has reached 10. */
123
if (abs(fp) <= Scalar(0.1) * delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)
126
/* compute the newton correction. */
127
for (j = 0; j < n; ++j) {
129
wa1[j] = diag[l] * (wa2[l] / dxnorm);
131
for (j = 0; j < n; ++j) {
134
for (i = j+1; i < n; ++i)
135
wa1[i] -= r(i,j) * temp;
137
temp = wa1.blueNorm();
138
parc = fp / delta / temp / temp;
140
/* depending on the sign of the function, update parl or paru. */
142
parl = (std::max)(parl,par);
144
paru = (std::min)(paru,par);
146
/* compute an improved estimate for par. */
148
par = (std::max)(parl,par+parc);
150
/* end of an iteration. */
159
template <typename Scalar>
161
const ColPivHouseholderQR<Matrix< Scalar, Dynamic, Dynamic> > &qr,
162
const Matrix< Scalar, Dynamic, 1 > &diag,
163
const Matrix< Scalar, Dynamic, 1 > &qtb,
166
Matrix< Scalar, Dynamic, 1 > &x)
169
typedef DenseIndex Index;
171
/* Local variables */
182
const Scalar dwarf = std::numeric_limits<Scalar>::min();
183
const Index n = qr.matrixQR().cols();
184
assert(n==diag.size());
185
assert(n==qtb.size());
187
Matrix< Scalar, Dynamic, 1 > wa1, wa2;
189
/* compute and store in x the gauss-newton direction. if the */
190
/* jacobian is rank-deficient, obtain a least squares solution. */
192
// const Index rank = qr.nonzeroPivots(); // exactly double(0.)
193
const Index rank = qr.rank(); // use a threshold
195
wa1.tail(n-rank).setZero();
196
qr.matrixQR().topLeftCorner(rank, rank).template triangularView<Upper>().solveInPlace(wa1.head(rank));
198
x = qr.colsPermutation()*wa1;
200
/* initialize the iteration counter. */
201
/* evaluate the function at the origin, and test */
202
/* for acceptance of the gauss-newton direction. */
204
wa2 = diag.cwiseProduct(x);
205
dxnorm = wa2.blueNorm();
207
if (fp <= Scalar(0.1) * delta) {
212
/* if the jacobian is not rank deficient, the newton */
213
/* step provides a lower bound, parl, for the zero of */
214
/* the function. otherwise set this bound to zero. */
217
wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2)/dxnorm;
218
qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
219
temp = wa1.blueNorm();
220
parl = fp / delta / temp / temp;
223
/* calculate an upper bound, paru, for the zero of the function. */
224
for (j = 0; j < n; ++j)
225
wa1[j] = qr.matrixQR().col(j).head(j+1).dot(qtb.head(j+1)) / diag[qr.colsPermutation().indices()(j)];
227
gnorm = wa1.stableNorm();
228
paru = gnorm / delta;
230
paru = dwarf / (std::min)(delta,Scalar(0.1));
232
/* if the input par lies outside of the interval (parl,paru), */
233
/* set par to the closer endpoint. */
234
par = (std::max)(par,parl);
235
par = (std::min)(par,paru);
237
par = gnorm / dxnorm;
239
/* beginning of an iteration. */
240
Matrix< Scalar, Dynamic, Dynamic > s = qr.matrixQR();
244
/* evaluate the function at the current value of par. */
246
par = (std::max)(dwarf,Scalar(.001) * paru); /* Computing MAX */
247
wa1 = sqrt(par)* diag;
249
Matrix< Scalar, Dynamic, 1 > sdiag(n);
250
qrsolv<Scalar>(s, qr.colsPermutation().indices(), wa1, qtb, x, sdiag);
252
wa2 = diag.cwiseProduct(x);
253
dxnorm = wa2.blueNorm();
257
/* if the function is small enough, accept the current value */
258
/* of par. also test for the exceptional cases where parl */
259
/* is zero or the number of iterations has reached 10. */
260
if (abs(fp) <= Scalar(0.1) * delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)
263
/* compute the newton correction. */
264
wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2/dxnorm);
265
// we could almost use this here, but the diagonal is outside qr, in sdiag[]
266
// qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
267
for (j = 0; j < n; ++j) {
270
for (Index i = j+1; i < n; ++i)
271
wa1[i] -= s(i,j) * temp;
273
temp = wa1.blueNorm();
274
parc = fp / delta / temp / temp;
276
/* depending on the sign of the function, update parl or paru. */
278
parl = (std::max)(parl,par);
280
paru = (std::min)(paru,par);
282
/* compute an improved estimate for par. */
283
par = (std::max)(parl,par+parc);
290
} // end namespace internal