MatrixOperators.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: MatrixOperators.hpp 2598 2011-05-16 05:19:42Z yanweignss $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //  
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00030 #ifndef GPSTK_MATRIX_OPERATORS_HPP
00031 #define GPSTK_MATRIX_OPERATORS_HPP
00032 
00033 #include <limits>
00034 #include "MiscMath.hpp"
00035 #include "MatrixFunctors.hpp"
00036 
00037 namespace gpstk
00038 {
00041  
00046    template <class T, class BaseClass1, class BaseClass2>
00047    inline Matrix<T> operator&&(const ConstMatrixBase<T, BaseClass1>& l, 
00048                             const ConstMatrixBase<T, BaseClass2>& r) 
00049    throw(MatrixException)
00050    {
00051       if (l.cols() != r.cols())
00052       {
00053          MatrixException e("Incompatible dimensions for Matrix && Matrix");
00054          GPSTK_THROW(e);
00055       }
00056 
00057       size_t rows = l.rows() + r.rows();
00058       size_t cols = l.cols();
00059       Matrix<T> toReturn(rows, cols);
00060 
00061       for (rows = 0; rows < l.rows(); rows++)
00062          for (cols = 0; cols < l.cols(); cols++)
00063             toReturn(rows, cols) = l(rows, cols);
00064 
00065       for (rows = 0; rows < r.rows(); rows++)
00066          for (cols = 0; cols < l.cols(); cols++)
00067             toReturn(rows + l.rows(), cols) = r(rows, cols);
00068 
00069       return toReturn;
00070    }
00071 
00076    template <class T, class BaseClass1, class BaseClass2>
00077    inline Matrix<T> operator&&(const ConstMatrixBase<T, BaseClass1>& t, 
00078                             const ConstVectorBase<T, BaseClass2>& b) 
00079    throw(MatrixException)
00080    {
00081       if (t.cols() != b.size())
00082       {
00083          MatrixException e("Incompatible dimensions for Matrix && Vector");
00084          GPSTK_THROW(e);
00085       }
00086 
00087       size_t rows = t.rows() + 1;
00088       size_t cols = t.cols();
00089       Matrix<T> toReturn(rows, cols);
00090 
00091       for (rows = 0; rows < t.rows(); rows++)
00092          for (cols = 0; cols < t.cols(); cols++)
00093             toReturn(rows, cols) = t(rows, cols);
00094 
00095       for (cols = 0; cols < t.cols(); cols++)
00096          toReturn(t.rows(), cols) = b(cols);
00097 
00098       return toReturn;
00099    }
00100 
00105    template <class T, class BaseClass1, class BaseClass2>
00106    inline Matrix<T> operator&&(const ConstVectorBase<T, BaseClass1>& t, 
00107                             const ConstMatrixBase<T, BaseClass2>& b) 
00108    throw(MatrixException)
00109    {
00110       if (t.size() != b.cols())
00111       {
00112          MatrixException e("Incompatible dimensions for Vector && Matrix");
00113          GPSTK_THROW(e);
00114       }
00115 
00116       size_t rows = 1 + b.rows();
00117       size_t cols = b.cols();
00118       Matrix<T> toReturn(rows, cols);
00119 
00120       for (cols = 0; cols < b.cols(); cols++)
00121          toReturn(0, cols) = t(cols);
00122 
00123       for (rows = 1; rows < b.rows()+1; rows++)
00124          for (cols = 0; cols < b.cols(); cols++)
00125             toReturn(rows, cols) = b(rows, cols);
00126 
00127       return toReturn;
00128    }
00129 
00134    template <class T, class BaseClass1, class BaseClass2>
00135    inline Matrix<T> operator||(const ConstMatrixBase<T, BaseClass1>& l,
00136                             const ConstMatrixBase<T, BaseClass2>& r)  
00137       throw(MatrixException)
00138    {
00139       if (l.rows() != r.rows())
00140       {
00141          MatrixException e("Incompatible dimensions for Matrix || Matrix");
00142          GPSTK_THROW(e);
00143       }
00144 
00145       size_t rows = l.rows();
00146       size_t cols = l.cols() + r.cols();
00147       Matrix<T> toReturn(rows, cols);
00148 
00149       for (cols = 0; cols < l.cols(); cols++)
00150          for (rows = 0; rows < l.rows(); rows++)
00151             toReturn(rows, cols) = l(rows, cols);
00152 
00153       for (cols = 0; cols < r.cols(); cols++)
00154          for (rows = 0; rows < l.rows(); rows++)
00155             toReturn(rows, cols + l.cols()) = r(rows,cols);
00156 
00157       return toReturn;
00158    }
00159 
00164    template <class T, class BaseClass1, class BaseClass2>
00165    inline Matrix<T> operator||(const ConstMatrixBase<T, BaseClass1>& l,
00166                             const ConstVectorBase<T, BaseClass2>& r)
00167       throw(MatrixException)
00168    {
00169       if (l.rows() != r.size())
00170       {
00171          MatrixException e("Incompatible dimensions for Matrix || Vector");
00172          GPSTK_THROW(e);
00173       }
00174 
00175       size_t rows = l.rows();
00176       size_t cols = l.cols() + 1;
00177       Matrix<T> toReturn(rows, cols);
00178 
00179       for (cols = 0; cols < l.cols(); cols++)
00180          for (rows = 0; rows < l.rows(); rows++)
00181             toReturn(rows, cols) = l(rows, cols);
00182 
00183       for (rows = 0; rows < l.rows(); rows++)
00184          toReturn(rows, l.cols()) = r(rows);
00185 
00186       return toReturn;
00187    }
00188 
00193    template <class T, class BaseClass1, class BaseClass2>
00194    inline Matrix<T> operator||(const ConstVectorBase<T, BaseClass1>& l,
00195                             const ConstMatrixBase<T, BaseClass2>& r)
00196       throw(MatrixException)
00197    {
00198       if (l.size() != r.rows())
00199       {
00200          MatrixException e("Incompatible dimensions for Vector || Matrix");
00201          GPSTK_THROW(e);
00202       }
00203 
00204       size_t rows = r.rows();
00205       size_t cols = r.cols() + 1;
00206       Matrix<T> toReturn(rows, cols);
00207 
00208       for (rows = 0; rows < r.rows(); rows++)
00209          toReturn(rows, 0) = l(rows);
00210 
00211       for (cols = 1; cols < r.cols()+1; cols++)
00212          for (rows = 0; rows < r.rows(); rows++)
00213             toReturn(rows, cols) = r(rows, cols);
00214 
00215       return toReturn;
00216    }
00217 
00222    template <class T, class BaseClass>
00223    inline Matrix<T> minorMatrix(const ConstMatrixBase<T, BaseClass>& l,
00224                           size_t row, size_t col) 
00225       throw(MatrixException)
00226    {
00227       if ((row >= l.rows()) || (col >= l.cols()))
00228       {
00229          MatrixException e("Invalid row or column for minorMatrix()");
00230          GPSTK_THROW(e);
00231       }
00232          // handle special cases
00233       if (row == 0)
00234       {
00235          if (col == 0)
00236          {
00237             return Matrix<T>(l,1,1,l.rows()-1,l.cols()-1);  
00238          }
00239          else if (col == (l.cols() - 1))
00240          {
00241             return Matrix<T>(l,1,0,l.rows()-1,l.cols()-1);
00242          }
00243          else
00244          {
00245             return Matrix<T>(l,1,0,l.rows()-1,col) ||
00246                Matrix<T>(l,1,col+1,l.rows()-1,l.cols()-col-1);
00247          }
00248       }
00249       else if (row == (l.rows() - 1))
00250       {
00251          if (col == 0)
00252          {
00253             return Matrix<T>(l,0,1,l.rows()-1,l.cols()-1);
00254          }
00255          else if (col == (l.cols() - 1))
00256          {
00257             return Matrix<T>(l,0,0,l.rows()-1,l.cols()-1);
00258          }
00259          else
00260          {
00261             return Matrix<T>(l,0,0,l.rows()-1,col) ||
00262                Matrix<T>(l,0,col+1,l.rows()-1,l.cols()-col-1);
00263          }
00264       }
00265       else if (col == 0)
00266       {
00267          return Matrix<T>(l,0,1,row,l.cols()-1) &&
00268             Matrix<T>(l,row+1,1,l.rows()-row-1,l.cols()-1);
00269       }
00270       else if (col == (l.cols() - 1))
00271       {
00272          return Matrix<T>(l,0,0,row,l.cols()-1) &&
00273             Matrix<T>(l,row+1,0,l.rows()-row-1,l.cols()-1);
00274       }
00275       else
00276       {
00277          return (Matrix<T>(l, 0, 0, row, col) || 
00278                  Matrix<T>(l, 0, col + 1, row, l.cols()-col-1)) &&
00279             (Matrix<T>(l, row + 1, 0, l.rows()-row-1, col) ||
00280              Matrix<T>(l, row + 1, col + 1, l.rows()-row-1, l.cols()-col-1));
00281       }
00282    }
00283 
00287    template <class T, class BaseClass>
00288    inline Matrix<T> transpose(const ConstMatrixBase<T, BaseClass>& m)
00289    {
00290       Matrix<T> temp(m.cols(), m.rows());
00291       size_t i, j;
00292       for (i = 0; i < m.rows(); i++)
00293          for (j = 0; j < m.cols(); j++)
00294             temp(j,i) = m(i,j);
00295       return temp;
00296    }
00297  
00301    template <class T, class BaseClass>
00302    inline T det(const ConstMatrixBase<T, BaseClass>& m) 
00303       throw(MatrixException)
00304    {
00305       try
00306       {
00307          LUDecomp<T> LU;
00308          LU(m);
00309          return LU.det();
00310       }
00311       catch(MatrixException& e)
00312       {
00313          e.addText("in det()");
00314          GPSTK_RETHROW(e);
00315       }
00316    }
00317 
00321    template <class T, class BaseClass>
00322    inline T condNum(const ConstMatrixBase<T, BaseClass>& m, T& big, T& small) 
00323       throw ()
00324    {
00325       SVD<T> svd;
00326       svd(m);
00327       // SVD will not always sort singular values in descending order
00328       svd.sort(true);
00329       big = svd.S(0);
00330       small = svd.S(svd.S.size()-1);
00331       if(small <= std::numeric_limits<T>::epsilon())
00332          return T(0);
00333       return big/small;
00334    }
00335 
00339    template <class T, class BaseClass>
00340    inline T condNum(const ConstMatrixBase<T, BaseClass>& m) 
00341       throw ()
00342    {
00343       T big, small;
00344       return condNum(m, big, small);
00345    }
00346 
00350    template <class T>
00351    inline Matrix<T> ident(size_t dim)
00352       throw(MatrixException)
00353    {
00354       if (dim == 0)
00355       {
00356          MatrixException e("Invalid (0) dimension for ident()");
00357          GPSTK_THROW(e);
00358       }
00359       Matrix<T> toReturn(dim, dim, T(0));
00360       size_t i;
00361       for (i = 0; i < toReturn.rows(); i++)
00362          toReturn(i,i) = T(1);
00363       return toReturn;
00364    }
00365 
00369    template <class T, class BaseClass>
00370    inline Matrix<T> diag(const ConstMatrixBase<T, BaseClass>& m)
00371       throw(MatrixException)
00372    {
00373       if ( (m.rows() != m.cols()) || (m.cols() < 1) )
00374       {
00375          MatrixException e("invalid matrix dimensions for ident()");
00376          GPSTK_THROW(e);
00377       }
00378 
00379       const size_t dim = m.rows();
00380 
00381       Matrix<T> temp(dim, dim, T(0));
00382       for (size_t i = 0; i < dim; i++)
00383          temp(i,i) = m(i,i);
00384 
00385       return temp;
00386    }
00387 
00391    template <class T, class BaseClass>
00392    inline Matrix<T> blkdiag(const ConstMatrixBase<T, BaseClass>& m1,
00393                             const ConstMatrixBase<T, BaseClass>& m2)
00394       throw(MatrixException)
00395    {
00396       if ( (m1.rows() != m1.cols()) || (m1.cols() < 1) ||
00397            (m2.rows() != m2.cols()) || (m2.cols() < 1) )
00398       {
00399          MatrixException e("Invalid matrix dimensions of input.");
00400          GPSTK_THROW(e);
00401       }
00402 
00403       const size_t dim1 = m1.rows();
00404       const size_t dim2 = m2.rows();
00405 
00406       Matrix<T> temp(dim1+dim2, dim1+dim2, T(0));
00407       for (size_t i = 0; i < dim1; i++)
00408       {
00409          for(size_t j = 0; j < dim1; j++)
00410          {
00411             temp(i,j) = m1(i,j);
00412          }
00413       }
00414       for (size_t i = 0; i < dim2; i++)
00415       {
00416          for(size_t j = 0; j < dim2; j++)
00417          {
00418             temp(i+dim1,j+dim1) = m2(i,j);
00419          }
00420       }
00421 
00422       return temp;
00423    }
00424 
00425    template <class T, class BaseClass>
00426    inline Matrix<T> blkdiag(const ConstMatrixBase<T, BaseClass>& m1,
00427                             const ConstMatrixBase<T, BaseClass>& m2,
00428                             const ConstMatrixBase<T, BaseClass>& m3)
00429       throw(MatrixException)
00430    { return blkdiag( blkdiag(m1,m2), m3 ); }
00431 
00432    template <class T, class BaseClass>
00433    inline Matrix<T> blkdiag(const ConstMatrixBase<T, BaseClass>& m1,
00434                             const ConstMatrixBase<T, BaseClass>& m2,
00435                             const ConstMatrixBase<T, BaseClass>& m3,
00436                             const ConstMatrixBase<T, BaseClass>& m4)
00437       throw(MatrixException)
00438    { return blkdiag( blkdiag(m1,m2,m3), m4 ); }
00439 
00440 
00445    template <class T>
00446    inline Matrix<T> rotation(T angle, int axis)
00447       throw(MatrixException)
00448    {
00449       if (axis < 1 || axis > 3)
00450       {
00451          MatrixException e("Invalid axis (must be 1,2, or 3)");
00452          GPSTK_THROW(e);
00453       }
00454       Matrix<T> toReturn(3,3,T(0));
00455       int i1 = axis-1;
00456       int i2 = (i1+1) % 3;
00457       int i3 = (i2+1) % 3;
00458       toReturn(i1,i1) = 1.0;
00459       toReturn(i2,i2) = toReturn(i3,i3) = ::cos(angle);
00460       toReturn(i3,i2) = -(toReturn(i2,i3) = ::sin(angle));
00461 
00462       return toReturn;
00463    }
00464 
00469    template <class T, class BaseClass>
00470    inline Matrix<T> inverse(const ConstMatrixBase<T, BaseClass>& m)
00471       throw (MatrixException)
00472    {
00473       if ((m.rows() != m.cols()) || (m.cols() == 0))
00474       {
00475          MatrixException e("inverse() requires non-trivial square matrix");
00476          GPSTK_THROW(e);
00477       }
00478 
00479       Matrix<T> toReturn(m.rows(), m.cols() * 2);
00480 
00481       size_t r, t, j;
00482       T temp;
00483 
00484          // set the left half to m
00485       {
00486          MatrixSlice<T> ms(toReturn, 0, 0, m.rows(), m.cols());
00487          ms = m;
00488       }
00489 
00490          // set the right half to identity
00491       {
00492          MatrixSlice<T> ms(toReturn, 0, m.cols(), m.rows(), m.cols());
00493          ident(ms);
00494       }
00495 
00496       for (r = 0; r < m.rows(); r++)
00497       {
00498             // if m(r,r) is zero, find another row
00499             // to add to it...
00500          if (toReturn(r,r) == 0)
00501          {
00502             t = r+1;
00503             while ( (t < m.rows()) && (toReturn(t,r) == 0) )
00504                t++;
00505 
00506             if (t == m.rows())
00507             {
00508                SingularMatrixException e("Singular matrix");
00509                GPSTK_THROW(e);
00510             }
00511 
00512             for (j = r; j < toReturn.cols(); j++)
00513                toReturn(r,j) += (toReturn(t,j) / toReturn(t,r));
00514          }
00515 
00516             // scale this row's (r,r)'th element to 1
00517          temp = toReturn(r,r);
00518          for (j = r; j < toReturn.cols(); j++)
00519             toReturn(r,j) /= temp;
00520 
00521             // do the elimination
00522          for (t = 0; t < m.rows(); t++)
00523          {
00524             if (t != r)
00525             {
00526                temp = toReturn(t,r);
00527                for (j = r; j < toReturn.cols(); j++)
00528                   toReturn(t,j) -= temp/toReturn(r,r) * toReturn(r,j);
00529             }
00530          }
00531       }
00532          // return the right hand side square matrix
00533       return Matrix<T>(toReturn, 0, m.cols(), m.rows(), m.cols());
00534 
00535    }  // end inverse
00536 
00541    template <class T, class BaseClass>
00542    inline Matrix<T> inverseLUD(const ConstMatrixBase<T, BaseClass>& m)
00543       throw (MatrixException)
00544    {
00545       if ((m.rows() != m.cols()) || (m.cols() == 0)) {
00546          MatrixException e("inverseLUD() requires non-trivial square matrix");
00547          GPSTK_THROW(e);
00548       }
00549 
00550       size_t i,j,N=m.rows();
00551       Matrix<T> inv(m);
00552       Vector<T> V(N);
00553       LUDecomp<T> LU;
00554       LU(m);
00555       for(j=0; j<N; j++) {    // loop over columns
00556          V = T(0);
00557          V(j) = T(1);
00558          LU.backSub(V);
00559          for(i=0; i<N; i++) inv(i,j)=V(i);
00560       }
00561       return inv;
00562 
00563    }  // end inverseLUD
00564 
00569    template <class T, class BaseClass>
00570    inline Matrix<T> inverseLUD(const ConstMatrixBase<T, BaseClass>& m, T& determ)
00571       throw (MatrixException)
00572    {
00573       if ((m.rows() != m.cols()) || (m.cols() == 0)) {
00574          MatrixException e("inverseLUD() requires non-trivial square matrix");
00575          GPSTK_THROW(e);
00576       }
00577 
00578       size_t i,j,N=m.rows();
00579       Matrix<T> inv(m);
00580       Vector<T> V(N);
00581       LUDecomp<T> LU;
00582       LU(m);
00583       // compute determinant
00584       determ = T(LU.parity);
00585       for(i = 0; i < m.rows(); i++) determ *= LU.LU(i,i);
00586       // compute inverse
00587       for(j=0; j<N; j++) {    // loop over columns
00588          V = T(0);
00589          V(j) = T(1);
00590          LU.backSub(V);
00591          for(i=0; i<N; i++) inv(i,j)=V(i);
00592       }
00593       return inv;
00594 
00595    }  // end inverseLUD
00596 
00601    template <class T, class BaseClass>
00602    inline Matrix<T> inverseSVD(const ConstMatrixBase<T, BaseClass>& m,
00603          const T tol=T(1.e-8)) throw (MatrixException)
00604    {
00605       if ((m.rows() != m.cols()) || (m.cols() == 0)) {
00606          MatrixException e("inverseSVD() requires non-trivial square matrix");
00607          GPSTK_THROW(e);
00608       }
00609 
00610       size_t i,j,N=m.rows();
00611       Matrix<T> inv(m);
00612       SVD<T> svd;
00613       svd(m);
00614       // SVD will not always sort singular values in descending order
00615       svd.sort(true);
00616       if(svd.S(0) == T(0)) {
00617          MatrixException e("Input is the zero matrix");
00618          GPSTK_THROW(e);
00619       }
00620       // edit singular values TD input tolerance, output edited SVs
00621       for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00622       // back substitution
00623       Vector<T> V(N);
00624       for(j=0; j<N; j++) {    //loop over columns
00625          V = T(0);
00626          V(j) = T(1);
00627          svd.backSub(V);
00628          for(i=0; i<N; i++) inv(i,j)=V(i);
00629       }
00630       return inv;
00631 
00632    }  // end inverseSVD
00633 
00639    template <class T, class BaseClass>
00640    inline Matrix<T> inverseSVD(const ConstMatrixBase<T, BaseClass>& m,
00641       T& big, T& small, const T tol=T(1.e-8)) throw (MatrixException)
00642    {
00643       if ((m.rows() != m.cols()) || (m.cols() == 0)) {
00644          MatrixException e("inverseSVD() requires non-trivial square matrix");
00645          GPSTK_THROW(e);
00646       }
00647 
00648       size_t i,j,N=m.rows();
00649       Matrix<T> inv(m);
00650       SVD<T> svd;
00651       svd(m);
00652       // SVD will not always sort singular values in descending order
00653       svd.sort(true);
00654       if(svd.S(0) == T(0)) {
00655          MatrixException e("Input is the zero matrix");
00656          GPSTK_THROW(e);
00657       }
00658 
00659       // compute condition number = big/small
00660       big = svd.S(0);
00661       small = svd.S(svd.S.size()-1);
00662 
00663       // edit singular values using input tolerance, output edited SVs
00664       for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00665 
00666       // back substitution
00667       Vector<T> V(N);
00668       for(j=0; j<N; j++) {    //loop over columns
00669          V = T(0);
00670          V(j) = T(1);
00671          svd.backSub(V);
00672          for(i=0; i<N; i++) inv(i,j)=V(i);
00673       }
00674       return inv;
00675 
00676    }  // end inverseSVD
00677 
00683    template <class T, class BaseClass>
00684    inline Matrix<T> inverseSVD(const ConstMatrixBase<T, BaseClass>& m,
00685       Vector<T>& sv, const T tol=T(1.e-8)) throw (MatrixException)
00686    {
00687       if ((m.rows() != m.cols()) || (m.cols() == 0)) {
00688          MatrixException e("inverseSVD() requires non-trivial square matrix");
00689          GPSTK_THROW(e);
00690       }
00691 
00692       size_t i,j,N=m.rows();
00693       Matrix<T> inv(m);
00694       SVD<T> svd;
00695       svd(m);
00696       // SVD will not always sort singular values in descending order
00697       svd.sort(true);
00698       if(svd.S(0) == T(0)) {
00699          MatrixException e("Input is the zero matrix");
00700          GPSTK_THROW(e);
00701       }
00702 
00703       // save the singular values
00704       sv = Vector<T>(N);
00705       for(i=0; i<N; i++) sv(i) = svd.S(i);
00706 
00707       // edit singular values using input tolerance, output edited SVs
00708       for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00709 
00710       // back substitution
00711       Vector<T> V(N);
00712       for(j=0; j<N; j++) {    //loop over columns
00713          V = T(0);
00714          V(j) = T(1);
00715          svd.backSub(V);
00716          for(i=0; i<N; i++) inv(i,j)=V(i);
00717       }
00718       return inv;
00719 
00720    }  // end inverseSVD
00721 
00727    template <class T, class BaseClass>
00728    inline Matrix<T> inverseChol(const ConstMatrixBase<T, BaseClass>& m)
00729        throw (MatrixException)
00730    {
00731        int N = m.rows(), i, j, k;
00732        double sum;
00733        Matrix<T> LI(N,N, 0.0);      // Here we will first store L^-1, and later m^-1
00734 
00735        // Let's call CholeskyCrout class to decompose matrix "m" in L*LT
00736        gpstk::CholeskyCrout<double> CC;
00737        CC(m);
00738 
00739        // Let's find the inverse of L (the LI from above)
00740        for(i=0; i<N; i++) {
00741            LI(i,i) = 1.0 / CC.L(i,i);
00742            for(j=0; j<i; j++) {
00743                sum = 0.0;
00744                for(k=i; k>=0; k-- ) sum += CC.L(i,k)*LI(k,j);
00745                LI(i,j) = -sum*LI(i,i);
00746            }
00747        }
00748 
00749        // Now, let's remember that m^-1 = transpose(LI)*LI
00750        LI = transpose(LI) * LI;
00751        return LI;
00752 
00753    }  // end inverseChol
00754 
00755 
00759    template <class T, class BaseClass1, class BaseClass2>
00760    inline Matrix<T> operator* (const ConstMatrixBase<T, BaseClass1>& l, 
00761                             const ConstMatrixBase<T, BaseClass2>& r)
00762       throw (MatrixException)
00763    {
00764       if (l.cols() != r.rows())
00765       {
00766          MatrixException e("Incompatible dimensions for Matrix * Matrix");
00767          GPSTK_THROW(e);
00768       }
00769    
00770       Matrix<T> toReturn(l.rows(), r.cols(), T(0));
00771       size_t i, j, k;
00772       for (i = 0; i < toReturn.rows(); i++)
00773          for (j = 0; j < toReturn.cols(); j++)
00774             for (k = 0; k < l.cols(); k++)
00775                toReturn(i,j) += l(i,k) * r(k,j);
00776 
00777       return toReturn;
00778    }
00779 
00783    template <class T, class BaseClass1, class BaseClass2>
00784    inline Vector<T> operator* (const ConstMatrixBase<T, BaseClass1>& m, 
00785                             const ConstVectorBase<T, BaseClass2>& v)
00786       throw (MatrixException)
00787    {
00788       if (v.size() != m.cols())
00789       {
00790          gpstk::MatrixException e("Incompatible dimensions for Vector * Matrix");
00791          GPSTK_THROW(e);
00792       }
00793    
00794       Vector<T> toReturn(m.rows());
00795       size_t i, j;
00796       for (i = 0; i < m.rows(); i++) 
00797       {
00798          toReturn[i] = 0;
00799          for (j = 0; j < m.cols(); j++)
00800             toReturn[i] += m(i, j) * v[j];
00801       }
00802       return toReturn;
00803    }
00807    template <class T, class BaseClass1, class BaseClass2>
00808    inline Vector<T> operator* (const ConstVectorBase<T, BaseClass1>& v, 
00809                             const ConstMatrixBase<T, BaseClass2>& m)
00810       throw (gpstk::MatrixException)
00811    {
00812       if (v.size() != m.rows())
00813       {
00814          gpstk::MatrixException e("Incompatible dimensions for Vector * Matrix");
00815          GPSTK_THROW(e);
00816       }
00817    
00818       Vector<T> toReturn(m.cols());
00819       size_t i, j;
00820       for (i = 0; i < m.cols(); i++) 
00821       {
00822          toReturn[i] = 0;
00823          for (j = 0; j < m.rows(); j++)
00824             toReturn[i] += m(j,i) * v[j];
00825       }
00826       return toReturn;
00827    }
00828 
00832    template <class T, class BaseClass1, class BaseClass2>
00833    inline Matrix<T> operator+ (const ConstMatrixBase<T, BaseClass1>& l,
00834                             const ConstMatrixBase<T, BaseClass2>& r)
00835       throw (MatrixException)
00836    {
00837       if (l.cols() != r.cols() || l.rows() != r.rows())
00838       {
00839          MatrixException e("Incompatible dimensions for Matrix + Matrix");
00840          GPSTK_THROW(e);
00841       }
00842 
00843       Matrix<T> toReturn(l.rows(), r.cols(), T(0));
00844       size_t i, j;
00845       for (i = 0; i < toReturn.rows(); i++)
00846          for (j = 0; j < toReturn.cols(); j++)
00847             toReturn(i,j) = l(i,j) + r(i,j);
00848 
00849       return toReturn;
00850    }
00851 
00855    template <class T, class BaseClass1, class BaseClass2>
00856    inline Matrix<T> operator- (const ConstMatrixBase<T, BaseClass1>& l,
00857                             const ConstMatrixBase<T, BaseClass2>& r)
00858       throw (MatrixException)
00859    {
00860       if (l.cols() != r.cols() || l.rows() != r.rows())
00861       {
00862          MatrixException e("Incompatible dimensions for Matrix - Matrix");
00863          GPSTK_THROW(e);
00864       }
00865 
00866       Matrix<T> toReturn(l.rows(), r.cols(), T(0));
00867       size_t i, j;
00868       for (i = 0; i < toReturn.rows(); i++)
00869          for (j = 0; j < toReturn.cols(); j++)
00870             toReturn(i,j) = l(i,j) - r(i,j);
00871 
00872       return toReturn;
00873    }
00874 
00878    template <class T, class BaseClass>
00879    inline Matrix<T> outer(const ConstVectorBase<T, BaseClass>& v,
00880                         const ConstVectorBase<T, BaseClass>& w)
00881       throw (MatrixException)
00882    {
00883       if(v.size()*w.size() == 0) {
00884          MatrixException e("Zero length vector(s)");
00885          GPSTK_THROW(e);
00886       }
00887       Matrix<T> M(v.size(),w.size(),T(0));
00888       for(size_t i=0; i<v.size(); i++)
00889          for(size_t j=0; j<w.size(); j++)
00890             M(i,j) = v(i)*w(j);
00891       return M;
00892    }
00893 
00895    template <class T, class BaseClass>
00896    inline Matrix<T> operator* (const ConstMatrixBase<T, BaseClass>& m, const T d)
00897    {
00898       Matrix<T> temp(m);
00899       return temp *= d;
00900    }
00901 
00903    template <class T, class BaseClass>
00904    inline Matrix<T> operator* (const T d, const ConstMatrixBase<T, BaseClass>& m)
00905    {
00906       Matrix<T> temp(m);
00907       return temp *= d;
00908    }
00909 
00911    template <class T, class BaseClass>
00912    inline Matrix<T> operator/ (const ConstMatrixBase<T, BaseClass>& m, const T d)
00913    {
00914       Matrix<T> temp(m);
00915       return temp /= d;
00916    }
00917 
00919    template <class T, class BaseClass>
00920    inline Matrix<T> operator/ (const T d, const ConstMatrixBase<T, BaseClass>& m)
00921    {
00922       Matrix<T> temp(m);
00923       return temp /= d;
00924    }
00925 
00927    template <class T, class BaseClass>
00928    inline Matrix<T> operator+ (const ConstMatrixBase<T, BaseClass>& m, const T d)
00929    {
00930       Matrix<T> temp(m);
00931       return temp += d;
00932    }
00933 
00935    template <class T, class BaseClass>
00936    inline Matrix<T> operator+ (const T d, const ConstMatrixBase<T, BaseClass>& m)
00937    {
00938       Matrix<T> temp(m);
00939       return temp += d;
00940    }
00941 
00943    template <class T, class BaseClass>
00944    inline Matrix<T> operator- (const ConstMatrixBase<T, BaseClass>& m, const T d)
00945    {
00946       Matrix<T> temp(m);
00947       return temp -= d;
00948    }
00949 
00951    template <class T, class BaseClass>
00952    inline Matrix<T> operator- (const T d, const ConstMatrixBase<T, BaseClass>& m)
00953    {
00954       Matrix<T> temp(m);
00955       return temp -= d;
00956    }
00957 
00959  
00960 }  // namespace
00961 
00962 #endif

Generated on Wed Feb 8 03:31:00 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1