r1updt.h
Go to the documentation of this file.
00001 namespace internal {
00002 
00003 template <typename Scalar>
00004 void r1updt(
00005         Matrix< Scalar, Dynamic, Dynamic > &s,
00006         const Matrix< Scalar, Dynamic, 1> &u,
00007         std::vector<JacobiRotation<Scalar> > &v_givens,
00008         std::vector<JacobiRotation<Scalar> > &w_givens,
00009         Matrix< Scalar, Dynamic, 1> &v,
00010         Matrix< Scalar, Dynamic, 1> &w,
00011         bool *sing)
00012 {
00013     typedef DenseIndex Index;
00014     const JacobiRotation<Scalar> IdentityRotation = JacobiRotation<Scalar>(1,0);
00015 
00016     /* Local variables */
00017     const Index m = s.rows();
00018     const Index n = s.cols();
00019     Index i, j=1;
00020     Scalar temp;
00021     JacobiRotation<Scalar> givens;
00022 
00023     // r1updt had a broader usecase, but we dont use it here. And, more
00024     // importantly, we can not test it.
00025     assert(m==n);
00026     assert(u.size()==m);
00027     assert(v.size()==n);
00028     assert(w.size()==n);
00029 
00030     /* move the nontrivial part of the last column of s into w. */
00031     w[n-1] = s(n-1,n-1);
00032 
00033     /* rotate the vector v into a multiple of the n-th unit vector */
00034     /* in such a way that a spike is introduced into w. */
00035     for (j=n-2; j>=0; --j) {
00036         w[j] = 0.;
00037         if (v[j] != 0.) {
00038             /* determine a givens rotation which eliminates the */
00039             /* j-th element of v. */
00040             givens.makeGivens(-v[n-1], v[j]);
00041 
00042             /* apply the transformation to v and store the information */
00043             /* necessary to recover the givens rotation. */
00044             v[n-1] = givens.s() * v[j] + givens.c() * v[n-1];
00045             v_givens[j] = givens;
00046 
00047             /* apply the transformation to s and extend the spike in w. */
00048             for (i = j; i < m; ++i) {
00049                 temp = givens.c() * s(j,i) - givens.s() * w[i];
00050                 w[i] = givens.s() * s(j,i) + givens.c() * w[i];
00051                 s(j,i) = temp;
00052             }
00053         } else
00054             v_givens[j] = IdentityRotation;
00055     }
00056 
00057     /* add the spike from the rank 1 update to w. */
00058     w += v[n-1] * u;
00059 
00060     /* eliminate the spike. */
00061     *sing = false;
00062     for (j = 0; j < n-1; ++j) {
00063         if (w[j] != 0.) {
00064             /* determine a givens rotation which eliminates the */
00065             /* j-th element of the spike. */
00066             givens.makeGivens(-s(j,j), w[j]);
00067 
00068             /* apply the transformation to s and reduce the spike in w. */
00069             for (i = j; i < m; ++i) {
00070                 temp = givens.c() * s(j,i) + givens.s() * w[i];
00071                 w[i] = -givens.s() * s(j,i) + givens.c() * w[i];
00072                 s(j,i) = temp;
00073             }
00074 
00075             /* store the information necessary to recover the */
00076             /* givens rotation. */
00077             w_givens[j] = givens;
00078         } else
00079             v_givens[j] = IdentityRotation;
00080 
00081         /* test for zero diagonal elements in the output s. */
00082         if (s(j,j) == 0.) {
00083             *sing = true;
00084         }
00085     }
00086     /* move w back into the last column of the output s. */
00087     s(n-1,n-1) = w[n-1];
00088 
00089     if (s(j,j) == 0.) {
00090         *sing = true;
00091     }
00092     return;
00093 }
00094 
00095 } // end namespace internal


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:33:16