aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
diff options
context:
space:
mode:
Diffstat (limited to 'unsupported/Eigen/src/NonLinearOptimization/qrsolv.h')
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/qrsolv.h170
1 files changed, 48 insertions, 122 deletions
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index 57884870c..1ee21d5ed 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,166 +1,92 @@
- template <typename Scalar>
-void ei_qrsolv(int n, Scalar *r__, int ldr,
- const int *ipvt, const Scalar *diag, const Scalar *qtb, Scalar *x,
- Scalar *sdiag, Scalar *wa)
-{
- /* System generated locals */
- int r_dim1, r_offset;
+template <typename Scalar>
+void ei_qrsolv(
+ Matrix< Scalar, Dynamic, Dynamic > &r,
+ VectorXi &ipvt, // TODO : const once ipvt mess fixed
+ const Matrix< Scalar, Dynamic, 1 > &diag,
+ const Matrix< Scalar, Dynamic, 1 > &qtb,
+ Matrix< Scalar, Dynamic, 1 > &x,
+ Matrix< Scalar, Dynamic, 1 > &sdiag)
+{
/* Local variables */
- int i, j, k, l, jp1, kp1;
- Scalar tan__, cos__, sin__, sum, temp, cotan;
- int nsing;
- Scalar qtbpj;
-
- /* Parameter adjustments */
- --wa;
- --sdiag;
- --x;
- --qtb;
- --diag;
- --ipvt;
- r_dim1 = ldr;
- r_offset = 1 + r_dim1 * 1;
- r__ -= r_offset;
+ int i, j, k, l;
+ Scalar sum, temp;
+ int n = r.cols();
+ Matrix< Scalar, Dynamic, 1 > wa(n);
/* Function Body */
/* copy r and (q transpose)*b to preserve input and initialize s. */
/* in particular, save the diagonal elements of r in x. */
- for (j = 1; j <= n; ++j) {
- for (i = j; i <= n; ++i) {
- r__[i + j * r_dim1] = r__[j + i * r_dim1];
- /* L10: */
- }
- x[j] = r__[j + j * r_dim1];
- wa[j] = qtb[j];
- /* L20: */
- }
+ x = r.diagonal();
+ wa = qtb;
- /* eliminate the diagonal matrix d using a givens rotation. */
+ for (j = 0; j < n; ++j)
+ for (i = j+1; i < n; ++i)
+ r(i,j) = r(j,i);
- for (j = 1; j <= n; ++j) {
+ /* eliminate the diagonal matrix d using a givens rotation. */
+ for (j = 0; j < n; ++j) {
/* prepare the row of d to be eliminated, locating the */
/* diagonal element using p from the qr factorization. */
l = ipvt[j];
- if (diag[l] == 0.) {
- goto L90;
- }
- for (k = j; k <= n; ++k) {
- sdiag[k] = 0.;
- /* L30: */
- }
+ if (diag[l] == 0.)
+ break;
+ sdiag.segment(j,n-j).setZero();
sdiag[j] = diag[l];
/* the transformations to eliminate the row of d */
/* modify only a single element of (q transpose)*b */
/* beyond the first n, which is initially zero. */
- qtbpj = 0.;
- for (k = j; k <= n; ++k) {
-
+ Scalar qtbpj = 0.;
+ for (k = j; k < n; ++k) {
/* determine a givens rotation which eliminates the */
/* appropriate element in the current row of d. */
-
- if (sdiag[k] == 0.)
- goto L70;
- if ( ei_abs(r__[k + k * r_dim1]) >= ei_abs(sdiag[k]))
- goto L40;
- cotan = r__[k + k * r_dim1] / sdiag[k];
- /* Computing 2nd power */
- sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
- cos__ = sin__ * cotan;
- goto L50;
-L40:
- tan__ = sdiag[k] / r__[k + k * r_dim1];
- /* Computing 2nd power */
- cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
- sin__ = cos__ * tan__;
-L50:
+ PlanarRotation<Scalar> givens;
+ givens.makeGivens(-r(k,k), sdiag[k]);
/* compute the modified diagonal element of r and */
/* the modified element of ((q transpose)*b,0). */
- r__[k + k * r_dim1] = cos__ * r__[k + k * r_dim1] + sin__ * sdiag[
- k];
- temp = cos__ * wa[k] + sin__ * qtbpj;
- qtbpj = -sin__ * wa[k] + cos__ * qtbpj;
+ r(k,k) = givens.c() * r(k,k) + givens.s() * sdiag[k];
+ temp = givens.c() * wa[k] + givens.s() * qtbpj;
+ qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;
wa[k] = temp;
/* accumulate the tranformation in the row of s. */
-
- kp1 = k + 1;
- if (n < kp1) {
- goto L70;
+ for (i = k+1; i<n; ++i) {
+ temp = givens.c() * r(i,k) + givens.s() * sdiag[i];
+ sdiag[i] = -givens.s() * r(i,k) + givens.c() * sdiag[i];
+ r(i,k) = temp;
}
- for (i = kp1; i <= n; ++i) {
- temp = cos__ * r__[i + k * r_dim1] + sin__ * sdiag[i];
- sdiag[i] = -sin__ * r__[i + k * r_dim1] + cos__ * sdiag[
- i];
- r__[i + k * r_dim1] = temp;
- /* L60: */
- }
-L70:
- /* L80: */
- ;
}
-L90:
-
- /* store the diagonal element of s and restore */
- /* the corresponding diagonal element of r. */
-
- sdiag[j] = r__[j + j * r_dim1];
- r__[j + j * r_dim1] = x[j];
- /* L100: */
}
+ // restore
+ sdiag = r.diagonal();
+ r.diagonal() = x;
+
/* solve the triangular system for z. if the system is */
/* singular, then obtain a least squares solution. */
- nsing = n;
- for (j = 1; j <= n; ++j) {
- if (sdiag[j] == 0. && nsing == n) {
- nsing = j - 1;
- }
- if (nsing < n) {
- wa[j] = 0.;
- }
- /* L110: */
- }
- if (nsing < 1) {
- goto L150;
- }
- for (k = 1; k <= nsing; ++k) {
- j = nsing - k + 1;
+ int nsing;
+ for (nsing=0; nsing<n && sdiag[nsing]!=0; nsing++);
+ wa.segment(nsing,n-nsing).setZero();
+ nsing--; // nsing is the last nonsingular index
+
+ for (j = nsing; j>=0; j--) {
sum = 0.;
- jp1 = j + 1;
- if (nsing < jp1) {
- goto L130;
- }
- for (i = jp1; i <= nsing; ++i) {
- sum += r__[i + j * r_dim1] * wa[i];
- /* L120: */
- }
-L130:
+ for (i = j+1; i <= nsing; ++i)
+ sum += r(i,j) * wa[i];
wa[j] = (wa[j] - sum) / sdiag[j];
- /* L140: */
}
-L150:
/* permute the components of z back to components of x. */
-
- for (j = 1; j <= n; ++j) {
- l = ipvt[j];
- x[l] = wa[j];
- /* L160: */
- }
- return;
-
- /* last card of subroutine qrsolv. */
-
-} /* qrsolv_ */
+ for (j = 0; j < n; ++j) x[ipvt[j]] = wa[j];
+}