1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Andy Rushton
4 // Copyright: (c) Southampton University 1999-2004
5 // (c) Andy Rushton 2004-2009
6 // License: BSD License, see ../docs/license.html
8 ////////////////////////////////////////////////////////////////////////////////
13 ////////////////////////////////////////////////////////////////////////////////
16 matrix<T>::matrix(unsigned rows, unsigned cols, const T& fill) throw()
21 resize(rows,cols,fill);
25 matrix<T>::~matrix(void) throw()
27 for (unsigned row = 0; row < m_rows; row++)
33 matrix<T>::matrix(const matrix<T>& r) throw()
42 matrix<T>& matrix<T>::operator =(const matrix<T>& right) throw()
44 // clear the old values
45 for (unsigned row = 0; row < m_rows; row++)
51 // now reconstruct with the new
52 resize(right.m_rows, right.m_cols);
53 for (unsigned row = 0; row < m_rows; row++)
54 for (unsigned col = 0; col < m_cols; col++)
55 m_data[row][col] = right.m_data[row][col];
60 void matrix<T>::resize(unsigned rows, unsigned cols, const T& fill) throw()
62 // a grid is an array of rows, where each row is an array of T
63 // a zero-row or zero-column matrix has a null grid
64 // TODO - make this exception-safe - new could throw here and that would cause a memory leak
68 new_grid = new T*[rows];
69 for (unsigned row = 0; row < rows; row++)
71 new_grid[row] = new T[cols];
72 // copy old items to the new grid but only within the bounds of the intersection of the old and new grids
73 // fill the rest of the grid with the initial value
74 for (unsigned col = 0; col < cols; col++)
75 if (row < m_rows && col < m_cols)
76 new_grid[row][col] = m_data[row][col];
78 new_grid[row][col] = fill;
81 // destroy the old grid
82 for (unsigned row = 0; row < m_rows; row++)
85 // move the new data into the matrix
92 unsigned matrix<T>::rows(void) const throw()
98 unsigned matrix<T>::columns(void) const throw()
104 void matrix<T>::erase(const T& fill) throw()
106 for (unsigned row = 0; row < m_rows; row++)
107 for (unsigned col = 0; col < m_cols; col++)
108 insert(row,col,fill);
112 void matrix<T>::erase(unsigned row, unsigned col, const T& fill) throw(std::out_of_range)
114 insert(row,col,fill);
118 void matrix<T>::insert(unsigned row, unsigned col, const T& element) throw(std::out_of_range)
120 if (row >= m_rows) throw std::out_of_range("matrix::insert row");
121 if (col >= m_cols) throw std::out_of_range("matrix::insert col");
122 m_data[row][col] = element;
126 const T& matrix<T>::item(unsigned row, unsigned col) const throw(std::out_of_range)
128 if (row >= m_rows) throw std::out_of_range("matrix::item row");
129 if (col >= m_cols) throw std::out_of_range("matrix::item col");
130 return m_data[row][col];
134 T& matrix<T>::item(unsigned row, unsigned col) throw(std::out_of_range)
136 if (row >= m_rows) throw std::out_of_range("matrix::item row");
137 if (col >= m_cols) throw std::out_of_range("matrix::item col");
138 return m_data[row][col];
142 const T& matrix<T>::operator()(unsigned row, unsigned col) const throw(std::out_of_range)
144 if (row >= m_rows) throw std::out_of_range("matrix::operator() row");
145 if (col >= m_cols) throw std::out_of_range("matrix::operator() col");
146 return m_data[row][col];
150 T& matrix<T>::operator()(unsigned row, unsigned col) throw(std::out_of_range)
152 if (row >= m_rows) throw std::out_of_range("matrix::operator() row");
153 if (col >= m_cols) throw std::out_of_range("matrix::operator() col");
154 return m_data[row][col];
158 void matrix<T>::fill(const T& item) throw()
164 void matrix<T>::fill_column(unsigned col, const T& item) throw (std::out_of_range)
166 if (col >= m_cols) throw std::out_of_range("matrix::fill_column");
167 for (unsigned row = 0; row < m_rows; row++)
168 insert(row, col, item);
172 void matrix<T>::fill_row(unsigned row, const T& item) throw (std::out_of_range)
174 if (row >= m_rows) throw std::out_of_range("matrix::fill_row");
175 for (unsigned col = 0; col < m_cols; col++)
176 insert(row, col, item);
180 void matrix<T>::fill_leading_diagonal(const T& item) throw()
182 for (unsigned i = 0; i < m_cols && i < m_rows; i++)
187 void matrix<T>::fill_trailing_diagonal(const T& item) throw()
189 for (unsigned i = 0; i < m_cols && i < m_rows; i++)
190 insert(i, m_cols-i-1, item);
194 void matrix<T>::make_identity(const T& one, const T& zero) throw()
197 fill_leading_diagonal(one);
201 void matrix<T>::transpose(void) throw()
203 // no gain in manipulating this, since building a new matrix is no less efficient
204 matrix<T> transposed(columns(), rows());
205 for (unsigned row = 0; row < rows(); row++)
206 for (unsigned col = 0; col < columns(); col++)
207 transposed.insert(col,row,item(row,col));
208 // TODO - avoid an extra copy by swapping the member data here
212 ////////////////////////////////////////////////////////////////////////////////
214 } // end namespace stlplus