Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.76 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <ios>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include <functional>
  7. #include <boost/range/algorithm.hpp>
  8. #include <boost/range/adaptor/strided.hpp>
  9. #include <boost/range/adaptor/sliced.hpp>
  10. #include <boost/typeof/typeof.hpp>
  11. #include "Vector.h"
  12.  
  13. #ifndef MATRIX_H
  14. #define MATRIX_H
  15.  
  16.  
  17. template<class T,
  18. std::size_t rowsize,
  19. std::size_t colsize>
  20. class Matrix{
  21.  
  22. private:
  23.  
  24. // row and/or colsize must be greater then 0;
  25. static_assert(rowsize > 0, "Number of Rows must be greater then 0.");
  26. static_assert(colsize > 0, "Number of Columns must be greater then 0.");
  27.  
  28. // Data is stored in a MVector, a modified std::vector
  29. MVector<T> matrix;
  30.  
  31. // size of row dimension of the matrix
  32. std::size_t row_dim;
  33.  
  34. // size of row dimension of the matrix
  35. std::size_t column_dim;
  36.  
  37.  
  38. public:
  39.  
  40. // *******************************************************
  41. // Constructors
  42. // *******************************************************
  43.  
  44. // default constructor
  45. // @ param "rowsize" - row dimension of matrix
  46. // @ param "colsize" - column dimension of matrix
  47. Matrix() :matrix(rowsize * colsize),
  48. row_dim(rowsize),
  49. column_dim(colsize) {}
  50.  
  51. // initializer list constructor
  52. // allows to create a matrix by an initialiser list
  53. // example: Matrix<int, 2, 2> a_matrix = {1,2,3,4};
  54. // @param "il" - initializer list
  55. Matrix(std::initializer_list<T> il) :matrix(il),
  56. row_dim(rowsize),
  57. column_dim(colsize){}
  58.  
  59. // constructor by MVector
  60. // if the size of the vector is larger then the size of the matrix,
  61. // the matrix will construct with the first rowsize*colsize elements of the vector
  62. // if the size of the vector is smaller then the size of the matrix,
  63. // the matrix will not construct
  64. explicit Matrix(const MVector<T>& s): matrix(s),
  65. row_dim(rowsize),
  66. column_dim(colsize){
  67. }
  68.  
  69. explicit Matrix(MVector<T>&& s): matrix(s),
  70. row_dim(rowsize),
  71. column_dim(colsize){
  72. }
  73.  
  74. // parameter pack constructor
  75. // constructs a matrix by typing values into the brackets
  76. // example: Matrix<int, 2, 2> a_matrix(1,2,3,4)
  77. // values can be of any type, they will be interpreted as of class T
  78. template<class ... N>
  79. explicit Matrix(T first, N&&... values): matrix{first,
  80. std::forward<T>(static_cast<T>(values))...},
  81. row_dim(rowsize),
  82. column_dim(colsize){}
  83.  
  84.  
  85.  
  86. // *******************************************************
  87. // Iterator support
  88. // *******************************************************
  89.  
  90. // traverse the entire vector
  91. typename std::vector<T>::iterator Begin(){
  92. return matrix.Begin();
  93. }
  94.  
  95. typename std::vector<T>::iterator End(){
  96. return matrix.End();
  97. }
  98.  
  99. typename std::vector<T>::const_iterator Cbegin() const{
  100. return matrix.Cbegin();
  101. }
  102.  
  103. typename std::vector<T>::const_iterator Cend() const{
  104. return matrix.Cend();
  105. }
  106.  
  107. typename std::vector<T>::reverse_iterator Rbegin(){
  108. return matrix.Rbegin();
  109. }
  110.  
  111. typename std::vector<T>::reverse_iterator Rend(){
  112. return matrix.Rend();
  113. }
  114.  
  115. typename std::vector<T>::const_reverse_iterator Crbegin() const{
  116. return matrix.Crbegin();
  117. }
  118.  
  119. typename std::vector<T>::const_reverse_iterator Crend() const{
  120. return matrix.Crend();
  121. }
  122.  
  123. // column traversing
  124. // don't unfortunatly lnow what to replace auto with
  125. auto Begin_col( std::size_t i ){
  126. return = boost::begin(boost::adaptors::stride(
  127. boost::adaptors::slice(matrix.get_data(), i, size()), cols()) );
  128. }
  129.  
  130. auto End_col( std::size_t i ){
  131. return boost::end(boost::adaptors::stride(
  132. boost::adaptors::slice(matrix.get_data(), i, size()), cols()) );
  133. }
  134.  
  135. //row traversing
  136. auto Begin_row( std::size_t i ){
  137. return boost::begin(boost::adaptors::slice(matrix.get_data(), i*cols(), i*cols()+cols()));
  138. }
  139.  
  140. auto End_row( std::size_t i ){
  141. return boost::end(boost::adaptors::slice(matrix.get_data(), i*cols(), i*cols()+cols()));
  142. }
  143.  
  144.  
  145. // returns the number of elements in the matrix
  146. std::size_t size() const{
  147. return matrix.size();
  148. }
  149.  
  150. // returns the number of rows of the matrix
  151. std::size_t rows() const{
  152. return row_dim;
  153. }
  154.  
  155. // returns the number of colums of the matrix
  156. std::size_t cols() const{
  157. return column_dim;
  158. }
  159.  
  160. // returns the matrix as a vector
  161. std::vector<T>& as_vector() {
  162. return matrix.get_data();
  163. }
  164.  
  165. // allows to access an element of the matrix by index expressed
  166. // in terms of rows and columns
  167. // @ param "r" - r'th row of the matrix
  168. // @ param "c" - c'th column of the matrix
  169. std::size_t index(std::size_t r, std::size_t c) const {
  170. return r*cols()+c;
  171. }
  172.  
  173. // returns a MVector object with the r'th row as it's elements
  174. // slicing is possible from both ends and by "jumping" over elements
  175. // @ param "begin" - starts at the n'th element
  176. // @ param "end" - substracts m from from the last element.
  177. // @ param "by" - selects every n'th element
  178. MVector<T> get_row(std::size_t r, std::size_t begin = 0,
  179. std::size_t end = 0, std::size_t by = 1) const{
  180. MVector<T> row;
  181. for (std::size_t i = index(r,begin); i < index(r,cols()-end); i += by) {
  182. row.addTo(matrix[i]);
  183. }
  184. return row;
  185. }
  186.  
  187. // get c'th column
  188. // slicing is possible from both ends and by "jumping" over elements
  189. // @ param "begin" - starts at the n'th element
  190. // @ param "end" - substracts m from from the last element.
  191. // @ param "by" - selects every n'th colum
  192. MVector<T> get_column(std::size_t c, std::size_t begin = 0,
  193. std::size_t end = 0, std::size_t by = 1) const{
  194. assert(c < cols() && end < rows());
  195. MVector<T> columns;
  196. for (std::size_t i = index(begin, c); i < index(rows()-end,c); i+=by*cols()) {
  197. columns.addTo(matrix[i]);
  198. }
  199. return columns;
  200. }
  201.  
  202. // get the diagonal elements of the matrix
  203. // stors the diagonal in MVector
  204. // and returns the vector
  205. MVector<T> get_diagonal(){
  206. MVector<T> diag;
  207. Matrix<T, rowsize, colsize> temp = *this;
  208. for (std::size_t i = 0; i < rowsize; i++) {
  209. diag.addTo(temp(i,i));
  210. }
  211. return diag;
  212. }
  213.  
  214. // assignment operator
  215. // assignes the content of another Matrix object to this one
  216. // takes advantage of the overloaded " = " operator of the MVector class
  217. // @ param "rhs" = Matrix object on the right hand side of the " = " sign
  218. Matrix<T, rowsize, colsize>& operator=(Matrix<T, rowsize, colsize> rhs) {
  219. this->matrix = rhs.matrix;
  220. return *this;
  221. }
  222.  
  223. // brackets operator
  224. // return an elements stored in the matrix
  225. // @ param "i" - i'th element in the matrix
  226. T& operator[](std::size_t i) {
  227. assert(i < size());
  228. return matrix[i];
  229. }
  230.  
  231. const T& operator[](std::size_t i) const {
  232. assert(i < size());
  233. return matrix[i];
  234. }
  235.  
  236. // brackets operator
  237. // return an elements stored in the matrix
  238. // @ param "r" - r'th row in the matrix
  239. // @ param "c" - c'th column in the matrix
  240. T& operator()(std::size_t r, std::size_t c) {
  241. assert(r < rows() && c < matrix.size() / rows());
  242. return matrix[index(r,c)];
  243. }
  244.  
  245. const T& operator()(std::size_t r, std::size_t c) const {
  246. assert(r < rows() && c < matrix.size() / rows());
  247. return matrix[index(r,c)];
  248. }
  249.  
  250. // end of class
  251. };
  252.  
  253.  
  254. // *****************************************************************************
  255. // // Equality operators
  256. // *****************************************************************************
  257.  
  258. template<class T, std::size_t rowsize, std::size_t colsize>
  259. bool operator==(const Matrix<T, rowsize, colsize> &lhs,
  260. const Matrix<T, rowsize, colsize> &rhs) {
  261.  
  262. // defined in MVector:
  263. return lhs.as_vector() == rhs.as_vector();
  264. }
  265. template<class T, std::size_t rowsize, std::size_t colsize>
  266. bool operator!=(const Matrix<T, rowsize, colsize> &lhs,
  267. const Matrix<T, rowsize, colsize> &rhs) {
  268.  
  269. // defined in MVector:
  270. return (! (lhs == rhs) );
  271. }
  272.  
  273.  
  274. // *****************************************************************************
  275. // // OS/iS operators
  276. // *****************************************************************************
  277.  
  278. template<class T, std::size_t row_dim, std::size_t col_dim>
  279. std::ostream& operator<<(std::ostream &os, const Matrix<T, row_dim, col_dim>& m){
  280. double max = *std::max_element( m.Cbegin(), m.Cend() );
  281. std::stringstream convert;
  282. convert << max;
  283. for(std::size_t i = 0; i < m.rows(); i++){
  284. os << "[" << i << ",]" << " ";
  285. for(std::size_t j = 0; j <m.cols(); j++){
  286. os << std::right << std::setw( convert.str().size() + 1 ) << m(i,j) << " ";
  287. } os << std::endl;
  288. }
  289. return os;
  290. }
  291.  
  292. // stores the data rowise
  293. template<class T, std::size_t rowsize, std::size_t colsize>
  294. std::istream& operator>>(std::istream &is, Matrix<T, rowsize, colsize>& m){
  295.  
  296. std::cout << "Enter " << rowsize*colsize << " numbers to construct the matrix: " <<std::endl;
  297. for(std::size_t i = 0; i < rowsize*colsize; i++){
  298.  
  299. is >> m[i];
  300. }
  301. return is;
  302. }
  303.  
  304. //more +=, +, *=, * ... overloaded operators
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement