Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <ios>
- #include <sstream>
- #include <algorithm>
- #include <functional>
- #include <boost/range/algorithm.hpp>
- #include <boost/range/adaptor/strided.hpp>
- #include <boost/range/adaptor/sliced.hpp>
- #include <boost/typeof/typeof.hpp>
- #include "Vector.h"
- #ifndef MATRIX_H
- #define MATRIX_H
- template<class T,
- std::size_t rowsize,
- std::size_t colsize>
- class Matrix{
- private:
- // row and/or colsize must be greater then 0;
- static_assert(rowsize > 0, "Number of Rows must be greater then 0.");
- static_assert(colsize > 0, "Number of Columns must be greater then 0.");
- // Data is stored in a MVector, a modified std::vector
- MVector<T> matrix;
- // size of row dimension of the matrix
- std::size_t row_dim;
- // size of row dimension of the matrix
- std::size_t column_dim;
- public:
- // *******************************************************
- // Constructors
- // *******************************************************
- // default constructor
- // @ param "rowsize" - row dimension of matrix
- // @ param "colsize" - column dimension of matrix
- Matrix() :matrix(rowsize * colsize),
- row_dim(rowsize),
- column_dim(colsize) {}
- // initializer list constructor
- // allows to create a matrix by an initialiser list
- // example: Matrix<int, 2, 2> a_matrix = {1,2,3,4};
- // @param "il" - initializer list
- Matrix(std::initializer_list<T> il) :matrix(il),
- row_dim(rowsize),
- column_dim(colsize){}
- // constructor by MVector
- // if the size of the vector is larger then the size of the matrix,
- // the matrix will construct with the first rowsize*colsize elements of the vector
- // if the size of the vector is smaller then the size of the matrix,
- // the matrix will not construct
- explicit Matrix(const MVector<T>& s): matrix(s),
- row_dim(rowsize),
- column_dim(colsize){
- }
- explicit Matrix(MVector<T>&& s): matrix(s),
- row_dim(rowsize),
- column_dim(colsize){
- }
- // parameter pack constructor
- // constructs a matrix by typing values into the brackets
- // example: Matrix<int, 2, 2> a_matrix(1,2,3,4)
- // values can be of any type, they will be interpreted as of class T
- template<class ... N>
- explicit Matrix(T first, N&&... values): matrix{first,
- std::forward<T>(static_cast<T>(values))...},
- row_dim(rowsize),
- column_dim(colsize){}
- // *******************************************************
- // Iterator support
- // *******************************************************
- // traverse the entire vector
- typename std::vector<T>::iterator Begin(){
- return matrix.Begin();
- }
- typename std::vector<T>::iterator End(){
- return matrix.End();
- }
- typename std::vector<T>::const_iterator Cbegin() const{
- return matrix.Cbegin();
- }
- typename std::vector<T>::const_iterator Cend() const{
- return matrix.Cend();
- }
- typename std::vector<T>::reverse_iterator Rbegin(){
- return matrix.Rbegin();
- }
- typename std::vector<T>::reverse_iterator Rend(){
- return matrix.Rend();
- }
- typename std::vector<T>::const_reverse_iterator Crbegin() const{
- return matrix.Crbegin();
- }
- typename std::vector<T>::const_reverse_iterator Crend() const{
- return matrix.Crend();
- }
- // column traversing
- // don't unfortunatly lnow what to replace auto with
- auto Begin_col( std::size_t i ){
- return = boost::begin(boost::adaptors::stride(
- boost::adaptors::slice(matrix.get_data(), i, size()), cols()) );
- }
- auto End_col( std::size_t i ){
- return boost::end(boost::adaptors::stride(
- boost::adaptors::slice(matrix.get_data(), i, size()), cols()) );
- }
- //row traversing
- auto Begin_row( std::size_t i ){
- return boost::begin(boost::adaptors::slice(matrix.get_data(), i*cols(), i*cols()+cols()));
- }
- auto End_row( std::size_t i ){
- return boost::end(boost::adaptors::slice(matrix.get_data(), i*cols(), i*cols()+cols()));
- }
- // returns the number of elements in the matrix
- std::size_t size() const{
- return matrix.size();
- }
- // returns the number of rows of the matrix
- std::size_t rows() const{
- return row_dim;
- }
- // returns the number of colums of the matrix
- std::size_t cols() const{
- return column_dim;
- }
- // returns the matrix as a vector
- std::vector<T>& as_vector() {
- return matrix.get_data();
- }
- // allows to access an element of the matrix by index expressed
- // in terms of rows and columns
- // @ param "r" - r'th row of the matrix
- // @ param "c" - c'th column of the matrix
- std::size_t index(std::size_t r, std::size_t c) const {
- return r*cols()+c;
- }
- // returns a MVector object with the r'th row as it's elements
- // slicing is possible from both ends and by "jumping" over elements
- // @ param "begin" - starts at the n'th element
- // @ param "end" - substracts m from from the last element.
- // @ param "by" - selects every n'th element
- MVector<T> get_row(std::size_t r, std::size_t begin = 0,
- std::size_t end = 0, std::size_t by = 1) const{
- MVector<T> row;
- for (std::size_t i = index(r,begin); i < index(r,cols()-end); i += by) {
- row.addTo(matrix[i]);
- }
- return row;
- }
- // get c'th column
- // slicing is possible from both ends and by "jumping" over elements
- // @ param "begin" - starts at the n'th element
- // @ param "end" - substracts m from from the last element.
- // @ param "by" - selects every n'th colum
- MVector<T> get_column(std::size_t c, std::size_t begin = 0,
- std::size_t end = 0, std::size_t by = 1) const{
- assert(c < cols() && end < rows());
- MVector<T> columns;
- for (std::size_t i = index(begin, c); i < index(rows()-end,c); i+=by*cols()) {
- columns.addTo(matrix[i]);
- }
- return columns;
- }
- // get the diagonal elements of the matrix
- // stors the diagonal in MVector
- // and returns the vector
- MVector<T> get_diagonal(){
- MVector<T> diag;
- Matrix<T, rowsize, colsize> temp = *this;
- for (std::size_t i = 0; i < rowsize; i++) {
- diag.addTo(temp(i,i));
- }
- return diag;
- }
- // assignment operator
- // assignes the content of another Matrix object to this one
- // takes advantage of the overloaded " = " operator of the MVector class
- // @ param "rhs" = Matrix object on the right hand side of the " = " sign
- Matrix<T, rowsize, colsize>& operator=(Matrix<T, rowsize, colsize> rhs) {
- this->matrix = rhs.matrix;
- return *this;
- }
- // brackets operator
- // return an elements stored in the matrix
- // @ param "i" - i'th element in the matrix
- T& operator[](std::size_t i) {
- assert(i < size());
- return matrix[i];
- }
- const T& operator[](std::size_t i) const {
- assert(i < size());
- return matrix[i];
- }
- // brackets operator
- // return an elements stored in the matrix
- // @ param "r" - r'th row in the matrix
- // @ param "c" - c'th column in the matrix
- T& operator()(std::size_t r, std::size_t c) {
- assert(r < rows() && c < matrix.size() / rows());
- return matrix[index(r,c)];
- }
- const T& operator()(std::size_t r, std::size_t c) const {
- assert(r < rows() && c < matrix.size() / rows());
- return matrix[index(r,c)];
- }
- // end of class
- };
- // *****************************************************************************
- // // Equality operators
- // *****************************************************************************
- template<class T, std::size_t rowsize, std::size_t colsize>
- bool operator==(const Matrix<T, rowsize, colsize> &lhs,
- const Matrix<T, rowsize, colsize> &rhs) {
- // defined in MVector:
- return lhs.as_vector() == rhs.as_vector();
- }
- template<class T, std::size_t rowsize, std::size_t colsize>
- bool operator!=(const Matrix<T, rowsize, colsize> &lhs,
- const Matrix<T, rowsize, colsize> &rhs) {
- // defined in MVector:
- return (! (lhs == rhs) );
- }
- // *****************************************************************************
- // // OS/iS operators
- // *****************************************************************************
- template<class T, std::size_t row_dim, std::size_t col_dim>
- std::ostream& operator<<(std::ostream &os, const Matrix<T, row_dim, col_dim>& m){
- double max = *std::max_element( m.Cbegin(), m.Cend() );
- std::stringstream convert;
- convert << max;
- for(std::size_t i = 0; i < m.rows(); i++){
- os << "[" << i << ",]" << " ";
- for(std::size_t j = 0; j <m.cols(); j++){
- os << std::right << std::setw( convert.str().size() + 1 ) << m(i,j) << " ";
- } os << std::endl;
- }
- return os;
- }
- // stores the data rowise
- template<class T, std::size_t rowsize, std::size_t colsize>
- std::istream& operator>>(std::istream &is, Matrix<T, rowsize, colsize>& m){
- std::cout << "Enter " << rowsize*colsize << " numbers to construct the matrix: " <<std::endl;
- for(std::size_t i = 0; i < rowsize*colsize; i++){
- is >> m[i];
- }
- return is;
- }
- //more +=, +, *=, * ... overloaded operators
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement