00001 #ifndef FASTSHOWER_MATRIX_H
00002 #define FASTSHOWER_MATRIX_H
00003 #include <valarray>
00004 #include "AtlfastUtils/Slice_iter.h"
00005 #include "AtlfastUtils/Cslice_iter.h"
00006 #include <iostream>
00007 #include <cstddef>
00008 #include <assert.h>
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 namespace FastShower {
00019 using std::valarray;
00020 using std::slice;
00021
00022 template<class T>
00023 class Matrix{
00024 private:
00025 valarray<T>* m_v;
00026 size_t m_d1, m_d2;
00027 public:
00028 Matrix(size_t x, size_t y);
00029 Matrix(size_t x, size_t y, T init);
00030 Matrix(const Matrix&);
00031 Matrix& operator=(const Matrix&);
00032 ~Matrix(){delete m_v;}
00033
00034 size_t size() const {return m_d1*m_d2;}
00035 size_t dim1() const {return m_d1;}
00036 size_t dim2() const {return m_d2;}
00037
00038 Slice_iter<T> row(size_t i);
00039 Cslice_iter<T> row(size_t i)const;
00040
00041 Slice_iter<T> column(size_t i);
00042 Cslice_iter<T> column(size_t i)const;
00043
00044 T& operator()(size_t x, size_t y);
00045 T operator()(size_t x, size_t y)const;
00046
00047 Slice_iter<T> operator()(size_t i) {return column(i);}
00048 Cslice_iter<T> operator()(size_t i) const {return column(i);}
00049
00050 Slice_iter<T> operator[](size_t i) {return column(i);}
00051 Cslice_iter<T> operator[](size_t i) const {return column(i);}
00052
00053 Matrix& operator*=(T);
00054
00055 valarray<T>& array() {return *m_v;}
00056
00057 Matrix sub(int minRow,int maxRow,int minCol,int maxCol) const;
00058 void sub(int minRow, int minCol, Matrix& dest) const;
00059 };
00060
00061
00062
00063
00064 template<class T> Matrix<T>::Matrix(size_t x, size_t y){
00065 m_d1=x;
00066 m_d2=y;
00067 m_v=new valarray<T>(x*y);
00068 }
00069
00070 template<class T> Matrix<T>::Matrix(size_t x, size_t y, T init){
00071 m_d1=x;
00072 m_d2=y;
00073 m_v=new valarray<T>(x*y);
00074 for(size_t i=0; i<m_d1*m_d2; ++i) m_v[i]=init;
00075 }
00076
00077 template<class T> T& Matrix<T>::operator()(size_t x, size_t y){
00078 return column(x)[y];
00079 }
00080
00081 template<class T> T Matrix<T>::operator() (size_t x, size_t y) const {
00082 return column(x)[y];
00083 }
00084
00085 template<class T>
00086 T mul(const Cslice_iter<T>& v1,
00087 const valarray<T>& v2){
00088 T res=0;
00089 for( size_t i=0; i<v2.size(); i++) res+=v1[i]*v2[i];
00090 return res;
00091 }
00092
00093 template<class T>
00094 valarray<T> operator*(const Matrix<T>&m, const valarray<T>&v){
00095 valarray<T> res(m.dim2());
00096 for(size_t i=0; i<m.dim2(); i++) res[i]=mul(m.row(i), v);
00097 return res;
00098 }
00099
00100 template<class T>
00101 Matrix<T>& Matrix<T>::operator*=(T d){
00102 (*m_v) *= d;
00103 return *this;
00104 }
00105
00106 template<class T>
00107 Matrix<T> Matrix<T>::sub(int minRow, int maxRow,
00108 int minCol, int maxCol) const{
00109 int endRow=maxRow+1;
00110 int endCol=maxCol+1;
00111
00112 assert(minRow>=0);
00113 assert(minCol>=0);
00114 assert(endRow<=m_d1);
00115 assert(endCol<=m_d2);
00116
00117 int nRow=endRow-minRow;
00118 assert(nRow>0);
00119
00120 int nCol=endCol-minCol;
00121 assert(nCol>0);
00122
00123 Matrix<T> m(nRow, nCol);
00124 int ii=0;
00125 int jj;
00126 for(int i = minRow; i<endRow; ++i){
00127 jj=0;
00128 for(int j = minCol; j<endCol; ++j) m[ii][jj++]=(*this)[i][j];
00129 ++ii;
00130 }
00131 assert(ii == endRow);
00132 assert(jj == endCol);
00133 return m;
00134 }
00135 template<class T>
00136 void Matrix<T>::sub(int minRow, int minCol, Matrix& m) const{
00137 int endRow=minRow+m.m_d1;
00138 int endCol=minCol+m.m_d2;
00139
00140 assert(minRow>=0);
00141 assert(minCol>=0);
00142 assert(endRow<=m_d1);
00143 assert(endCol<=m_d2);
00144
00145 int nRow=endRow-minRow;
00146 assert(nRow>0);
00147
00148 int nCol=endCol-minCol;
00149 assert(nCol>0);
00150
00151 int ii=0;
00152 int jj;
00153 for(int i = minRow; i<endRow; ++i){
00154 jj=0;
00155 for(int j = minCol; j<endCol; ++j) m[ii][jj++]=(*this)[i][j];
00156 ++ii;
00157 }
00158 assert(ii == endRow);
00159 assert(jj == endCol);
00160 return;
00161 }
00162
00163 template<class T> inline Slice_iter<T> Matrix<T>::row(size_t i){
00164 return Slice_iter<T>(m_v, slice(i,m_d1,m_d2));
00165 }
00166
00167 template<class T> Cslice_iter<T> Matrix<T>::row(size_t i) const {
00168 return Cslice_iter<T>(m_v, slice(i,m_d1,m_d2));
00169 }
00170
00171 template<class T> inline Slice_iter<T> Matrix<T>::column(size_t i){
00172 return Slice_iter<T>(m_v, slice(i*m_d2,m_d2,1));
00173 }
00174
00175 template<class T> inline Cslice_iter<T> Matrix<T>::column(size_t i) const {
00176 return Cslice_iter<T>(m_v, slice(i*m_d2,m_d2,1));
00177 }
00178 template<class T>
00179 ostream& operator <<(ostream& o,const Atlfast::Matrix<T>& m){
00180 size_t end1 = m.dim1();
00181 size_t end2 = m.dim2();
00182 size_t i = 0;
00183 size_t j = 0;
00184 for(; i!= end1; ++i){
00185 for(j=0; j!= end2; ++j){
00186 cout<<m(i,j)<<" ";
00187 }
00188 cout<<endl;
00189 }
00190 return o;
00191 }
00192
00193 }
00194
00195 #endif
00196
00197
00198
00199
00200
00201