Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.03 KB | None | 0 0
  1. template <typename T = double, typename SFINAE = std::void_t<decltype(std::declval<T&>() * std::declval<T&>(), std::declval<T&>() + std::declval<T&>())>>
  2. class matrix {
  3. private:
  4.  
  5.     std::vector<std::vector<T>> data;
  6.  
  7.     size_t height;
  8.  
  9.     size_t width;
  10.  
  11. public:
  12.  
  13.     matrix(size_t n, size_t m) noexcept
  14.             : data(m, std::vector<T>(n)),
  15.               height(m),
  16.               width(n)
  17.               { }
  18.  
  19.     matrix(const matrix&) = default;
  20.     matrix& operator=(const matrix&) = default;
  21.     matrix(matrix&&) = default;
  22.     matrix& operator=(matrix&&) = default;
  23.  
  24.     T& operator()(size_t x, size_t y) {
  25.         if (x > width || y > height) {
  26.             throw std::out_of_range("matrix index is too large");
  27.         }
  28.         return data[y][x];
  29.     }
  30.  
  31.     const T operator()(size_t x, size_t y) const {
  32.         if (x > width || y > height) {
  33.             throw std::out_of_range("matrix index is too large");
  34.         }
  35.         return data[y][x];
  36.     }
  37.  
  38.     constexpr size_t get_height() const {
  39.         return height;
  40.     }
  41.  
  42.     constexpr size_t get_width() const {
  43.         return width;
  44.     }
  45.  
  46.     matrix transpose() const {
  47.         matrix result(width, height);
  48.         for (size_t i = 0; i < height; ++i) {
  49.             for (size_t j = 0; j < width; ++j) {
  50.                 result(i, j) = data[i][j];
  51.             }
  52.         }
  53.         return result;
  54.     }
  55.  
  56. };
  57.  
  58. template<typename T, typename U>
  59. auto operator+(const matrix<T>& left, const matrix<U>& right) -> matrix<decltype(T() * U())> {
  60.     if (left.get_width() != right.get_width() || left.get_height() != right.get_height()) {
  61.         throw std::runtime_error("we need two matrix with the same dimension for addition");
  62.     }
  63.     matrix<decltype(T() * U())> result(left.get_height(), left.get_width());
  64.     for (size_t i = 0; i < left.get_height(); ++i) {
  65.         for (size_t j = 0; j < left.get_width(); ++j) {
  66.             result(j, i) = left(j, i) + right(j, i);
  67.         }
  68.     }
  69.     return result;
  70. }
  71.  
  72. template<typename T, typename U>
  73. auto operator*(const T multiplier, const matrix<U>& right) -> matrix<decltype(T() * U())> {
  74.     matrix<decltype(T() * U())> result(right.get_height(), right.get_width());
  75.     for (size_t i = 0; i < right.get_height(); ++i) {
  76.         for (size_t j = 0; j < right.get_width(); ++j) {
  77.             result(j, i) = multiplier * right(j, i);
  78.         }
  79.     }
  80.     return result;
  81. }
  82.  
  83. template<typename T, typename U>
  84. auto operator*(const matrix<T>& left, const U multiplier) -> matrix<decltype(U() * T())> {
  85.     matrix<decltype(T() * U())> result(left.get_height(), left.get_width());
  86.     for (size_t i = 0; i < left.get_height(); ++i) {
  87.         for (size_t j = 0; j < left.get_width(); ++j) {
  88.             result(j, i) = left(j, i) * multiplier;
  89.         }
  90.     }
  91.     return result;
  92. }
  93.  
  94. template<typename T, typename U>
  95. auto operator*(const matrix<T>& left, const matrix<U> right) -> matrix<decltype(U() * T())> {
  96.     if (left.get_width() != right.get_height()) {
  97.         throw std::runtime_error("cannot multiply two matrix if the dimensions aren't correct");
  98.     }
  99.     matrix<decltype(T() * U())> result(left.get_height(), right.get_width());
  100.     for (size_t i = 0; i < left.get_height(); ++i) {
  101.         for (size_t j = 0; j < right.get_width(); ++j) {
  102.             for (size_t k = 0; k < left.get_width(); ++k) {
  103.                 result(j, i) += left(k, i) * right(j, k);
  104.             }
  105.         }
  106.     }
  107.     return result;
  108. }
  109.  
  110. template<typename T, typename U>
  111. auto hadamard_multiplicaton(const matrix<T>& left, const matrix<U>& right) -> matrix<decltype(std::declval<T&>() * std::declval<U&>())> {
  112.     if (left.get_width() != right.get_width() || left.get_height() != right.get_height()) {
  113.         throw std::runtime_error("we need two matrix with the same dimension for hadamard multiplication");
  114.     }
  115.     matrix<decltype(std::declval<T&>() * std::declval<U&>())> result(left.get_height(), left.get_width());
  116.     for (size_t i = 0; i < left.get_height(); ++i) {
  117.         for (size_t j = 0; j < left.get_width(); ++j) {
  118.             result(j, i) = left(j, i) * right(j, i);
  119.         }
  120.     }
  121.     return result;
  122. }
  123.  
  124. template<typename T, typename U>
  125. auto kronecker_product(const matrix<T>& left, const matrix<U>& right) -> matrix<decltype(std::declval<T&>() * std::declval<U&>())> {
  126.     if (left.get_height() != 1 || right.get_width() != 1) {
  127.         throw std::runtime_error("we need a row and a column vector for kronecker product");
  128.     }
  129.     matrix<decltype(std::declval<T&>() * std::declval<U&>())> result(right.get_height(), left.get_width());
  130.     for (size_t i = 0; i < right.get_height(); ++i) {
  131.         for (size_t j = 0; j < left.get_width(); ++j) {
  132.             result(j, i) = left(j, 0) * right(0, i);
  133.         }
  134.     }
  135.     return result;
  136. }
  137.  
  138. template <typename T>
  139. std::ostream& operator<<(std::ostream& os, const matrix<T>& m) {
  140.     for (size_t i = 0; i < m.get_height(); ++i) {
  141.         for (size_t j = 0; j < m.get_width(); ++j) {
  142.             os << m(j, i) << "\t";
  143.         }
  144.         os << "\n";
  145.     }
  146.     return os;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement