[6ab5981] | 1 | /* emacs edit mode for this file is -*- C++ -*- */ |
---|
[c5f2101] | 2 | |
---|
[fb1675] | 3 | #include "factory/templates/ftmpl_matrix.h" |
---|
[c5f2101] | 4 | |
---|
| 5 | template <class T> |
---|
| 6 | Matrix<T>::Matrix( int nr, int nc ) : NR(nr), NC(nc) |
---|
| 7 | { |
---|
| 8 | ASSERT( (nr > 0 && nc > 0) || (nr == 0 && nc == 0), "illegal index" ); |
---|
| 9 | if ( nr == 0 ) |
---|
[2bf04b] | 10 | elems = 0; |
---|
[c5f2101] | 11 | else { |
---|
[2bf04b] | 12 | int i; |
---|
| 13 | elems = new T_ptr[nr]; |
---|
| 14 | for ( i = 0; i < nr; i++ ) |
---|
| 15 | elems[i] = new T[nc]; |
---|
[c5f2101] | 16 | } |
---|
| 17 | } |
---|
| 18 | |
---|
| 19 | template <class T> |
---|
| 20 | Matrix<T>::Matrix( const Matrix<T>& M ) : NR(M.NR), NC(M.NC) |
---|
| 21 | { |
---|
| 22 | if ( NR == 0 ) |
---|
[2bf04b] | 23 | elems = 0; |
---|
[c5f2101] | 24 | else { |
---|
[2bf04b] | 25 | int i, j; |
---|
| 26 | elems = new T_ptr[NR]; |
---|
| 27 | for ( i = 0; i < NR; i++ ) { |
---|
| 28 | elems[i] = new T[NC]; |
---|
| 29 | for ( j = 0; j < NC; j++ ) |
---|
| 30 | elems[i][j] = M.elems[i][j]; |
---|
| 31 | } |
---|
[c5f2101] | 32 | } |
---|
| 33 | } |
---|
| 34 | |
---|
| 35 | template <class T> |
---|
| 36 | Matrix<T>::~Matrix() |
---|
| 37 | { |
---|
| 38 | if ( elems != 0 ) { |
---|
[2bf04b] | 39 | int i; |
---|
| 40 | for ( i = 0; i < NR; i++ ) |
---|
| 41 | delete [] elems[i]; |
---|
| 42 | delete [] elems; |
---|
[c5f2101] | 43 | } |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | template <class T> |
---|
| 47 | Matrix<T>& Matrix<T>::operator= ( const Matrix<T>& M ) |
---|
| 48 | { |
---|
| 49 | if ( this != &M ) { |
---|
[2bf04b] | 50 | int i, j; |
---|
| 51 | if ( NR != M.NR || NC != M.NC ) { |
---|
| 52 | for ( i = 0; i < NR; i++ ) |
---|
| 53 | delete [] elems[i]; |
---|
| 54 | delete elems; |
---|
| 55 | NR = M.NR; NC = M.NC; |
---|
| 56 | elems = new T_ptr[NR]; |
---|
| 57 | for ( i = 0; i < NR; i++ ) |
---|
| 58 | elems[i] = new T[NC]; |
---|
| 59 | } |
---|
| 60 | for ( i = 0; i < NR; i++ ) |
---|
| 61 | for ( j = 0; j < NC; j++ ) |
---|
| 62 | elems[i][j] = M.elems[i][j]; |
---|
[c5f2101] | 63 | } |
---|
| 64 | return *this; |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | template <class T> |
---|
| 68 | SubMatrix<T> Matrix<T>::operator[] ( int i ) |
---|
| 69 | { |
---|
| 70 | ASSERT( i > 0 && i <= NR, "illegal index" ); |
---|
| 71 | return SubMatrix<T>( i, i, 1, NC, *this ); |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | template <class T> |
---|
| 75 | const SubMatrix<T> Matrix<T>::operator[] ( int i ) const |
---|
| 76 | { |
---|
| 77 | ASSERT( i > 0 && i <= NR, "illegal index" ); |
---|
| 78 | return SubMatrix<T>( i, i, 1, NC, *this ); |
---|
| 79 | } |
---|
| 80 | |
---|
| 81 | template <class T> |
---|
| 82 | T& Matrix<T>::operator() ( int row, int col ) |
---|
| 83 | { |
---|
| 84 | ASSERT( row > 0 && col > 0 && row <= NR && col <= NC, "illegal index" ); |
---|
| 85 | return elems[row-1][col-1]; |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | template <class T> |
---|
| 89 | T Matrix<T>::operator() ( int row, int col ) const |
---|
| 90 | { |
---|
| 91 | ASSERT( row > 0 && col > 0 && row <= NR && col <= NC, "illegal index" ); |
---|
| 92 | return elems[row-1][col-1]; |
---|
| 93 | } |
---|
| 94 | |
---|
| 95 | template <class T> |
---|
| 96 | SubMatrix<T> Matrix<T>::operator() ( int rmin, int rmax, int cmin, int cmax ) |
---|
| 97 | { |
---|
| 98 | ASSERT( rmin > 0 && rmax <= NR && rmin <= rmax && cmin > 0 && cmax <= NC && cmin <= cmax , "illegal index" ); |
---|
| 99 | return SubMatrix<T>( rmin, rmax, cmin, cmax, *this ); |
---|
| 100 | } |
---|
| 101 | |
---|
| 102 | template <class T> |
---|
| 103 | const SubMatrix<T> Matrix<T>::operator() ( int rmin, int rmax, int cmin, int cmax ) const |
---|
| 104 | { |
---|
| 105 | ASSERT( rmin > 0 && rmax <= NR && rmin <= rmax && cmin > 0 && cmax <= NC && cmin <= cmax , "illegal index" ); |
---|
| 106 | return SubMatrix<T>( rmin, rmax, cmin, cmax, *this ); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | template <class T> |
---|
| 110 | void Matrix<T>::swapRow ( int i, int j ) |
---|
| 111 | { |
---|
| 112 | ASSERT( i > 0 && i <= NR && j > 0 && j <= NR, "illegal index" ); |
---|
| 113 | if ( i != j ) { |
---|
[2bf04b] | 114 | i--; j--; |
---|
| 115 | T * h = elems[i]; |
---|
| 116 | elems[i] = elems[j]; |
---|
| 117 | elems[j] = h; |
---|
[c5f2101] | 118 | } |
---|
| 119 | } |
---|
| 120 | |
---|
| 121 | template <class T> |
---|
| 122 | void Matrix<T>::swapColumn ( int i, int j ) |
---|
| 123 | { |
---|
| 124 | ASSERT( i > 0 && i <= NC && j > 0 && j <= NC, "illegal index" ); |
---|
| 125 | if ( i != j ) { |
---|
[2bf04b] | 126 | int k; |
---|
| 127 | i--; j--; |
---|
| 128 | for ( k = 0; k < NR; k++ ) { |
---|
| 129 | T h = elems[k][i]; |
---|
| 130 | elems[k][i] = elems[k][j]; |
---|
| 131 | elems[k][j] = h; |
---|
| 132 | } |
---|
[c5f2101] | 133 | } |
---|
| 134 | } |
---|
| 135 | |
---|
[c753a61] | 136 | #ifndef NOSTREAMIO |
---|
[c5f2101] | 137 | template <class T> |
---|
[181148] | 138 | void Matrix<T>::printrow ( OSTREAM & s, int i ) const |
---|
[c5f2101] | 139 | { |
---|
| 140 | s << "( " << elems[i][0]; |
---|
| 141 | for ( int j = 1; j < NC; j++ ) |
---|
[2bf04b] | 142 | s << ", " << elems[i][j]; |
---|
[c5f2101] | 143 | s << " )"; |
---|
| 144 | } |
---|
| 145 | |
---|
| 146 | template <class T> |
---|
[181148] | 147 | void Matrix<T>::print( OSTREAM& s ) const |
---|
[c5f2101] | 148 | { |
---|
| 149 | if ( NR == 0 ) |
---|
[2bf04b] | 150 | s << "( )"; |
---|
[c5f2101] | 151 | else if ( NR == 1 ) { |
---|
[2bf04b] | 152 | s << "( "; |
---|
| 153 | printrow( s, 0 ); |
---|
| 154 | s << " )"; |
---|
[c5f2101] | 155 | } |
---|
| 156 | else { |
---|
[2bf04b] | 157 | int i; |
---|
| 158 | s << "(\n"; |
---|
| 159 | printrow( s, 0 ); |
---|
| 160 | for ( i = 1; i < NR; i++ ) { |
---|
| 161 | s << ",\n"; |
---|
| 162 | printrow( s, i ); |
---|
| 163 | } |
---|
| 164 | s << "\n)"; |
---|
[c5f2101] | 165 | } |
---|
| 166 | } |
---|
[c753a61] | 167 | #endif /* NOSTREAMIO */ |
---|
[c5f2101] | 168 | |
---|
[ccda50] | 169 | /*template <class T> |
---|
[c5f2101] | 170 | Matrix<T> operator+ ( const Matrix<T>& lhs, const Matrix<T>& rhs ) |
---|
| 171 | { |
---|
| 172 | ASSERT( lhs.NR == rhs.NR && lhs.NC == rhs.NC, "incompatible matrices" ); |
---|
| 173 | Matrix<T> res( lhs.NR, rhs.NR ); |
---|
| 174 | int i, j; |
---|
| 175 | for ( i = 0; i < lhs.NR; i++ ) |
---|
[2bf04b] | 176 | for ( j = 0; j < lhs.NC; j++ ) |
---|
| 177 | res.elems[i][j] = lhs.elems[i][j] + rhs.elems[i][j]; |
---|
[c5f2101] | 178 | return res; |
---|
| 179 | } |
---|
| 180 | |
---|
| 181 | template <class T> |
---|
| 182 | Matrix<T> operator- ( const Matrix<T>& lhs, const Matrix<T>& rhs ) |
---|
| 183 | { |
---|
| 184 | ASSERT( lhs.NR == rhs.NR && lhs.NC == rhs.NC, "incompatible matrices" ); |
---|
| 185 | Matrix<T> res( lhs.NR, rhs.NR ); |
---|
| 186 | int i, j; |
---|
| 187 | for ( i = 0; i < lhs.NR; i++ ) |
---|
[2bf04b] | 188 | for ( j = 0; j < lhs.NC; j++ ) |
---|
| 189 | res.elems[i][j] = lhs.elems[i][j] - rhs.elems[i][j]; |
---|
[c5f2101] | 190 | return res; |
---|
| 191 | } |
---|
| 192 | |
---|
| 193 | template <class T> |
---|
| 194 | Matrix<T> operator* ( const Matrix<T>& lhs, const T& rhs ) |
---|
| 195 | { |
---|
| 196 | Matrix<T> res( lhs.NR, lhs.NC ); |
---|
| 197 | int i, j; |
---|
| 198 | for ( i = 0; i < lhs.NR; i++ ) |
---|
[2bf04b] | 199 | for ( j = 0; j < lhs.NC; j++ ) |
---|
| 200 | res.elems[i][j] = lhs.elems[i][j] * rhs; |
---|
[c5f2101] | 201 | return res; |
---|
| 202 | } |
---|
| 203 | |
---|
| 204 | template <class T> |
---|
| 205 | Matrix<T> operator* ( const T& lhs, const Matrix<T>& rhs ) |
---|
| 206 | { |
---|
| 207 | Matrix<T> res( rhs.NR, rhs.NC ); |
---|
| 208 | int i, j; |
---|
| 209 | for ( i = 0; i < rhs.NR; i++ ) |
---|
[2bf04b] | 210 | for ( j = 0; j < rhs.NC; j++ ) |
---|
| 211 | res.elems[i][j] = rhs.elems[i][j] * lhs; |
---|
[c5f2101] | 212 | return res; |
---|
| 213 | } |
---|
| 214 | |
---|
| 215 | template <class T> |
---|
| 216 | Matrix<T> operator* ( const Matrix<T>& lhs, const Matrix<T>& rhs ) |
---|
| 217 | { |
---|
| 218 | ASSERT( lhs.NC == rhs.NR, "incompatible matrices" ); |
---|
| 219 | Matrix<T> res( lhs.NR, rhs.NC ); |
---|
| 220 | int i, j, k; |
---|
| 221 | for ( i = 0; i < lhs.NR; i++ ) |
---|
[2bf04b] | 222 | for ( j = 0; j < rhs.NC; j++ ) { |
---|
| 223 | res[i][j] = 0; |
---|
| 224 | for ( k = 0; k < lhs.NC; k++ ) |
---|
| 225 | res[i][j]+= lhs.elems[i][k] * rhs.elems[k][j]; |
---|
| 226 | } |
---|
[c5f2101] | 227 | return res; |
---|
[ccda50] | 228 | }*/ |
---|
[c5f2101] | 229 | |
---|
| 230 | template <class T> |
---|
| 231 | SubMatrix<T>::SubMatrix( int rmin, int rmax, int cmin, int cmax, const Matrix<T> & m ) : r_min(rmin), r_max(rmax), c_min(cmin), c_max(cmax), M((Matrix<T>&)m) {} |
---|
| 232 | |
---|
| 233 | template <class T> |
---|
| 234 | SubMatrix<T>::SubMatrix( const SubMatrix<T> & S ) : r_min(S.r_min), r_max(S.r_max), c_min(S.c_min), c_max(S.c_max), M(S.M) {} |
---|
| 235 | |
---|
| 236 | template <class T> |
---|
| 237 | SubMatrix<T>& SubMatrix<T>::operator= ( const Matrix<T>& S ) |
---|
| 238 | { |
---|
| 239 | ASSERT( r_max - r_min + 1 == S.NR && c_max - c_min + 1 == S.NC, "incompatible matrices" ); |
---|
| 240 | if ( M.elems != S.elems ) { |
---|
[2bf04b] | 241 | int i, j; |
---|
| 242 | for ( i = 0; i < S.NR; i++ ) |
---|
| 243 | for ( j = 0; j < S.NC; j++ ) |
---|
| 244 | M.elems[r_min+i-1][c_min+j-1] = S.elems[i][j]; |
---|
[c5f2101] | 245 | } |
---|
| 246 | return *this; |
---|
| 247 | } |
---|
| 248 | |
---|
| 249 | template <class T> |
---|
| 250 | SubMatrix<T>& SubMatrix<T>::operator= ( const SubMatrix<T>& S ) |
---|
| 251 | { |
---|
| 252 | ASSERT( r_max - r_min == S.r_max - S.r_min && c_max - c_min == S.c_max - S.c_min, "incompatible matrices" ); |
---|
| 253 | int i, j, n, m; |
---|
| 254 | n = r_max - r_min + 1; |
---|
| 255 | m = c_max - c_min + 1; |
---|
| 256 | if ( M.elems == S.M.elems ) { |
---|
[2bf04b] | 257 | if ( r_min < S.r_min ) { |
---|
| 258 | for ( i = 0; i < n; i++ ) |
---|
| 259 | for ( j = 0; j < m; j++ ) |
---|
| 260 | M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1]; |
---|
| 261 | } |
---|
| 262 | else if ( r_min > S.r_min ) { |
---|
| 263 | for ( i = n-1; i >= 0; i-- ) |
---|
| 264 | for ( j = 0; j < m; j++ ) |
---|
| 265 | M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1]; |
---|
| 266 | } |
---|
| 267 | else if ( c_min < S.c_min ) { |
---|
| 268 | for ( j = 0; j < m; j++ ) |
---|
| 269 | for ( i = 0; i < n; i++ ) |
---|
| 270 | M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1]; |
---|
| 271 | } |
---|
| 272 | else if ( c_min > S.c_min ) { |
---|
| 273 | for ( j = m-1; j >= 0; j-- ) |
---|
| 274 | for ( i = 0; i < n; i++ ) |
---|
| 275 | M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1]; |
---|
| 276 | } |
---|
[c5f2101] | 277 | } |
---|
| 278 | else { |
---|
[2bf04b] | 279 | for ( i = 0; i < n; i++ ) |
---|
| 280 | for ( j = 0; j < m; j++ ) |
---|
| 281 | M.elems[r_min+i-1][c_min+j-1] = S.M.elems[S.r_min+i-1][S.c_min+j-1]; |
---|
[c5f2101] | 282 | } |
---|
| 283 | return *this; |
---|
| 284 | } |
---|
| 285 | |
---|
| 286 | template <class T> |
---|
| 287 | SubMatrix<T>::operator Matrix<T>() const |
---|
| 288 | { |
---|
| 289 | Matrix<T> res( r_max - r_min + 1, c_max - c_min + 1 ); |
---|
| 290 | int i, j; |
---|
| 291 | int n = r_max - r_min + 1, m = c_max - c_min + 1; |
---|
| 292 | for ( i = 0; i < n; i++ ) |
---|
[2bf04b] | 293 | for ( j = 0; j < m; j++ ) |
---|
| 294 | res.elems[i][j] = M.elems[r_min+i-1][c_min+j-1]; |
---|
[c5f2101] | 295 | return res; |
---|
| 296 | } |
---|
| 297 | |
---|
| 298 | template <class T> |
---|
| 299 | T SubMatrix<T>::operator[] ( int i ) const |
---|
| 300 | { |
---|
| 301 | ASSERT( r_min == r_max && i >= c_min && i <= c_max, "illegal index" ); |
---|
| 302 | return M.elems[r_min-1][i-1]; |
---|
| 303 | } |
---|
| 304 | |
---|
| 305 | template <class T> |
---|
| 306 | T& SubMatrix<T>::operator[] ( int i ) |
---|
| 307 | { |
---|
| 308 | ASSERT( r_min == r_max && i >= c_min && i <= c_max, "illegal index" ); |
---|
| 309 | return M.elems[r_min-1][i-1]; |
---|
| 310 | } |
---|
[5bb462] | 311 | |
---|
| 312 | #ifndef NOSTREAMIO |
---|
| 313 | template <class T> |
---|
[181148] | 314 | OSTREAM & operator<< ( OSTREAM & s, const Matrix<T>& M ) |
---|
[5bb462] | 315 | { |
---|
| 316 | M.print( s ); |
---|
| 317 | return s; |
---|
| 318 | } |
---|
| 319 | #endif /* NOSTREAMIO */ |
---|