00001 #pragma ident "$Id: MatrixOperators.hpp 2598 2011-05-16 05:19:42Z yanweignss $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
00485 {
00486 MatrixSlice<T> ms(toReturn, 0, 0, m.rows(), m.cols());
00487 ms = m;
00488 }
00489
00490
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
00499
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
00517 temp = toReturn(r,r);
00518 for (j = r; j < toReturn.cols(); j++)
00519 toReturn(r,j) /= temp;
00520
00521
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
00533 return Matrix<T>(toReturn, 0, m.cols(), m.rows(), m.cols());
00534
00535 }
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++) {
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 }
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
00584 determ = T(LU.parity);
00585 for(i = 0; i < m.rows(); i++) determ *= LU.LU(i,i);
00586
00587 for(j=0; j<N; j++) {
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 }
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
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
00621 for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00622
00623 Vector<T> V(N);
00624 for(j=0; j<N; j++) {
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 }
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
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
00660 big = svd.S(0);
00661 small = svd.S(svd.S.size()-1);
00662
00663
00664 for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00665
00666
00667 Vector<T> V(N);
00668 for(j=0; j<N; j++) {
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 }
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
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
00704 sv = Vector<T>(N);
00705 for(i=0; i<N; i++) sv(i) = svd.S(i);
00706
00707
00708 for(i=1; i<N; i++) if(svd.S(i) < tol*svd.S(0)) svd.S(i)=T(0);
00709
00710
00711 Vector<T> V(N);
00712 for(j=0; j<N; j++) {
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 }
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);
00734
00735
00736 gpstk::CholeskyCrout<double> CC;
00737 CC(m);
00738
00739
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
00750 LI = transpose(LI) * LI;
00751 return LI;
00752
00753 }
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 }
00961
00962 #endif