00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef IXLIB_MATRIX
00011 #define IXLIB_MATRIX
00012
00013
00014
00015 #include <cmath>
00016 #include <iostream>
00017 #include <ixlib_exgen.hh>
00018 #include <ixlib_array.hh>
00019 #include <ixlib_numeric.hh>
00020
00021
00022
00023
00024 namespace ixion {
00025 template <class T>
00026 struct number_traits {
00027 typedef T number_type;
00028 typedef T scalar_type;
00029
00030 static const number_type zero = 0;
00031
00032 static scalar_type norm(number_type value) {
00033 return NUM_ABS(value);
00034 }
00035 static number_type sqrt(number_type value) {
00036 return ::sqrt(value);
00037 }
00038
00039 static void isRing();
00040 static void isField();
00041 static void isVectorSpace();
00042 };
00043
00044
00045
00046
00047
00048 template <class T,class Traits = number_traits<T> >
00049 class matrix {
00050 protected:
00051 TSize Height,Width;
00052 auto_array<T> Data;
00053
00054 public:
00055 typedef Traits traits_type;
00056 typedef typename traits_type::number_type entry_type;
00057 typedef typename traits_type::scalar_type scalar_type;
00058 typedef T *iterator;
00059 typedef T const *const_iterator;
00060
00061 matrix(TSize height = 0,TSize width = 0);
00062 template<class InputIterator>
00063 inline matrix(TSize height,TSize width,InputIterator first);
00064 matrix(matrix const &src);
00065
00066 matrix &operator=(matrix const &src);
00067
00068 matrix &operator+=(matrix const &op2);
00069 matrix &operator-=(matrix const &op2);
00070 matrix &operator*=(matrix const &op2) {
00071 return operator=(operator*(op2));
00072 }
00073
00074 matrix &operator*=(scalar_type scalar);
00075
00076 matrix operator-() const {
00077 matrix copy(*this);
00078 copy *= -1;
00079 return copy;
00080 }
00081 matrix operator+(matrix const &op2) const {
00082 matrix copy(*this);
00083 copy += op2;
00084 return copy;
00085 }
00086 matrix operator-(matrix const &op2) const {
00087 matrix copy(*this);
00088 copy -= op2;
00089 return copy;
00090 }
00091 matrix operator*(matrix const &op2) const;
00092
00093 matrix operator()(TIndex row) const {
00094 return extractRow(row);
00095 }
00096 entry_type &operator()(TIndex row,TIndex col) {
00097 return Data[getIndex(row,col)];
00098 }
00099 entry_type operator()(TIndex row,TIndex col) const {
00100 return Data[getIndex(row,col)];
00101 }
00102
00103 iterator begin() {
00104 return Data.get();
00105 }
00106 const_iterator begin() const {
00107 return Data.get();
00108 }
00109 iterator end() {
00110 return Data.get()+getSize();
00111 }
00112 const_iterator end() const {
00113 return Data.get()+getSize();
00114 }
00115
00116 TSize getWidth() const {
00117 return Width;
00118 }
00119 TSize getHeight() const {
00120 return Height;
00121 }
00122
00123 matrix extract(TIndex row,TIndex col,TSize height,TSize width) const;
00124 matrix extractRow(TIndex row) const {
00125 return extract(row,0,1,Width);
00126 }
00127 matrix extractColumn(TIndex col) const {
00128 return extract(0,col,Height,1);
00129 }
00130
00131 matrix &set(TIndex row,TIndex col,matrix const &src);
00132 matrix &setRow(TIndex row,matrix const &src) {
00133 return set(row,0,src);
00134 }
00135 matrix &setColumn(TIndex col,matrix const &src) {
00136 return set(0,col,src);
00137 }
00138
00139 matrix &add(TIndex row,TIndex col,matrix const &src,entry_type factor = 1);
00140 matrix &addRow(TIndex row,matrix &src,entry_type factor = 1) {
00141 return add(row,0,src,factor);
00142 }
00143 matrix &addColumn(TIndex col,matrix &src,entry_type factor = 1) {
00144 return add(0,col,src,factor);
00145 }
00146
00147 matrix &addRowSelf(TIndex to,TIndex from,entry_type factor = 1,TIndex startcol = 0);
00148 matrix &addColumnSelf(TIndex to,TIndex from,entry_type factor = 1,TIndex startrow = 0);
00149 matrix &multiplyRowSelf(TIndex row,entry_type factor,TIndex startcol = 0);
00150 matrix &multiplyColumnSelf(TIndex column,entry_type factor,TIndex startrow = 0);
00151 matrix &swapRowSelf(TIndex row1,TIndex row2);
00152 matrix &swapColumnSelf(TIndex col1,TIndex col2);
00153
00154 static const int infty = -1;
00155
00156 entry_type det() const;
00157 entry_type getVectorNorm(int index = 2) const;
00158 entry_type trace() const;
00159 entry_type diagonalProduct() const;
00160 matrix getTransposed() const;
00161 matrix getInverted() const;
00162 matrix getGaussElim(scalar_type pivot_threshold = 0,TSize *swapcount = NULL) const;
00163 matrix getGaussJordan(scalar_type pivot_threshold = 0,TSize *swapcount = NULL) const;
00164 matrix linearSolve(matrix const &vec,scalar_type pivot_threshold = 0) const;
00165 matrix getCholesky() const;
00166 void getLR(matrix &l,matrix &r) const;
00167
00168
00169 matrix &normalize();
00170 matrix upperTriangleSolve(matrix const &vec) const;
00171 matrix lowerTriangleSolve(matrix const &vec) const;
00172
00173 void wipe(entry_type value = traits_type::zero);
00174 void setDimension(TSize height,TSize width);
00175
00176 void outMatrix(std::ostream &ostr,void (*item_formatter)(std::ostream &os,bool first,bool last) = NULL) const;
00177
00178 protected:
00179 void setup(TSize height,TSize width);
00180 TSize getSize() const {
00181 return Width*Height;
00182 }
00183 TIndex getIndex(TIndex row,TIndex col) const {
00184 return Width*row+col;
00185 }
00186 };
00187 }
00188
00189
00190
00191
00192
00193 template <class T,class Traits>
00194 inline ixion::matrix<T,Traits> operator*(T scalar,ixion::matrix<T,Traits> const &mat);
00195 template <class T,class Traits>
00196 inline ixion::matrix<T,Traits> operator*(ixion::matrix<T,Traits> const &mat,T scalar);
00197 template <class T,class Traits>
00198 inline std::istream &operator>>(std::istream &istr,ixion::matrix<T,Traits> &mat);
00199 template <class T,class Traits>
00200 inline std::ostream &operator<<(std::ostream &ostr,ixion::matrix<T,Traits> const &mat);
00201
00202
00203
00204
00205
00206 template<class T,class Traits>
00207 template<class InputIterator>
00208 inline ixion::matrix<T,Traits>::matrix(TSize width,TSize height,InputIterator first) {
00209 setup(width,height);
00210 TSize size = getSize();
00211 iterator it = begin();
00212
00213 while (size--)
00214 *it++ = *first++;
00215 }
00216
00217
00218
00219
00220
00221 template <class T,class Traits>
00222 inline ixion::matrix<T,Traits> operator*(ixion::matrix<T,Traits>::scalar_type scalar,ixion::matrix<T,Traits> const &mat) {
00223 ixion::matrix<T,Traits> copy(mat);
00224 copy *= scalar;
00225 return copy;
00226 }
00227
00228
00229
00230
00231 template <class T,class Traits>
00232 inline ixion::matrix<T,Traits> operator*(ixion::matrix<T,Traits> const &mat,ixion::matrix<T,Traits>::scalar_type scalar) {
00233 ixion::matrix<T,Traits> copy(mat);
00234 copy *= scalar;
00235 return copy;
00236 }
00237
00238
00239
00240
00241 template <class T,class Traits>
00242 inline std::istream &operator>>(std::istream &istr,ixion::matrix<T,Traits> &mat) {
00243 ixion::TSize height,width;
00244 char c;
00245 istr >> height >> c >> width;
00246 mat.setDimension(height,width);
00247 for (ixion::TIndex y = 0;y < height;y++)
00248 for (ixion::TIndex x = 0;x < width;x++)
00249 istr >> mat(y,x);
00250 return istr;
00251 }
00252
00253
00254
00255
00256 template <class T,class Traits>
00257 inline std::ostream &operator<<(std::ostream &ostr,ixion::matrix<T,Traits> const &mat) {
00258 mat.outMatrix(ostr);
00259 return ostr;
00260 }
00261
00262
00263
00264
00265 #endif