matrix.h
namespace math_use
{
template <class Type>
class generaterand {
private:
Type m_start;
Type m_end;
public:
generaterand(const Type _start = -20, const Type _end = 20) : m_start(_start), m_end(_end) {}
Type operator () () const
{
std::random_device rd;
return Type(m_start + ((double)rd() / (double)(rd.max() - rd.min())) * (m_end - m_start));
}
};
template <class Type>
class number_multi {
private:
Type m_number;
public:
number_multi(const Type _num) : m_number(_num) {}
Type operator () (const Type _value) const {
return Type(m_number * _value);
}
};
template <class Type>
class number_add {
public:
Type operator () (const Type _lhs_value, const Type _rhs_value) const {
return Type(_lhs_value + _rhs_value);
}
};
template <class Type>
class number_subtraction {
public:
Type operator () (const Type _lhs_value, const Type _rhs_value) const {
return Type(_lhs_value - _rhs_value);
}
};
template <class Type>
class matrix
{
typedef typename std::vector<std::vector<Type> > matrix_type;
typedef typename matrix_type::iterator matt_iterator;
typedef typename matrix_type::const_iterator const_matt_iterator;
typedef typename std::vector<Type> vector_type;
typedef typename vector_type::iterator vec_iterator;
typedef typename vector_type::const_iterator const_vec_iterator;
friend std::ostream& operator << (std::ostream &of, const matrix& m_matt) {
std::ostream_iterator<Type> outs(of, " ");
std::for_each(m_matt._matt.begin(), m_matt._matt.end(), [&](const vector_type& _meta) -> void {
std::copy(_meta.begin(), _meta.end(), outs);
of << std::endl; });
return of;
}
friend std::istream& operator >> (std::istream &inf, matrix& m_matt) {
std::for_each(m_matt._matt.begin(), m_matt._matt.end(), [&] (vector_type& m_meta) -> void {
std::for_each(m_meta.begin(), m_meta.end(), [&] (Type& _value) -> void {
inf >> _value; });
});
return inf;
}
friend matrix operator * (const matrix& _lhs, const matrix& _rhs) {
matrix m_multi(_lhs.m_row, _rhs.m_col);
for(unsigned int i_row = 0; i_row < m_multi.m_row; ++i_row) {
for(unsigned int i_col = 0; i_col < m_multi.m_col; ++i_col) {
m_multi.getdate(i_row, i_col) = 0;
for(unsigned int i_add = 0; i_add < _lhs.m_col; ++i_add) {
m_multi.getdate(i_row, i_col) += _lhs.getdate(i_row, i_add) * _rhs.getdate(i_add, i_col);
}
}
}
return m_multi;
}
friend matrix& operator *= (matrix& _rhs, const Type _lhs_num) {
std::for_each(_rhs._matt.begin(), _rhs._matt.end(), [&] (vector_type& meta_vector) -> void {
std::transform(meta_vector.begin(), meta_vector.end(), meta_vector.begin(), number_multi<Type> (_lhs_num));
});
return _rhs;
}
friend matrix operator * (const matrix& _lhs, const Type _rhs_num) {
matrix m_multi(_lhs);
m_multi *= _rhs_num;
return m_multi;
}
friend matrix operator * (const Type _lhs_num, const matrix& _rhs) {
matrix m_multi(_rhs);
m_multi *= _lhs_num;
return m_multi;
}
friend matrix& operator -= (matrix& _lhs, const matrix& _rhs) {
assert(_lhs.m_row == _rhs.m_row && _lhs.m_col == _rhs.m_col);
const_matt_iterator _rhs_iter = _rhs._matt.begin();
std::for_each(_lhs._matt.begin(), _lhs._matt.end(), [&] (vector_type& meta_vector) ->void {
std::transform(meta_vector.begin(), meta_vector.end(), (*_rhs_iter).begin(), meta_vector.begin(), number_subtraction<Type>());
++_rhs_iter; });
return _lhs;
}
friend matrix operator - (const matrix& _lhs, const matrix& _rhs) {
matrix m_meta(_lhs);
m_meta -= _rhs;
return m_meta;
}
friend matrix& operator += (matrix& _lhs, const matrix& _rhs) {
assert(_lhs.m_row == _rhs.m_row && _lhs.m_col == _rhs.m_col);
const_matt_iterator _rhs_iter = _rhs._matt.begin();
std::for_each(_lhs._matt.begin(), _lhs._matt.end(), [&] (vector_type& meta_vector) ->void {
std::transform(meta_vector.begin(), meta_vector.end(), (*_rhs_iter).begin(), meta_vector.begin(), number_add<Type>());
++_rhs_iter; });
return _lhs;
}
friend matrix operator + (const matrix& _lhs, const matrix& _rhs) {
matrix m_meta(_lhs);
m_meta += _rhs;
return m_meta;
}
friend bool operator == (const matrix& _lhs, const matrix& _rhs) {
if(_lhs.m_row != _rhs.m_row || _lhs.m_col != _rhs.m_col) return false;
bool is_equals = true;
const_matt_iterator c_iter = _rhs._matt.begin();
std::for_each(_lhs._matt.begin(), _lhs._matt.end(), [&](const vector_type& _meta) -> void {
is_equals = ((*c_iter) == _meta);
if(is_equals == false) return;
++c_iter; });
return is_equals;
}
friend bool operator != (const matrix& _lhs, const matrix& _rhs) {
return !(_lhs == _rhs);
}
private:
unsigned int m_row, m_col;
matrix_type _matt;
public:
matrix() : m_row(0), m_col(0) {}
matrix(const unsigned int row, const unsigned int col) : m_row(row), m_col(col) {
unsigned int meta_row = row;
while(meta_row != 0) {
std::vector<Type> m_meta(col);
_matt.push_back(m_meta);
--meta_row;
}
}
matrix(const matrix& _matt_rhs) : m_row(_matt_rhs.m_row), m_col(_matt_rhs.m_col), _matt(_matt_rhs._matt) {
}
matrix& operator = (const matrix& _matt_rhs)
{
m_row = _matt_rhs.m_row;
m_col = _matt_rhs.m_col;
_matt.clear();
std::vector<Type> m_meta(m_col);
std::for_each(_matt_rhs._matt.begin(), _matt_rhs._matt.end(), [&] (const vector_type& _meta) -> void {
std::copy(_meta.begin(), _meta.end(), m_meta.begin());
_matt.push_back(m_meta);
});
return (*this);
}
unsigned int get_row () const {
return m_row;
}
unsigned int get_col () const {
return m_col;
}
Type getdate(unsigned int row, unsigned int col) const {
return _matt[row][col];
}
Type& getdate(unsigned int row, unsigned int col) {
return _matt[row][col];
}
matrix T() const
{
unsigned int rhs_col = 0;
matrix rev_matt(m_col, m_row);
std::for_each(rev_matt._matt.begin(), rev_matt._matt.end(), [&] (vector_type& m_meta_value) -> void {
const_matt_iterator m_matt_iterator = _matt.begin();
std::for_each(m_meta_value.begin(), m_meta_value.end(), [&] (Type& _value) -> void {
_value = (*m_matt_iterator)[rhs_col];
++m_matt_iterator; });
++rhs_col;
});
return rev_matt;
}
unsigned int size() const {
return _matt.size();
}
void fill_rand(const Type _start = -20, const Type _end = 20)
{
std::for_each(_matt.begin(), _matt.end(), [&] (vector_type& meta_vector) -> void {
std::generate(meta_vector.begin(), meta_vector.end(), generaterand<Type> (_start, _end)); });
}
virtual ~matrix() {}
void read_para() {
std::ifstream infile("matrix.datum");
if(!infile) {
std::cerr << "can not open file" << std::endl;
return;
}
infile >> (*this);
infile.close();
}
};
}