00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef TINY_MATRIX_HPP
00021 #define TINY_MATRIX_HPP
00022
00023 #include <TinyVector.hpp>
00024
00035 template <size_t M, size_t N,
00036 typename T=real_t>
00037 class TinyMatrix
00038 {
00039 public:
00040 typedef TinyVector<N>
00041 AssociatedVector;
00043 typedef TinyVector<M>
00044 AssociatedTransposedVector;
00047 typedef T ValueType;
00050 enum {
00051 NumberOfLines = M,
00052 NumberOfRow = N
00053 };
00054
00055 private:
00056 T __x[M][N];
00058 public:
00059
00068 inline T& operator()(const size_t& i, const size_t& j)
00069 {
00070 ASSERT ((i<M) && (j<N));
00071 return __x[i][j];
00072 }
00073
00082 inline const T& operator()(const size_t& i, const size_t& j) const
00083 {
00084 ASSERT ((i<M) && (j<N));
00085 return __x[i][j];
00086 }
00087
00095 inline const TinyMatrix<M,N,T>& operator=(const TinyMatrix<M,N,T>& B)
00096 {
00097 T* y = __x[0];
00098 const T* B_y = B.__x[0];
00099 for (size_t i=0; i<M*N; i++)
00100 y[i] = B_y[i];
00101 return (*this);
00102 }
00103
00111 inline const TinyMatrix<M,N,T>& operator += (const TinyMatrix<M,N,T>& B)
00112 {
00113 T* y = __x[0];
00114 const T* B_y = B.__x[0];
00115 for (size_t i=0; i<M*N; i++)
00116 y[i] += B_y[i];
00117 return (*this);
00118 }
00119
00127 inline const TinyMatrix<M,N,T>& operator -= (const TinyMatrix<M,N,T>& B)
00128 {
00129 T* y = __x[0];
00130 const T* B_y = B.__x[0];
00131 for (size_t i=0; i<M*N; i++)
00132 y[i] -= B_y[i];
00133 return (*this);
00134 }
00135
00143 template <size_t P>
00144 inline TinyMatrix<M,P> operator * (const TinyMatrix<N,P>& B) const
00145 {
00146 TinyMatrix<M,P> C(0);
00147 for (size_t i=0; i<M; i++)
00148 for (size_t j=0; j<P; j++)
00149 for (size_t k=0; k<N; k++)
00150 C(i,j) += __x[i][k] * B(k,j);
00151 return C;
00152 }
00153
00161 inline TinyVector<M,T> operator * (const TinyVector<N,T>& v) const
00162 {
00163 TinyVector<M,T> u = 0;
00164 for (size_t i=0; i<M; i++)
00165 for (size_t j=0; j<N; j++)
00166 u[i] += __x[i][j] * v[j];
00167 return u;
00168 }
00169
00177 inline TinyMatrix<M,N,T> operator * (const T& t) const
00178 {
00179 TinyMatrix<M,N,T> B;
00180 for (size_t i=0; i<M; i++)
00181 for (size_t j=0; j<N; j++)
00182 B.__x[i][j] = __x[i][j] * t;
00183 return B;
00184 }
00185
00193 inline TinyMatrix<M,N,T> operator / (const T& t) const
00194 {
00195 ASSERT(t != 0);
00196 TinyMatrix<M,N,T> B;
00197 const T t_1 = 1./t;
00198 for (size_t i=0; i<M; i++)
00199 for (size_t j=0; j<N; j++)
00200 B.__x[i][j] = __x[i][j] * t_1;
00201 return B;
00202 }
00203
00211 inline const TinyMatrix<M,N,T>& operator *= (const T& t)
00212 {
00213 for (size_t i=0; i<M; i++)
00214 for (size_t j=0; j<N; j++)
00215 __x[i][j] *= t;
00216 return (*this);
00217 }
00218
00226 inline const TinyMatrix<M,N,T>& operator /= (const T& t)
00227 {
00228 const T t_1 = 1./t;
00229 for (size_t i=0; i<M; i++)
00230 for (size_t j=0; j<N; j++)
00231 __x[i][j] *= t_1;
00232 return (*this);
00233 }
00234
00243 inline friend TinyMatrix<M,N,T> operator * (const T& t,
00244 const TinyMatrix<M,N,T>& A)
00245 {
00246 return (A*t);
00247 }
00248
00256 inline TinyMatrix<M,N,T> operator + (const TinyMatrix<M,N,T>& B) const
00257 {
00258 TinyMatrix<M,N,T> C;
00259 for (size_t i=0; i<M; i++)
00260 for (size_t j=0; j<N; j++)
00261 C.__x[i][j] = __x[i][j] + B.__x[i][j];
00262 return C;
00263 }
00264
00272 inline TinyMatrix<M,N,T> operator - (const TinyMatrix<M,N,T>& B) const
00273 {
00274 TinyMatrix<M,N,T> C;
00275 for (size_t i=0; i<M; i++)
00276 for (size_t j=0; j<N; j++)
00277 C.__x[i][j] = __x[i][j] - B.__x[i][j];
00278 return C;
00279 }
00280
00289 friend std::ostream& operator << (std::ostream& os,
00290 const TinyMatrix<M,N,T>& A)
00291 {
00292 for (size_t i=0; i<M; i++) {
00293 for (size_t j=0; j<N; j++)
00294 os << A(i,j) << " ";
00295 os << '\n';
00296 }
00297 return os;
00298 }
00299
00305 TinyMatrix()
00306 {
00307 T* y = __x[0];
00308 for (size_t i=0; i<M*N; i++) {
00309 y[i] = 0;
00310 }
00311 }
00312
00318 TinyMatrix(const TinyMatrix<M,N,T>& B)
00319 {
00320 T* y = __x[0];
00321 const T* B_y = B.__x[0];
00322 for (size_t i=0; i<M*N; i++) {
00323 y[i] = B_y[i];
00324 }
00325 }
00326
00336 TinyMatrix(const T& t)
00337 {
00338 for (size_t i=0; i<M; i++)
00339 for (size_t j=0; j<N; j++)
00340 __x[i][j] = (i==j)?t:0;
00341 }
00342
00347 ~TinyMatrix()
00348 {
00349 ;
00350 }
00351 };
00352
00362 template <size_t N,
00363 typename T>
00364 class TinyMatrix<N,N,T>
00365 {
00366 public:
00367 typedef TinyVector<N>
00368 AssociatedVector;
00370 typedef TinyVector<N>
00371 AssociatedTransposedVector;
00374 typedef T ValueType;
00377 enum {
00378 NumberOfLines = N,
00379 NumberOfRow = N
00380 };
00381
00382 private:
00383 T __x[N][N];
00385 public:
00386
00392 size_t size() const
00393 {
00394 return N;
00395 }
00396
00405 inline T& operator()(const size_t& i, const size_t& j)
00406 {
00407 ASSERT ((i<N) && (j<N));
00408 return __x[i][j];
00409 }
00410
00419 inline const T& operator()(const size_t& i, const size_t& j) const
00420 {
00421 ASSERT ((i<N) && (j<N));
00422 return __x[i][j];
00423 }
00424
00432 inline TinyMatrix<N,N,T> invert() const
00433 {
00434 TinyMatrix<N,N,T> M;
00435 TinyMatrix<N,N,T> lu;
00436 TinyMatrix<N,N,T> P;
00437 LU(*this, lu, P);
00438
00439 TinyVector<N,T> v;
00440 TinyVector<N,T> u;
00441
00442 for (size_t i=0; i<N; ++i) {
00443 for (size_t j=0; j<N; ++j)
00444 v[j] = (i==j)?1:0;
00445
00446 u = lu.applyLU(P*v);
00447 for (size_t j=0; j<N; ++j)
00448 M(j,i) = u[j];
00449 }
00450
00451 return M;
00452 }
00453
00461 inline TinyMatrix<N,N,T>& operator = (const TinyMatrix<N,N,T>& B)
00462 {
00463 for (size_t i=0; i<N; i++)
00464 for (size_t j=0; j<N; j++)
00465 __x[i][j] = B.__x[i][j];
00466 return (*this);
00467 }
00468
00476 inline const TinyMatrix<N,N,T>& operator += (const TinyMatrix<N,N,T>& B)
00477 {
00478 for (size_t i=0; i<N; i++)
00479 for (size_t j=0; j<N; j++)
00480 __x[i][j] += B.__x[i][j];
00481 return (*this);
00482 }
00483
00491 inline const TinyMatrix<N,N,T>& operator -= (const TinyMatrix<N,N,T>& B)
00492 {
00493 for (size_t i=0; i<N; i++)
00494 for (size_t j=0; j<N; j++)
00495 __x[i][j] -= B.__x[i][j];
00496 return (*this);
00497 }
00498
00506 inline const TinyMatrix<N,N,T>& operator = (const T& t)
00507 {
00508 for (size_t i=0; i<N; i++)
00509 for (size_t j=0; j<N; j++)
00510 __x[i][j] = (i==j)?t:0;
00511 return (*this);
00512 }
00513
00521 template <size_t P>
00522 inline TinyMatrix<N,P> operator * (const TinyMatrix<N,P>& B) const
00523 {
00524 TinyMatrix<N,P> C(0);
00525 for (size_t i=0; i<N; i++)
00526 for (size_t j=0; j<P; j++)
00527 for (size_t k=0; k<N; k++)
00528 C(i,j) += __x[i][k] * B(k,j);
00529 return C;
00530 }
00531
00539 inline TinyVector<N,T> operator * (const TinyVector<N,T>& v) const
00540 {
00541 TinyVector<N,T> u = 0;
00542 for (size_t i=0; i<N; i++)
00543 for (size_t j=0; j<N; j++)
00544 u[i] += __x[i][j] * v[j];
00545 return u;
00546 }
00547
00555 inline TinyMatrix<N,N,T> operator * (const T& t) const
00556 {
00557 TinyMatrix<N,N,T> B;
00558 for (size_t i=0; i<N; i++)
00559 for (size_t j=0; j<N; j++)
00560 B.__x[i][j] = __x[i][j] * t;
00561 return B;
00562 }
00563
00571 inline TinyMatrix<N,N,T> operator / (const T& t) const
00572 {
00573 ASSERT (t!=0);
00574 const T t_1 = 1./t;
00575 TinyMatrix<N,N,T> B;
00576 for (size_t i=0; i<N; i++)
00577 for (size_t j=0; j<N; j++)
00578 B.__x[i][j] = __x[i][j] * t_1;
00579 return B;
00580 }
00581
00589 inline const TinyMatrix<N,N,T>& operator *= (const T& t)
00590 {
00591 for (size_t i=0; i<N; i++)
00592 for (size_t j=0; j<N; j++)
00593 __x[i][j] *= t;
00594 return (*this);
00595 }
00596
00604 inline TinyMatrix<N,N,T>& operator /= (const T& t) {
00605 const T t_1 = 1./t;
00606 for (size_t i=0; i<N; i++)
00607 for (size_t j=0; j<N; j++)
00608 __x[i][j] *= t_1;
00609 return (*this);
00610 }
00611
00619 inline TinyMatrix<N,N,T> operator + (const TinyMatrix<N,N,T>& B) const
00620 {
00621 TinyMatrix<N,N,T> C;
00622 for (size_t i=0; i<N; i++)
00623 for (size_t j=0; j<N; j++)
00624 C.__x[i][j] = __x[i][j] + B.__x[i][j];
00625 return C;
00626 }
00627
00635 inline TinyMatrix<N,N,T> operator - (const TinyMatrix<N,N,T>& B) const
00636 {
00637 TinyMatrix<N,N,T> C;
00638 for (size_t i=0; i<N; i++)
00639 for (size_t j=0; j<N; j++)
00640 C.__x[i][j] = __x[i][j] - B.__x[i][j];
00641 return C;
00642 }
00643
00652 inline friend TinyMatrix<N,N,T> operator * (const T& t,
00653 const TinyMatrix<N,N,T>& A)
00654 {
00655 return (A*t);
00656 }
00657
00664 inline TinyMatrix<N,N,T> operator - () const
00665 {
00666 TinyMatrix<N,N,T> B;
00667 for (size_t i=0; i<N; i++)
00668 for (size_t j=0; j<N; j++)
00669 B.__x[i][j] = - __x[i][j];
00670 return B;
00671 }
00672
00681 friend std::ostream& operator << (std::ostream& os,
00682 const TinyMatrix<N,N,T>& A)
00683 {
00684 for (size_t i=0; i<N; i++) {
00685 for (size_t j=0; j<N; j++)
00686 os << A(i,j) << " ";
00687 os << '\n';
00688 }
00689 return os;
00690 }
00691
00699 friend T det(const TinyMatrix<N,N,T>& A)
00700 {
00701 T d = 1.;
00702 TinyMatrix<N,N,T> B = A;
00703
00704 for (size_t k=0; k<N-1; k++) {
00705 size_t maxLine = k;
00706 for (size_t i=k+1; i<N; i++) {
00707 maxLine = (std::abs(B(i,k))>std::abs(B(maxLine,k)))?i:maxLine;
00708 }
00709 if (k != maxLine) {
00710 B.swapLines(k,maxLine);
00711 d *= -1;
00712 }
00713
00714 for(size_t i=k+1; i<N; ++i) {
00715 for (size_t j=k+1; j<N; j++) {
00716 B(i,j) -= B(i,k)*B(k,j)/B(k,k);
00717 }
00718 B(i,k) = 0;
00719 }
00720 }
00721 for (size_t i=0; i<N; ++i)
00722 d *= B(i,i);
00723 return d;
00724 }
00725
00735 template <typename T2>
00736 friend T gaussPivot(const TinyMatrix<N,N,T>& A,
00737 const TinyVector<N,T2>& rightHandSide,
00738 TinyVector<N,T2>& X)
00739 {
00740 T t = 1.;
00741 TinyMatrix<N,N,T> M = A;
00742 TinyVector<N,T2> b = rightHandSide;
00743
00744 for (size_t k=0; k<N-1; k++) {
00745 size_t maxLine = k;
00746 for (size_t i=k+1; i<N; i++) {
00747 maxLine = (std::abs(M(i,k))>std::abs(M(maxLine,k)))?i:maxLine;
00748 }
00749 if (k != maxLine) {
00750 M.swapLines(k,maxLine);
00751 std::swap(b[k], b[maxLine]);
00752 t *= -1;
00753 }
00754
00755 for(size_t i=k+1; i<N; ++i) {
00756 const real_t coef = M(i,k)/M(k,k);
00757 for (size_t j=k; j<N; j++) {
00758 M(i,j) -= coef * M(k,j);
00759 }
00760 b[i] -= coef*b[k];
00761 }
00762 }
00763 for (size_t i=0; i<N; ++i)
00764 t *= M(i,i);
00765
00766 for (size_t i = N-1; i < N; --i) {
00767 X[i] = 0;
00768 for (size_t j = i+1; j<N; j++) {
00769 X[i] -= M(i,j)*X[j];
00770 }
00771 X[i] += b[i];
00772 X[i] /= M(i,i);
00773 }
00774 return t;
00775 }
00776
00783 void swapLines(const size_t& n, const size_t& m)
00784 {
00785 if (n==m)
00786 return;
00787
00788 T temp;
00789 for (size_t i=0; i<N; ++i) {
00790 temp = __x[n][i];
00791 __x[n][i] = __x[m][i];
00792 __x[m][i] = temp;
00793 }
00794 }
00795
00803 friend void LU(const TinyMatrix<N,N,T>& A,
00804 TinyMatrix<N,N,T>& lu,
00805 TinyMatrix<N,N,T>& P)
00806 {
00807
00808 for (size_t i=0; i<N; i++)
00809 for (size_t j=0; j<N; j++) {
00810 P(i,j) = (i==j);
00811 }
00812
00813 lu = A;
00814
00815 for (size_t k=0; k<N-1; k++) {
00816
00817 size_t maxLine = k;
00818 for (size_t i=k+1; i<N; i++) {
00819 maxLine = (std::abs(lu(i,k))<std::abs(lu(maxLine,k)))?maxLine:i;
00820 }
00821 lu.swapLines(k,maxLine);
00822 P.swapLines(k,maxLine);
00823
00824 for (size_t i=k+1; i<N; i++) {
00825 lu(i,k) /= lu(k,k);
00826 for (size_t j=k+1; j<N; j++)
00827 lu(i,j) -=lu(i,k)*lu(k,j);
00828 }
00829 }
00830 }
00831
00839 inline TinyVector<N,T> applyLU(const TinyVector<N,T>& b) const
00840 {
00841 const TinyMatrix<N,N,T>& lu = (*this);
00842
00843 TinyVector<N,T> y = b;
00844
00845 for (size_t i=0; i<N; i++) {
00846 for (size_t j=0; j<i; j++)
00847 y[i] -= y[j]*lu(i,j);
00848 }
00849
00850
00851 for (size_t i=N-1; i<N; i--) {
00852 for (size_t j=i+1; j<N; j++)
00853 y[i] -= y[j]*lu(i,j);
00854
00855 y[i] /= lu(i,i);
00856 }
00857
00858 return y;
00859 }
00860
00869 friend TinyVector<N,T> operator/(const TinyVector<N,T>& b,
00870 const TinyMatrix<N,N,T>& A)
00871 {
00872 TinyMatrix<N,N,T> lu;
00873 TinyMatrix<N,N,T> P;
00874 LU(A,lu,P);
00875
00876 return lu.applyLU(P*b);
00877 }
00878
00884 TinyMatrix()
00885 {
00886 for (size_t i=0; i<N; i++)
00887 for (size_t j=0; j<N; j++)
00888 __x[i][j] = 0;
00889 }
00890
00896 TinyMatrix(const TinyMatrix<N,N,T>& B)
00897 {
00898 for (size_t i=0; i<N; i++)
00899 for (size_t j=0; j<N; j++)
00900 __x[i][j] = B.__x[i][j];
00901 }
00902
00911 TinyMatrix(const T& t)
00912 {
00913 for (size_t i=0; i<N; i++)
00914 for (size_t j=0; j<N; j++)
00915 __x[i][j] = (i==j)?t:0;
00916 }
00917
00922 ~TinyMatrix()
00923 {
00924 ;
00925 }
00926 };
00927
00928
00937 template<typename T>
00938 class TinyMatrix<1,1,T>
00939 {
00940 public:
00941 typedef T
00942 AssociatedVector;
00944 typedef T
00945 AssociatedTransposedVector;
00948 typedef T ValueType;
00951 enum {
00952 NumberOfLines = 1,
00953 NumberOfRow = 1
00954 };
00955
00956 private:
00957 T __x;
00959 public:
00965 inline operator T&()
00966 {
00967 return __x;
00968 }
00969
00975 inline operator const T&() const
00976 {
00977 return __x;
00978 }
00979
00988 T& operator()(const size_t& i, const size_t& j)
00989 {
00990 ASSERT ((i==0)&&(j==0));
00991 return __x;
00992 }
00993
01002 const T& operator()(const size_t& i, const size_t& j) const
01003 {
01004 ASSERT ((i==0)&&(j==0));
01005 return __x;
01006 }
01007
01009 friend const T& det(const TinyMatrix<1,1,T>& A)
01010 {
01011 return A.__x;
01012 }
01013
01018 TinyMatrix()
01019 : __x(0)
01020 {
01021 ;
01022 }
01023
01029 TinyMatrix(const T& t)
01030 : __x(t)
01031 {
01032 ;
01033 }
01034
01040 TinyMatrix(const TinyMatrix<1,1,T>& B)
01041 : __x(B.__x)
01042 {
01043 ;
01044 }
01045
01050 ~TinyMatrix()
01051 {
01052 ;
01053 }
01054 };
01055
01056 #endif // TINY_MATRIX_HPP