X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fstlplus%2Fcontainers%2Fmatrix.tpp;h=6bb651157f104c837b768dd030a158badd65ed81;hp=1e2f785b9fd97c6e93c0ec88aff080f8130d2c89;hb=4f6e4488a55f7e3ba3f7485d78177f793c0eab9a;hpb=574af38ed616d1adfa5e6ce35f67cda1f707f89d diff --git a/src/stlplus/containers/matrix.tpp b/src/stlplus/containers/matrix.tpp index 1e2f785..6bb6511 100644 --- a/src/stlplus/containers/matrix.tpp +++ b/src/stlplus/containers/matrix.tpp @@ -1,215 +1,215 @@ -//////////////////////////////////////////////////////////////////////////////// - -// Author: Andy Rushton -// Copyright: (c) Southampton University 1999-2004 -// (c) Andy Rushton 2004-2009 -// License: BSD License, see ../docs/license.html - -//////////////////////////////////////////////////////////////////////////////// - -namespace stlplus -{ - - //////////////////////////////////////////////////////////////////////////////// - - template - matrix::matrix(unsigned rows, unsigned cols, const T& fill) throw() - { - m_rows = 0; - m_cols = 0; - m_data = 0; - resize(rows,cols,fill); - } - - template - matrix::~matrix(void) throw() - { - for (unsigned row = 0; row < m_rows; row++) - delete[] m_data[row]; - delete[] m_data; - } - - template - matrix::matrix(const matrix& r) throw() - { - m_rows = 0; - m_cols = 0; - m_data = 0; - *this = r; - } - - template - matrix& matrix::operator =(const matrix& right) throw() - { - // clear the old values - for (unsigned row = 0; row < m_rows; row++) - delete[] m_data[row]; - delete[] m_data; - m_rows = 0; - m_cols = 0; - m_data = 0; - // now reconstruct with the new - resize(right.m_rows, right.m_cols); - for (unsigned row = 0; row < m_rows; row++) - for (unsigned col = 0; col < m_cols; col++) - m_data[row][col] = right.m_data[row][col]; - return *this; - } - - template - void matrix::resize(unsigned rows, unsigned cols, const T& fill) throw() - { - // a grid is an array of rows, where each row is an array of T - // a zero-row or zero-column matrix has a null grid - // TODO - make this exception-safe - new could throw here and that would cause a memory leak - T** new_grid = 0; - if (rows && cols) - { - new_grid = new T*[rows]; - for (unsigned row = 0; row < rows; row++) - { - new_grid[row] = new T[cols]; - // copy old items to the new grid but only within the bounds of the intersection of the old and new grids - // fill the rest of the grid with the initial value - for (unsigned col = 0; col < cols; col++) - if (row < m_rows && col < m_cols) - new_grid[row][col] = m_data[row][col]; - else - new_grid[row][col] = fill; - } - } - // destroy the old grid - for (unsigned row = 0; row < m_rows; row++) - delete[] m_data[row]; - delete[] m_data; - // move the new data into the matrix - m_data = new_grid; - m_rows = rows; - m_cols = cols; - } - - template - unsigned matrix::rows(void) const throw() - { - return m_rows; - } - - template - unsigned matrix::columns(void) const throw() - { - return m_cols; - } - - template - void matrix::erase(const T& fill) throw() - { - for (unsigned row = 0; row < m_rows; row++) - for (unsigned col = 0; col < m_cols; col++) - insert(row,col,fill); - } - - template - void matrix::erase(unsigned row, unsigned col, const T& fill) throw(std::out_of_range) - { - insert(row,col,fill); - } - - template - void matrix::insert(unsigned row, unsigned col, const T& element) throw(std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::insert row"); - if (col >= m_cols) throw std::out_of_range("matrix::insert col"); - m_data[row][col] = element; - } - - template - const T& matrix::item(unsigned row, unsigned col) const throw(std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::item row"); - if (col >= m_cols) throw std::out_of_range("matrix::item col"); - return m_data[row][col]; - } - - template - T& matrix::item(unsigned row, unsigned col) throw(std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::item row"); - if (col >= m_cols) throw std::out_of_range("matrix::item col"); - return m_data[row][col]; - } - - template - const T& matrix::operator()(unsigned row, unsigned col) const throw(std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::operator() row"); - if (col >= m_cols) throw std::out_of_range("matrix::operator() col"); - return m_data[row][col]; - } - - template - T& matrix::operator()(unsigned row, unsigned col) throw(std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::operator() row"); - if (col >= m_cols) throw std::out_of_range("matrix::operator() col"); - return m_data[row][col]; - } - - template - void matrix::fill(const T& item) throw() - { - erase(item); - } - - template - void matrix::fill_column(unsigned col, const T& item) throw (std::out_of_range) - { - if (col >= m_cols) throw std::out_of_range("matrix::fill_column"); - for (unsigned row = 0; row < m_rows; row++) - insert(row, col, item); - } - - template - void matrix::fill_row(unsigned row, const T& item) throw (std::out_of_range) - { - if (row >= m_rows) throw std::out_of_range("matrix::fill_row"); - for (unsigned col = 0; col < m_cols; col++) - insert(row, col, item); - } - - template - void matrix::fill_leading_diagonal(const T& item) throw() - { - for (unsigned i = 0; i < m_cols && i < m_rows; i++) - insert(i, i, item); - } - - template - void matrix::fill_trailing_diagonal(const T& item) throw() - { - for (unsigned i = 0; i < m_cols && i < m_rows; i++) - insert(i, m_cols-i-1, item); - } - - template - void matrix::make_identity(const T& one, const T& zero) throw() - { - fill(zero); - fill_leading_diagonal(one); - } - - template - void matrix::transpose(void) throw() - { - // no gain in manipulating this, since building a new matrix is no less efficient - matrix transposed(columns(), rows()); - for (unsigned row = 0; row < rows(); row++) - for (unsigned col = 0; col < columns(); col++) - transposed.insert(col,row,item(row,col)); - // TODO - avoid an extra copy by swapping the member data here - *this = transposed; - } - - //////////////////////////////////////////////////////////////////////////////// - -} // end namespace stlplus - +//////////////////////////////////////////////////////////////////////////////// + +// Author: Andy Rushton +// Copyright: (c) Southampton University 1999-2004 +// (c) Andy Rushton 2004 onwards +// License: BSD License, see ../docs/license.html + +//////////////////////////////////////////////////////////////////////////////// + +namespace stlplus +{ + + //////////////////////////////////////////////////////////////////////////////// + + template + matrix::matrix(unsigned rows, unsigned cols, const T& fill) throw() + { + m_rows = 0; + m_cols = 0; + m_data = 0; + resize(rows,cols,fill); + } + + template + matrix::~matrix(void) throw() + { + for (unsigned row = 0; row < m_rows; row++) + delete[] m_data[row]; + delete[] m_data; + } + + template + matrix::matrix(const matrix& r) throw() + { + m_rows = 0; + m_cols = 0; + m_data = 0; + *this = r; + } + + template + matrix& matrix::operator =(const matrix& right) throw() + { + // clear the old values + for (unsigned row = 0; row < m_rows; row++) + delete[] m_data[row]; + delete[] m_data; + m_rows = 0; + m_cols = 0; + m_data = 0; + // now reconstruct with the new + resize(right.m_rows, right.m_cols); + for (unsigned row = 0; row < m_rows; row++) + for (unsigned col = 0; col < m_cols; col++) + m_data[row][col] = right.m_data[row][col]; + return *this; + } + + template + void matrix::resize(unsigned rows, unsigned cols, const T& fill) throw() + { + // a grid is an array of rows, where each row is an array of T + // a zero-row or zero-column matrix has a null grid + // TODO - make this exception-safe - new could throw here and that would cause a memory leak + T** new_grid = 0; + if (rows && cols) + { + new_grid = new T*[rows]; + for (unsigned row = 0; row < rows; row++) + { + new_grid[row] = new T[cols]; + // copy old items to the new grid but only within the bounds of the intersection of the old and new grids + // fill the rest of the grid with the initial value + for (unsigned col = 0; col < cols; col++) + if (row < m_rows && col < m_cols) + new_grid[row][col] = m_data[row][col]; + else + new_grid[row][col] = fill; + } + } + // destroy the old grid + for (unsigned row = 0; row < m_rows; row++) + delete[] m_data[row]; + delete[] m_data; + // move the new data into the matrix + m_data = new_grid; + m_rows = rows; + m_cols = cols; + } + + template + unsigned matrix::rows(void) const throw() + { + return m_rows; + } + + template + unsigned matrix::columns(void) const throw() + { + return m_cols; + } + + template + void matrix::erase(const T& fill) throw() + { + for (unsigned row = 0; row < m_rows; row++) + for (unsigned col = 0; col < m_cols; col++) + insert(row,col,fill); + } + + template + void matrix::erase(unsigned row, unsigned col, const T& fill) throw(std::out_of_range) + { + insert(row,col,fill); + } + + template + void matrix::insert(unsigned row, unsigned col, const T& element) throw(std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::insert row"); + if (col >= m_cols) throw std::out_of_range("matrix::insert col"); + m_data[row][col] = element; + } + + template + const T& matrix::item(unsigned row, unsigned col) const throw(std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::item row"); + if (col >= m_cols) throw std::out_of_range("matrix::item col"); + return m_data[row][col]; + } + + template + T& matrix::item(unsigned row, unsigned col) throw(std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::item row"); + if (col >= m_cols) throw std::out_of_range("matrix::item col"); + return m_data[row][col]; + } + + template + const T& matrix::operator()(unsigned row, unsigned col) const throw(std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::operator() row"); + if (col >= m_cols) throw std::out_of_range("matrix::operator() col"); + return m_data[row][col]; + } + + template + T& matrix::operator()(unsigned row, unsigned col) throw(std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::operator() row"); + if (col >= m_cols) throw std::out_of_range("matrix::operator() col"); + return m_data[row][col]; + } + + template + void matrix::fill(const T& item) throw() + { + erase(item); + } + + template + void matrix::fill_column(unsigned col, const T& item) throw (std::out_of_range) + { + if (col >= m_cols) throw std::out_of_range("matrix::fill_column"); + for (unsigned row = 0; row < m_rows; row++) + insert(row, col, item); + } + + template + void matrix::fill_row(unsigned row, const T& item) throw (std::out_of_range) + { + if (row >= m_rows) throw std::out_of_range("matrix::fill_row"); + for (unsigned col = 0; col < m_cols; col++) + insert(row, col, item); + } + + template + void matrix::fill_leading_diagonal(const T& item) throw() + { + for (unsigned i = 0; i < m_cols && i < m_rows; i++) + insert(i, i, item); + } + + template + void matrix::fill_trailing_diagonal(const T& item) throw() + { + for (unsigned i = 0; i < m_cols && i < m_rows; i++) + insert(i, m_cols-i-1, item); + } + + template + void matrix::make_identity(const T& one, const T& zero) throw() + { + fill(zero); + fill_leading_diagonal(one); + } + + template + void matrix::transpose(void) throw() + { + // no gain in manipulating this, since building a new matrix is no less efficient + matrix transposed(columns(), rows()); + for (unsigned row = 0; row < rows(); row++) + for (unsigned col = 0; col < columns(); col++) + transposed.insert(col,row,item(row,col)); + // TODO - avoid an extra copy by swapping the member data here + *this = transposed; + } + + //////////////////////////////////////////////////////////////////////////////// + +} // end namespace stlplus +