Advertisement
greannmhar

Matrix.cpp

Oct 14th, 2024
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. #include "Matrix.hpp"
  2. #include <stdexcept>
  3. #include <iomanip>
  4. #include <iostream>
  5. #include <sstream>
  6. // Конструктор
  7. Matrix::Matrix(int size) : N(size) {
  8. allocateMemory();
  9. }
  10.  
  11. // Конструктор копирования
  12. Matrix::Matrix(const Matrix& other) : N(other.N) {
  13. allocateMemory();
  14. copyDataFrom(other);
  15. }
  16.  
  17. // Деструктор
  18. Matrix::~Matrix() {
  19. deallocateMemory();
  20. }
  21.  
  22. // Выделение памяти
  23. void Matrix::allocateMemory() {
  24. data = new double*[N];
  25. for (int i = 0; i < N; ++i) {
  26. data[i] = new double[N];
  27. for (int j = 0; j < N; ++j) {
  28. data[i][j] = 0;
  29. }
  30. }
  31. }
  32.  
  33. // Освобождение памяти
  34. void Matrix::deallocateMemory() {
  35. for (int i = 0; i < N; ++i) {
  36. delete[] data[i];
  37. }
  38. delete[] data;
  39. }
  40.  
  41. // Копирование данных
  42. void Matrix::copyDataFrom(const Matrix& other) {
  43. for (int i = 0; i < N; i++) {
  44. for (int j = 0; j < N; j++) {
  45. data[i][j] = other.data[i][j];
  46. }
  47. }
  48. }
  49.  
  50. // Оператор присваивания
  51. Matrix& Matrix::operator=(const Matrix& other) {
  52. if (this != &other) {
  53. deallocateMemory();
  54. N = other.N;
  55. allocateMemory();
  56. copyDataFrom(other);
  57. }
  58. return *this;
  59. }
  60.  
  61. // Доступ к элементам
  62. double& Matrix::operator()(int i, int j) {
  63. if (i >= N || j >= N || i < 0 || j < 0)
  64. throw std::out_of_range("Index out of bounds");
  65. return data[i][j];
  66. }
  67.  
  68. const double& Matrix::operator()(int i, int j) const {
  69. if (i >= N || j >= N || i < 0 || j < 0)
  70. throw std::out_of_range("Index out of bounds");
  71. return data[i][j];
  72. }
  73.  
  74. // Арифметические операции
  75. Matrix Matrix::operator+(const Matrix& other) const {
  76. if (N != other.N)
  77. throw std::invalid_argument("Matrix sizes do not match");
  78.  
  79. Matrix result(N);
  80. for (int i = 0; i < N; ++i) {
  81. for (int j = 0; j < N; ++j) {
  82. result(i, j) = (*this)(i, j) + other(i, j);
  83. }
  84. }
  85. return result;
  86. }
  87.  
  88. Matrix& Matrix::operator+=(const Matrix& other) {
  89. *this = *this + other;
  90. return *this;
  91. }
  92.  
  93. Matrix Matrix::operator*(const Matrix& other) const {
  94. if (N != other.N)
  95. throw std::invalid_argument("Matrix sizes do not match");
  96.  
  97. Matrix result(N);
  98. for (int i = 0; i < N; ++i) {
  99. for (int j = 0; j < N; ++j) {
  100. result(i, j) = 0;
  101. for (int k = 0; k < N; ++k) {
  102. result(i, j) += (*this)(i, k) * other(k, j);
  103. }
  104. }
  105. }
  106. return result;
  107. }
  108.  
  109. // Операции сравнения
  110. bool Matrix::operator==(const Matrix& other) const {
  111. if (N != other.N)
  112. return false;
  113. for (int i = 0; i < N; ++i) {
  114. for (int j = 0; j < N; ++j) {
  115. if (data[i][j] != other.data[i][j])
  116. return false;
  117. }
  118. }
  119. return true;
  120. }
  121.  
  122. bool Matrix::operator!=(const Matrix& other) const {
  123. return !(*this == other);
  124. }
  125.  
  126. // Транспонирование
  127. Matrix Matrix::transpose() const {
  128. Matrix result(N);
  129. for (int i = 0; i < N; ++i) {
  130. for (int j = 0; j < N; ++j) {
  131. result(i, j) = (*this)(j, i);
  132. }
  133. }
  134. return result;
  135. }
  136.  
  137. // Ввод и вывод
  138.  
  139. std::istream& operator>>(std::istream& is, Matrix& matrix) {
  140. int totalElements = matrix.N * matrix.N; // Общее количество элементов
  141. int elementCount = 0; // Счетчик введенных элементов
  142.  
  143. // Создадим временный буфер для хранения всех введенных данных
  144. std::string inputLine;
  145. std::getline(is >> std::ws, inputLine); // Считываем всю строку с элементами, игнорируя начальные пробелы
  146. std::stringstream ss(inputLine); // Используем stringstream для обработки чисел
  147.  
  148. for (int i = 0; i < matrix.N; ++i) {
  149. for (int j = 0; j < matrix.N; ++j) {
  150. if (!(ss >> matrix(i, j))) { // Попытка ввести элемент
  151. throw std::runtime_error("Error: Invalid input. Please enter numeric values.");
  152. }
  153. elementCount++; // Увеличиваем счетчик при успешном вводе
  154. }
  155. }
  156.  
  157. // Проверяем, что после ввода всех нужных элементов не осталось лишних
  158. double extra;
  159. if (ss >> extra) { // Если после чтения всех элементов есть еще данные, это ошибка
  160. throw std::runtime_error("Error: Too many elements entered.");
  161. }
  162.  
  163. if (elementCount != totalElements) {
  164. throw std::runtime_error("Error: Incorrect number of elements entered.");
  165. }
  166.  
  167. return is;
  168. }
  169.  
  170.  
  171.  
  172. std::ostream& operator<<(std::ostream& out, const Matrix& matrix) {
  173. for (int i = 0; i < matrix.N; ++i) {
  174. for (int j = 0; j < matrix.N; ++j) {
  175. out << std::setw(10) << matrix(i, j) << " ";
  176. }
  177. out << std::endl;
  178. }
  179. return out;
  180. }
  181.  
  182. // Вычисление определителя (рекурсивно)
  183. double Matrix::determinant() const {
  184. if (N == 1) return data[0][0];
  185. if (N == 2) return data[0][0] * data[1][1] - data[0][1] * data[1][0];
  186.  
  187. double det = 0;
  188. for (int p = 0; p < N; ++p) {
  189. Matrix subMatrix(N - 1);
  190. for (int i = 1; i < N; i++) {
  191. int sub_j = 0;
  192. for (int j = 0; j < N; j++) {
  193. if (j == p) continue;
  194. subMatrix(i - 1, sub_j) = data[i][j];
  195. sub_j++;
  196. }
  197. }
  198. det += data[0][p] * (p % 2 == 0 ? 1 : -1) * subMatrix.determinant();
  199. }
  200. return det;
  201. }
  202.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement