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