1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
#ifndef MATRIX_HPP
#define MATRIX_HPP
#include "stride_iter.hpp" // see Recipe 11.12
#include <valarray>
#include <numeric>
#include <algorithm>
template<class Value_T>
class matrix
{
public:
// public typedefs
typedef Value_T value_type;
typedef matrix self;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef Value_T* row_type;
typedef stride_iter<value_type*> col_type;
typedef const value_type* const_row_type;
typedef stride_iter<const value_type*> const_col_type;
// constructors
matrix() : nrows(0), ncols(0), m() {}
matrix(int r, int c) : nrows(r), ncols(c), m(r * c) {}
matrix(const self& x) : m(x.m), nrows(x.nrows), ncols(x.ncols) {}
template<typename T>
explicit matrix(const std::valarray<T>& x)
: m(x.size() + 1), nrows(x.size()), ncols(1)
{
for (int i=0; i<x.size(); ++i) m[i] = x[i];
}
// allow construction from matrices of other types
template<typename T>
explicit matrix(const matrix<T>& x)
: m(x.size() + 1), nrows(x.nrows), ncols(x.ncols)
{
copy(x.begin(), x.end(), m.begin());
}
// public functions
int rows() const { return nrows; }
int cols() const { return ncols; }
int size() const { return nrows * ncols; }
// element access
row_type row_begin(int n) { return &m[n * cols()]; }
row_type row_end(int n) { return row_begin() + cols(); }
col_type col_begin(int n) { return col_type(&m[n], cols()); }
col_type col_end(int n) { return col_begin(n) + cols(); }
const_row_type row_begin(int n) const { return &m[n * cols()]; }
const_row_type row_end(int n) const { return row_begin() + cols(); }
const_col_type col_begin(int n) const { return col_type(&m[n], cols()); }
const_col_type col_end(int n) const { return col_begin() + cols(); }
iterator begin() { return &m[0]; }
iterator end() { return begin() + size(); }
const_iterator begin() const { return &m[0]; }
const_iterator end() const { return begin() + size(); }
// operators
self& operator=(const self& x) {
m = x.m; nrows = x.nrows; ncols = x.ncols; return *this;
}
self& operator=(value_type x) { m = x; return *this; }
row_type operator[](int n) { return row_begin(n); }
const_row_type operator[](int n) const { return row_begin(n); }
self& operator+=(const self& x) { m += x.m; return *this; }
self& operator-=(const self& x) { m -= x.m; return *this; }
self& operator+=(value_type x) {m += x; return *this; }
self& operator-=(value_type x) { m -= x; return *this; }
self& operator*=(value_type x) { m *= x; return *this; }
self& operator/=(value_type x) { m /= x; return *this; }
self& operator%=(value_type x) { m %= x; return *this; }
self operator-() { return -m; }
self operator+() { return +m; }
self operator!() { return !m; }
self operator~() { return ~m; }
// friend operators
friend self operator+(const self& x, const self& y) { return self(x) += y;}
friend self operator-(const self& x, const self& y) { return self(x) -= y; }
friend self operator+(const self& x, value_type y) { return self(x) += y; }
friend self operator-(const self& x, value_type y) { return self(x) -= y; }
friend self operator*(const self& x, value_type y) { return self(x) *= y; }
friend self operator/(const self& x, value_type y) { return self(x) /= y; }
friend self operator%(const self& x, value_type y) { return self(x) %= y; }
private:
mutable std::valarray<Value_T> m;
int nrows;
int ncols;
};
#endif
|