00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __OPENKN_MATH__MATRIX_HPP__
00027 #define __OPENKN_MATH__MATRIX_HPP__
00028
00029
00030
00031
00032 #include <iostream>
00033 #include <algorithm>
00034 #include <cmath>
00035
00036
00037
00038
00039 #include "Vector.hpp"
00040 #include "MathException.hpp"
00041
00042
00043
00044
00045 namespace kn {
00046
00047
00048
00049
00050
00054 template<class T> class Matrix {
00055
00056 protected:
00057
00061 size_t rowsMatrix;
00062
00066 size_t columnsMatrix;
00067
00071 T* data;
00072
00076 T* begin_;
00077
00081 T* end_;
00082
00086 T** accessor;
00087
00088 public:
00089
00090
00091
00092
00093
00097 Matrix();
00098
00104 Matrix(const Matrix<T>& m);
00105
00112 Matrix(const Matrix<T>* m);
00113
00121 Matrix(const size_t& n,
00122 const size_t& m);
00123
00130 explicit Matrix(const size_t& n);
00131
00140 Matrix(const size_t& n,
00141 const size_t& m,
00142 const T& d);
00143
00152 Matrix(const size_t& n,
00153 const size_t& m,
00154 T* a);
00155
00156
00164 Matrix(const size_t& n, T* a);
00165
00176 Matrix(const size_t& n,
00177 const size_t& m,
00178 const Vector<T>& v,
00179 const bool& setasrows = true);
00180
00190 Matrix(const size_t& n,
00191 const Vector<T>* v,
00192 const bool& setasrows = true);
00193
00194
00195
00196
00197
00201 virtual ~Matrix(void){
00202 if(data!=0){
00203 delete[] accessor;
00204 delete[] data;
00205 }
00206 }
00207
00208 protected:
00209
00213 void allocate(void);
00214
00215 public:
00216
00220 inline virtual T * begin() const {return begin_;}
00221
00225 inline virtual T * end() const {return end_;}
00226
00227
00236 T& at(const unsigned int& i, const unsigned int& j);
00237
00246 const T& at(const unsigned int& i, const unsigned int& j) const;
00247
00248
00249
00250
00251
00257 bool operator==(const Matrix<T>& m) const;
00258
00264 inline bool operator!=(const Matrix<T>& m) const
00265 {
00266 return !(*this == m);
00267 }
00268
00275 Matrix<T>& operator=(const Matrix<T>& m);
00276
00282 Matrix<T>& operator=(const T & value);
00283
00290 Matrix<T> operator+(const Matrix<T>& m) const;
00291
00298 Matrix<T> operator-(const Matrix<T>& m) const;
00299
00306 Matrix<T> operator/(const T& d) const;
00307
00314 Matrix<T> operator*(const Matrix<T>& m) const;
00315
00322 Vector<T> operator*(const Vector<T>& v) const;
00323
00329 Matrix<T> operator*(const T& d) const;
00330
00336 void times(const Matrix<T>& m1,const Matrix<T>& m2);
00337
00342 Matrix<T> operator-(void) const;
00343
00350 Matrix<T>& operator+=(const Matrix<T>& m);
00351
00357 Matrix<T>& operator+=(const T& d);
00358
00365 Matrix<T>& operator-=(const Matrix<T>& m);
00366
00372 Matrix<T>& operator-=(const T& d);
00373
00381 Matrix<T>& operator/=(const T& d);
00382
00389 Matrix<T>& operator*=(const Matrix<T>& m);
00390
00396 Matrix<T>& operator*=(const T& d);
00397
00407 T* operator[](const unsigned int& i) const;
00408
00416 T& operator()(const unsigned int& i,
00417 const unsigned int& j);
00418
00426 const T& operator()(const unsigned int& i,
00427 const unsigned int& j) const;
00428
00429
00430
00431
00432
00437 inline size_t rows(void) const{
00438 return rowsMatrix;
00439 }
00440
00445 inline size_t columns(void) const{
00446 return columnsMatrix;
00447 }
00448
00455 double getNorm(void) const;
00456
00462 const T* getMatrixArray(void) const{
00463 return data;
00464 }
00465
00466
00471 Matrix<T>& transpose(void);
00472
00478 inline Matrix<T> getTranspose(void) const
00479 {
00480 return Matrix<T>(*this).transpose();
00481 }
00482
00488 Matrix<T>& power(const unsigned int& p);
00489
00493 void setIdentity(void);
00494
00498 inline void setZero(void)
00499 {
00500 std::fill(begin_,end_,T(0.0));
00501 }
00502
00506 inline void fill(const T &d){
00507 std::fill(begin_,end_,d);
00508 }
00509
00514 void roundZero(const double& d = 1.0e-14);
00515
00525 void setSubMatrix(const unsigned int& row,
00526 const unsigned int& column,
00527 const Matrix<T>& m);
00528
00538 Matrix<T> getSubMatrix(const unsigned int& firstrow,const unsigned int& row,
00539 const unsigned int& firstcolumn,const unsigned int& column);
00547 void setRow(const unsigned int& row,
00548 const Vector<T>& v);
00549
00557 void setRow(const unsigned int& row,
00558 T* a);
00559
00566 void setRow(const unsigned int& row,
00567 const T& d);
00568
00576 void setColumn(const unsigned int& column,
00577 const Vector<T>& v);
00578
00586 void setColumn(const unsigned int& column,
00587 const T* a);
00588
00595 void setColumn(const unsigned int& column,
00596 const T& d);
00597
00604 Vector<T> getRow(const unsigned int& row) const;
00605
00612 Vector<T> getColumn(const unsigned int& column) const;
00613
00621 void swapRows(const unsigned int& row1,
00622 const unsigned int& row2);
00623
00631 void swapColumns(const unsigned int& column1,
00632 const unsigned int& column2);
00633
00639 void setDiagonal(const Vector<T>& v);
00640
00646 void setDiagonal(const T* a);
00647
00652 void setDiagonal(const T& d);
00653
00658 Vector<T> getDiagonal(void) const;
00659
00664 inline bool isSquare(void) const{
00665 return rowsMatrix == columnsMatrix;
00666 }
00667
00673 T trace(void) const;
00674
00683 void cross3x3(const kn::Vector<T> v);
00684
00685 };
00686
00687 template<typename T>
00688 Matrix<T>:: Matrix()
00689 : rowsMatrix(0), columnsMatrix(0){
00690 data = NULL;
00691 begin_ = NULL;
00692 end_ = NULL;
00693 accessor = NULL;
00694 }
00695
00696 template<typename T>
00697 Matrix<T>:: Matrix(const Matrix<T>& m)
00698 : rowsMatrix(m.rows()), columnsMatrix(m.columns()){
00699 allocate();
00700 std::copy(m.begin_, m.end_, begin_);
00701 }
00702
00703
00704 template<typename T>
00705 Matrix<T>::Matrix(const Matrix<T>* m)
00706 : rowsMatrix(m->rows()), columnsMatrix(m->columns()){
00707 if(m==0)
00708 throw MathException("Pointer is null");
00709 allocate();
00710 std::copy(m->begin_, m->end_, begin_);
00711 }
00712
00713
00714 template<typename T>
00715 Matrix<T>::Matrix(const size_t& n,
00716 const size_t& m)
00717 :rowsMatrix(n), columnsMatrix(m){
00718 if(m==0 || n==0)
00719 throw MathException("Matrix size is null");
00720 allocate();
00721 }
00722
00723
00724 template<typename T>
00725 Matrix<T>::Matrix(const size_t& n)
00726 :rowsMatrix(n), columnsMatrix(n){
00727 if(n==0)
00728 throw MathException("Matrix size is null");
00729 allocate();
00730 }
00731
00732
00733 template<typename T>
00734 Matrix<T>::Matrix(const size_t& n,
00735 const size_t& m,
00736 const T& d)
00737 :rowsMatrix(n), columnsMatrix(m){
00738 if(m==0 || n==0)
00739 throw MathException("Matrix size is null");
00740 allocate();
00741 std::fill(begin_, end_, d);
00742 }
00743
00744
00745 template<typename T>
00746 Matrix<T>::Matrix(const size_t& n,
00747 const size_t& m,
00748 T* a)
00749 :rowsMatrix(n), columnsMatrix(m){
00750 if(m==0 || n==0)
00751 throw MathException("Matrix size is null");
00752 if(a==0)
00753 throw MathException("Pointer is null");
00754 allocate();
00755 std::copy(a, a + n*m, this->begin_);
00756 }
00757
00758
00759
00760 template<typename T>
00761 Matrix<T>::Matrix(const size_t& n, T* a)
00762 :rowsMatrix(n), columnsMatrix(n){
00763 if(n==0)
00764 throw MathException("Matrix size is null");
00765 if(a==0)
00766 throw MathException("Pointer is null");
00767 allocate();
00768 std::copy(a, a + n*n, this->begin_);
00769 }
00770
00771
00772 template<typename T>
00773 Matrix<T>::Matrix(const size_t& n,
00774 const size_t& m,
00775 const Vector<T>& v,
00776 const bool& setasrows)
00777 :rowsMatrix(n), columnsMatrix(m){
00778 if(m==0 || n==0)
00779 throw MathException("Matrix size is null");
00780 if(v.size()!=n*m)
00781 throw MathException("Vector size is different from Matrix size");
00782
00783 allocate();
00784
00785 if(setasrows)
00786 for(unsigned int i = 0; i < rowsMatrix*columnsMatrix; ++i)
00787 data[i] = v[i];
00788 else
00789 for(unsigned int j = 0; j < columnsMatrix; ++j)
00790 for(unsigned int i = 0; i < rowsMatrix; ++i)
00791 accessor[i][j] = v[j*columnsMatrix+i];
00792 }
00793
00794
00795 template<typename T> Matrix<T>::Matrix(const size_t& n,
00796 const Vector<T>* v,
00797 const bool& setasrows){
00798
00799 if(n==0)
00800 throw MathException("Matrix size is null");
00801 if(v==0)
00802 throw MathException("Pointer is null");
00803 unsigned int checksize = 0;
00804 for(unsigned int i = 0; i < n; ++i){
00805 if(v[i].size()==0)
00806 throw MathException("One vector size is null");
00807 if(i==0)
00808 checksize = v[i].size();
00809 else
00810 if(v[i].size() != checksize)
00811 throw MathException("Vectors size are different");
00812 }
00813
00814 if(setasrows){
00815 rowsMatrix = n;
00816 columnsMatrix = v[0].size();
00817 allocate();
00818 for(unsigned int i = 0; i < n; ++i)
00819 for(unsigned int j = 0; j < (v[i]).size(); ++j)
00820 accessor[i][j] = v[i][j];
00821 }else{
00822 rowsMatrix = v[0].size();
00823 columnsMatrix = n;
00824 allocate();
00825 for(unsigned int j = 0; j < n; ++j)
00826 for(unsigned int i = 0; i < (v[i]).size(); ++i)
00827 accessor[i][j] = v[j][i];
00828 }
00829 }
00830
00831
00832
00833 template<typename T>
00834 void Matrix<T>::allocate(void){
00835 this->data = this->begin_ = this->end_ = 0;
00836 this->accessor = 0;
00837 this->data = new T[rowsMatrix*columnsMatrix];
00838 this->begin_ = this->data;
00839 this->end_ = this->begin_ + this->rowsMatrix*this->columnsMatrix;
00840 this->accessor = new T*[this->rowsMatrix];
00841 for(unsigned int i = 0; i < this->rowsMatrix; ++i)
00842 this->accessor[i] = this->begin_ + i*this->columnsMatrix;
00843 }
00844
00845 template<typename T>
00846 T& Matrix<T>::at(const unsigned int& i, const unsigned int& j) {
00847 if(i>=rowsMatrix || j>=columnsMatrix)
00848 throw MathException("Out of bounds");
00849
00850 return accessor[i][j];
00851 }
00852
00853 template<typename T>
00854 const T& Matrix<T>::at(const unsigned int& i, const unsigned int& j) const {
00855 if(i>=rowsMatrix || j>=columnsMatrix)
00856 throw MathException("Out of bounds");
00857
00858 return accessor[i][j];
00859 }
00860
00861
00862 template<typename T>
00863 bool Matrix<T>::operator==(const Matrix<T>& m) const{
00864 if(m.rowsMatrix != rowsMatrix || m.columnsMatrix != columnsMatrix) return false;
00865 return std::equal(begin_, end_, m.begin_);
00866 }
00867
00868
00869 template<typename T>
00870 Matrix<T>& Matrix<T>::operator=(const Matrix<T>& m){
00871 if(&m == this) return *this;
00872
00873 if(rowsMatrix == 0 && columnsMatrix == 0){
00874 rowsMatrix = m.rowsMatrix;
00875 columnsMatrix = m.columnsMatrix;
00876 allocate();
00877 }
00878
00879 if(m.rowsMatrix == rowsMatrix && m.columnsMatrix == columnsMatrix)
00880 std::copy(m.begin_,m.end_,begin_);
00881 else
00882 throw MathException("Matrices'size are different");
00883
00884 return *this;
00885 }
00886
00887 template<typename T>
00888 Matrix<T>& Matrix<T>::operator=(const T & value) {
00889 std::fill(begin_,end_,T(value));
00890
00891 return *this;
00892 }
00893
00894
00895 template<typename T>
00896 Matrix<T> Matrix<T>::operator+(const Matrix<T>& m) const{
00897 Matrix<T> result = *this;
00898 result += m;
00899 return result;
00900 }
00901
00902
00903 template<typename T>
00904 Matrix<T> Matrix<T>::operator-(const Matrix<T>& m) const{
00905 Matrix<T> result = *this;
00906 result -= m;
00907 return result;
00908 }
00909
00910
00911 template<typename T>
00912 Matrix<T> Matrix<T>::operator/(const T& d) const{
00913 Matrix<T> result = *this;
00914 result /= d;
00915 return result;
00916 }
00917
00918
00919 template<typename T>
00920 Matrix<T> Matrix<T>::operator*(const Matrix<T>& m) const{
00921
00922 if(m.rowsMatrix != columnsMatrix)
00923 throw MathException("Matrices'size is incorrect");
00924
00925 Matrix<T> result(rowsMatrix,m.columnsMatrix);
00926 result.times(this,m);
00927 return result;
00928 }
00929
00930 template<typename T>
00931 void Matrix<T>::times(const Matrix<T>& m1,const Matrix<T>& m2){
00932
00933 if(m1.columnsMatrix != m2.rowsMatrix)
00934 throw MathException("Matrices'size is incorrect");
00935
00936 if(m1.rowsMatrix != rowsMatrix)
00937 throw MathException("Matrices' rows size is incorrect");
00938
00939 if(m2.columnsMatrix != columnsMatrix)
00940 throw MathException("Matrices' columns size is incorrect");
00941
00942 T sum;
00943 for(unsigned int i = 0; i < rowsMatrix; ++i)
00944 for(unsigned int j = 0; j < columnsMatrix; ++j){
00945 sum = T(0.0);
00946 for(unsigned int k = 0; k < m1.columnsMatrix; ++k){
00947 sum += m1[i][k]*m2[k][j];
00948 }
00949 accessor[i][j] = sum;
00950 }
00951 }
00952
00953
00954
00955 template<typename T>
00956 Vector<T> Matrix<T>::operator*(const Vector<T>& v) const{
00957 if(v.size() != columnsMatrix)
00958 throw MathException("Matrice rows and vector size are different");
00959
00960 Vector<T> vtmp(rowsMatrix);
00961 T sum;
00962 for(unsigned int i = 0; i < rowsMatrix; ++i){
00963 sum = T(0);
00964 for(unsigned int j = 0; j < columnsMatrix; ++j){
00965 sum += accessor[i][j]*v[j];
00966 }
00967 vtmp[i] = sum;
00968 }
00969 return vtmp;
00970 }
00971
00972
00973 template<typename T>
00974 Matrix<T> Matrix<T>::operator*(const T& d) const{
00975 Matrix<T> result = *this;
00976 result *= d;
00977 return result;
00978 }
00979
00980
00981 template<typename T>
00982 Matrix<T> Matrix<T>::operator-(void) const{
00983 Matrix<T> result = *this;
00984 std::transform(begin_, end_, result.begin_, std::negate<T>());
00985 return result;
00986 }
00987
00988
00989 template<typename T>
00990 Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& m){
00991 if(m.rowsMatrix != rowsMatrix || m.columnsMatrix != columnsMatrix)
00992 throw MathException("Matrices'size is incorrect");
00993 std::transform(begin_, end_, m.begin_, begin_, std::plus<T>());
00994 return *this;
00995 }
00996
00997
00998 template<typename T>
00999 Matrix<T>& Matrix<T>::operator-=(const Matrix<T>& m){
01000 if(m.rowsMatrix != rowsMatrix || m.columnsMatrix != columnsMatrix)
01001 throw MathException("Matrices'size is incorrect");
01002 std::transform(begin_, end_, m.begin_, begin_, std::minus<T>());
01003 return *this;
01004 }
01005
01006 template<typename T>
01007 Matrix<T>& Matrix<T>::operator/=(const T& d){
01008 if(d==0)
01009 throw MathException("Value is null");
01010 std::transform(begin_, end_, begin_, std::bind2nd(std::divides<T>(),d));
01011 return *this;
01012 }
01013
01014 template<typename T>
01015 Matrix<T>& Matrix<T>::operator+=(const T& d){
01016 std::transform(begin_, end_, begin_, std::bind2nd(std::plus<T>(),d));
01017 return *this;
01018 }
01019
01020 template<typename T>
01021 Matrix<T>& Matrix<T>::operator-=(const T& d){
01022 std::transform(begin_, end_, begin_, std::bind2nd(std::minus<T>(),d));
01023 return *this;
01024 }
01025
01026 template<typename T>
01027 Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& m){
01028
01029 if(rowsMatrix != columnsMatrix)
01030 throw MathException("Matrices'size is incorrect");
01031
01032 if(m.rowsMatrix != m.columnsMatrix)
01033 throw MathException("Matrices'size is incorrect");
01034
01035 if(m.rowsMatrix != columnsMatrix)
01036 throw MathException("Matrices'size is incorrect");
01037
01038 Matrix<T> tmp = *this;
01039 T sum;
01040 for(unsigned int i = 0; i < rowsMatrix; ++i)
01041 for(unsigned int j = 0; j < m.columnsMatrix; ++j){
01042 sum = T(0.0);
01043
01044 for(unsigned int k = 0; k < columnsMatrix; ++k){
01045 sum += tmp[i][k]*m[k][j];
01046 }
01047 accessor[i][j] = sum;
01048 }
01049 return *this;
01050 }
01051
01052 template<typename T>
01053 Matrix<T>& Matrix<T>::operator*=(const T& d){
01054 std::transform(begin_, end_, begin_, std::bind2nd(std::multiplies<T>(),d));
01055 return *this;
01056 }
01057
01058
01059 template<typename T>
01060 T* Matrix<T>::operator[](const unsigned int& i) const{
01061 return accessor[i];
01062 }
01063
01064 template<typename T>
01065 T& Matrix<T>::operator()(const unsigned int& i, const unsigned int& j) {
01066 return accessor[i][j];
01067 }
01068
01069 template<typename T>
01070 const T& Matrix<T>::operator()(const unsigned int& i, const unsigned int& j) const{
01071 return accessor[i][j];
01072 }
01073
01074
01075
01076
01077 template<typename T>
01078 double Matrix<T>::getNorm(void) const{
01079 double norm = 0.0;
01080 for(unsigned int i = 0; i < rowsMatrix*columnsMatrix; ++i)
01081 norm += data[i]*data[i];
01082 return sqrt(norm);
01083 }
01084
01085
01086
01091 template<typename T>
01092 Matrix<T>& Matrix<T>::transpose(void){
01093 Matrix<T> tmp(*this);
01094 std::swap(rowsMatrix,columnsMatrix);
01095
01096 if(data!=0){
01097 delete[] accessor;
01098 delete[] data;
01099 }
01100 allocate();
01101 for(unsigned int i = 0; i < rowsMatrix; ++i)
01102 for(unsigned int j = 0; j < columnsMatrix; ++j)
01103 accessor[i][j] = tmp[j][i];
01104
01105 return *this;
01106 }
01107
01108
01109 template<typename T>
01110 Matrix<T>& Matrix<T>::power(const unsigned int& p){
01111 if(rowsMatrix != columnsMatrix)
01112 throw MathException("Matrix is not square");
01113
01114 if(p == 0){
01115 setIdentity();
01116 return *this;
01117 }
01118 Matrix<T> tmp(*this);
01119
01120 for(unsigned int i=1; i < p; ++i)
01121 *this *= tmp;
01122
01123 return *this;
01124 }
01125
01129 template<typename T>
01130 void Matrix<T>::setIdentity(void){
01131 setZero();
01132 setDiagonal(T(1.0));
01133 }
01134
01135
01136 template<typename T>
01137 void Matrix<T>::roundZero(const double& d){
01138 T *iter = begin_;
01139
01140 while(iter != end_){
01141 if(std::abs((*iter)) < d) (*iter) = T(0.0);
01142 ++iter;
01143 }
01144 }
01145
01146 template<typename T>
01147 void Matrix<T>::setSubMatrix(const unsigned int& row,
01148 const unsigned int& column,
01149 const Matrix<T>& m){
01150
01151 if(row + m.rowsMatrix > rowsMatrix || column + m.columnsMatrix > columnsMatrix)
01152 throw MathException("Input matrix size is incorrect");
01153
01154 for(unsigned int i = 0; i < m.rowsMatrix; ++i)
01155 std::copy(m.accessor[i], m.accessor[i]+m.columnsMatrix,accessor[i+row]+column);
01156
01157 }
01158
01159 template<typename T>
01160 Matrix<T> Matrix<T>::getSubMatrix(const unsigned int& firstrow,const unsigned int& row,
01161 const unsigned int& firstcolumn,const unsigned int& column){
01162
01163 if(firstrow + row > rowsMatrix || firstcolumn + column > columnsMatrix)
01164 throw MathException("Input parameter row/column size is incorrect");
01165
01166 Matrix<T> tmp(row,column);
01167
01168 for(unsigned int i = 0; i < row; ++i)
01169 std::copy(accessor[firstrow+i]+firstcolumn, accessor[firstrow+i]+firstcolumn+column,tmp.accessor[i]);
01170
01171 return tmp;
01172 }
01173
01174 template<typename T>
01175 void Matrix<T>::setRow(const unsigned int& row,
01176 const Vector<T>& v){
01177 if(row >= rowsMatrix)
01178 throw MathException("Out of bounds");
01179 if (v.size() > columnsMatrix)
01180 throw MathException("Input vector size is incorrect");
01181
01182 for(unsigned int i = 0; i < columnsMatrix; ++i)
01183 accessor[row][i] = v[i];
01184 }
01185
01186 template<typename T>
01187 void Matrix<T>::setRow(const unsigned int& row,
01188 T* a){
01189 if(row >= rowsMatrix)
01190 throw MathException("Out of bounds");
01191 std::copy(a, a+columnsMatrix,accessor[row]);
01192 }
01193
01194 template<typename T>
01195 void Matrix<T>::setRow(const unsigned int& row,
01196 const T& d){
01197 if(row >= rowsMatrix)
01198 throw MathException("Out of bounds");
01199 std::fill(accessor[row], accessor[row]+columnsMatrix,d);
01200 }
01201
01202
01203 template<typename T>
01204 void Matrix<T>::setColumn(const unsigned int& column,
01205 const Vector<T>& v){
01206 if(column >= columnsMatrix)
01207 throw MathException("Out of bounds");
01208 if (v.size() > rowsMatrix)
01209 throw MathException("Input vector size is incorrect");
01210
01211 for(unsigned int i = 0; i < rowsMatrix; ++i)
01212 accessor[i][column] = v[i];
01213 }
01214
01215 template<typename T>
01216 void Matrix<T>::setColumn(const unsigned int& column,
01217 const T* a){
01218 if(column >= columnsMatrix)
01219 throw MathException("Out of bounds");
01220
01221 for(unsigned int i = 0; i < rowsMatrix; ++i)
01222 accessor[i][column] = a[i];
01223 }
01224
01225
01226 template<typename T>
01227 void Matrix<T>::setColumn(const unsigned int& column,
01228 const T& d){
01229 if(column >= columnsMatrix)
01230 throw MathException("Out of bounds");
01231
01232 for(unsigned int i = 0; i < rowsMatrix; ++i)
01233 accessor[i][column] = d;
01234 }
01235
01236 template<typename T>
01237 Vector<T> Matrix<T>::getRow(const unsigned int& row) const{
01238 if(row >= rowsMatrix)
01239 throw MathException("Out of bounds");
01240 Vector<T> v(columnsMatrix);
01241 for(unsigned int i = 0; i < columnsMatrix; ++i)
01242 v[i] = accessor[row][i];
01243 return v;
01244 }
01245
01246 template<typename T>
01247 Vector<T> Matrix<T>::getColumn(const unsigned int& column) const{
01248 if(column >= columnsMatrix)
01249 throw MathException("Out of bounds");
01250 Vector<T> v(rowsMatrix);
01251 for(unsigned int i = 0; i < rowsMatrix; ++i)
01252 v[i] = accessor[i][column];
01253 return v;
01254 }
01255
01256
01257 template<typename T>
01258 void Matrix<T>::swapRows(const unsigned int& row1,
01259 const unsigned int& row2){
01260 if(row1 >= rowsMatrix || row2 >= rowsMatrix)
01261 throw MathException("Out of bounds");
01262
01263 std::swap_ranges(accessor[row1],accessor[row1]+columnsMatrix,accessor[row2]);
01264 }
01265
01266
01267 template<typename T>
01268 void Matrix<T>::swapColumns(const unsigned int& column1,
01269 const unsigned int& column2){
01270 if(column1 >= columnsMatrix || column2 >= columnsMatrix)
01271 throw MathException("Out of bounds");
01272
01273 for(unsigned int i = 0; i < rowsMatrix; ++i)
01274 std::swap(accessor[i][column1],accessor[i][column2]);
01275 }
01276
01277
01278 template<typename T>
01279 void Matrix<T>::setDiagonal(const Vector<T>& v){
01280 unsigned int min = std::min(columnsMatrix,rowsMatrix);
01281
01282 if(v.size() != min)
01283 throw MathException("Vector size is incorrect");
01284
01285 for(unsigned int i = 0; i < min; ++i)
01286 accessor[i][i] = v[i];
01287 }
01288
01289
01290 template<typename T>
01291 void Matrix<T>::setDiagonal(const T* a){
01292 unsigned int min = std::min(columnsMatrix,rowsMatrix);
01293
01294 for(unsigned int i = 0; i < min; ++i)
01295 accessor[i][i] = a[i];
01296 }
01297
01298 template<typename T>
01299 void Matrix<T>::setDiagonal(const T& d)
01300 {
01301 unsigned int min = std::min(columnsMatrix,rowsMatrix);
01302
01303 for(unsigned int i = 0; i < min; ++i)
01304 accessor[i][i] = d;
01305 }
01306
01307
01308 template<typename T>
01309 Vector<T> Matrix<T>::getDiagonal(void) const{
01310 unsigned int min = std::min(columnsMatrix,rowsMatrix);
01311 Vector<T> v(min);
01312 for(unsigned int i = 0; i < min; ++i)
01313 v[i] = accessor[i][i];
01314 return v;
01315 }
01316
01317 template<typename T>
01318 T Matrix<T>::trace(void) const{
01319 T sum = 0;
01320 unsigned int min = std::min(columnsMatrix,rowsMatrix);
01321 for(unsigned int i = 0; i < min; ++i)
01322 sum += accessor[i][i];
01323 return sum;
01324 }
01325
01326 template<typename T>
01327 void Matrix<T>::cross3x3(const kn::Vector<T> v){
01328 if(v.size() != 3)
01329 throw MathException("argument shoud be a 3-vector");
01330
01331 if(rowsMatrix != 3 && columnsMatrix != 3)
01332 throw MathException("valid only with 3x3 matrices");
01333
01334 accessor[0][0] = 0.0; accessor[0][1] = -v[2]; accessor[0][2] = v[1];
01335 accessor[1][0] = v[2]; accessor[1][1] = 0.0; accessor[1][2] = -v[0];
01336 accessor[2][0] = -v[1]; accessor[2][1] = v[0]; accessor[2][2] = 0.0;
01337 }
01338
01339
01346 template<class U> std::ostream& operator<< (std::ostream& stream,
01347 const Matrix<U>& m){
01348 for(unsigned int i=0; i<m.rows(); ++i){
01349 for (unsigned int j=0; j<m.columns(); ++j)
01350 stream<<m[i][j] << " " ;
01351 stream<<std::endl;
01352 }
01353 return stream;
01354 }
01355
01363 template<class U> Vector<U> operator* (const Vector<U>& v,
01364 const Matrix<U>& m){
01365 if(m.rows() != v.size())
01366 throw MathException("Matrix or vector size is incorrect");
01367
01368 Vector<U> result(m.columns());
01369 U sum;
01370 for(unsigned int i=0; i<m.columns(); ++i){
01371 sum = U(0.0);
01372 for(unsigned int j=0; j<m.rows(); ++j)
01373 sum += m[j][i] * v[j];
01374 result[i] = sum;
01375 }
01376 return result;
01377 }
01378
01385 template<class U> Matrix<U> operator* (const U& d,
01386 const Matrix<U>& m){
01387 return m*d;
01388 }
01389
01390
01391
01392
01393
01394 typedef Matrix<float> Matrixf;
01395 typedef Matrix<double> Matrixd;
01396 typedef Matrix<int> Matrixi;
01397
01398
01399
01400
01401
01402 }
01403
01404
01405
01406
01407
01408 #endif