/
Xakka
/
CPP1
Обзор
Документация
Войти
/
Xakka
/
CPP1
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/S21Matrix.cpp
423 строки
12 KB
moshedur
master: release 1.0
04 янв 2025, 23:23
04 янв 2025, 23:23
a55ad39
Код
Авторство
О чём код?
#include <cstring> #include <stdexcept> #include "s21_matrix_oop.h" /** * Базовый конструктор, инициализирующий матрицу некоторой заранее заданной * размерностью. */ S21Matrix::S21Matrix() { rows_ = MATRIX_SIZE_DEF; cols_ = MATRIX_SIZE_DEF; matrix_ = new double[rows_ * cols_]{0}; } /** * Параметризированный конструктор с количеством строк и столбцов. * @param rows количество строк * @param cols количество столбцов */ S21Matrix::S21Matrix(int rows, int cols) { if (rows > 0 && cols > 0) { rows_ = rows; cols_ = cols; matrix_ = new double[rows_ * cols_]{0}; } else { throw std::out_of_range("Incorrect input, index is out of range"); } } /** * Конструктор копирования * @param other исходная матрица */ S21Matrix::S21Matrix(const S21Matrix &other) { Copy(other); } /** * Функция копирования матрицы * @param other исходная матрица */ void S21Matrix::Copy(const S21Matrix &other) { rows_ = other.rows_; cols_ = other.cols_; matrix_ = new double[rows_ * cols_]{0}; std::memcpy(matrix_, other.matrix_, rows_ * cols_ * sizeof(double)); } /** * Конструктор переноса * @param other переносимая матрица */ S21Matrix::S21Matrix(S21Matrix &&other) { Move(other); } /** * Функция переноса матрицы * @param other исходная матрица */ void S21Matrix::Move(S21Matrix &other) { rows_ = other.rows_; cols_ = other.cols_; matrix_ = new double[rows_ * cols_]{0}; std::memmove(matrix_, other.matrix_, rows_ * cols_ * sizeof(double)); other.rows_ = 0; other.cols_ = 0; } /** * Деструктор */ S21Matrix::~S21Matrix() { if (matrix_) { delete[] matrix_; } rows_ = 0; cols_ = 0; } /** * Проверяет матрицы на равенство между собой * @param other сравнимая матрица * @return результат сравнения true, false */ bool S21Matrix::EqMatrix(const S21Matrix &other) const { bool status = true; if (this->rows_ == other.rows_ && this->cols_ == other.cols_) { for (auto i = 0; i < rows_ * cols_ && status; i++) { if ((this->matrix_[i] > other.matrix_[i] ? this->matrix_[i] - other.matrix_[i] : other.matrix_[i] - this->matrix_[i]) >= ACCURACY) { status = false; } } } else { status = false; } return status; } /** * Функция сложения/вычитания матрицы в зависимости от режима (mode) * @param other прибавляемая матрица * @param mode режим вычисления: -1 вычитание; 1 сложение */ void S21Matrix::SumbMatrix(const S21Matrix &other, int mode) { if (rows_ == other.rows_ && cols_ == other.cols_) { for (auto i = 0; i < rows_ * cols_; i++) { matrix_[i] = matrix_[i] + other.matrix_[i] * mode; } } else { throw std::out_of_range( "Incorrect input, matrices should have the same size"); } } /** * Прибавляет вторую матрицы к текущей * @param other прибавляемая матрица */ void S21Matrix::SumMatrix(const S21Matrix &other) { SumbMatrix(other, 1); } /** * Вычитает из текущей матрицы другую * @param other вычитаемая матрица */ void S21Matrix::SubMatrix(const S21Matrix &other) { SumbMatrix(other, -1); } /** * Умножает текущую матрицу на число * @param num число-множитель */ void S21Matrix::MulNumber(const double num) { for (auto i = 0; i < rows_ * cols_; i++) { matrix_[i] = matrix_[i] * num; } } /** * Умножает текущую матрицу на вторую * @param other матрица-множитель */ void S21Matrix::MulMatrix(const S21Matrix &other) { if (this->cols_ == other.rows_) { S21Matrix tmp(this->rows_, other.cols_); for (int i = 0; i < this->rows_; i++) { for (int j = 0; j < other.cols_; j++) { for (int k = 0; k < this->cols_; k++) { tmp(i, j) += (*this)(i, k) * other(k, j); } } } *this = tmp; } else { throw std::out_of_range( "Incorrect input, matrices should have the same size"); } } /** * Создает новую транспонированную матрицу из текущей и возвращает ее * @return транспонированная матрица */ S21Matrix S21Matrix::Transpose() { S21Matrix tmp(cols_, rows_); for (int i = 0; i < rows_; i++) { for (int j = 0; j < cols_; j++) { tmp(j, i) = (*this)(i, j); } } return tmp; } /** * Вспомогательные функция расчёта минора для ij-элемента матрицы * @param minor_i i-ый номер вычеркиваемой строки * @param minor_j j-ый номер вычеркиваемого столбца * @return минор */ double S21Matrix::GetMinor(int minor_i, int minor_j) { S21Matrix tmp(rows_ - 1, cols_ - 1); for (int i = 0; i < rows_; i++) { if (i == minor_i) { continue; } for (int j = 0; j < cols_; j++) { if (j == minor_j) { continue; } tmp(i < minor_i ? i : i - 1, j < minor_j ? j : j - 1) = (*this)(i, j); } } return tmp.Determinant(); } /** * Вычисляет матрицу алгебраических дополнений текущей матрицы и возвращает ее * @return матрица алгебраических дополнений */ S21Matrix S21Matrix::CalcComplements() { S21Matrix tmp(rows_, cols_); if (rows_ == cols_ && rows_ != 1) { for (int i = 0; i < rows_; i++) { for (int j = 0; j < cols_; j++) { double minor = GetMinor(i, j); tmp(i, j) = ((i + j) % 2 ? -1 : 1) * minor; } } } else { throw std::invalid_argument("The matrix is not square."); } return tmp; } /** * Вычисляет и возвращает определитель текущей матрицы * @return определитель матрицы */ double S21Matrix::Determinant() { double result = 0; if (rows_ == cols_) { if (rows_ == 1) { result = (*this)(0, 0); } else if (rows_ == 2) { result = (*this)(0, 0) * (*this)(1, 1) - (*this)(0, 1) * (*this)(1, 0); } else { S21Matrix complement = CalcComplements(); for (int k = 0; k < rows_; k++) { result += (*this)(0, k) * complement(0, k); } } } else { throw std::invalid_argument("The matrix is not square."); } return result; } /** * Вычисляет и возвращает обратную матрицу * @return обратная матрица */ S21Matrix S21Matrix::InverseMatrix() { if (rows_ == cols_) { double determinant = Determinant(); if (determinant != 0) { if (rows_ == 1) { MulNumber(1 / determinant); } else { S21Matrix b = CalcComplements(); *this = b.Transpose(); MulNumber(1 / determinant); } } else { throw std::invalid_argument("The determinant of the matrix is 0"); } } else { throw std::invalid_argument("The matrix is not square"); } return *this; } /** * Сложение матриц А + B = C * @param other слагаемая матрица * @return суммирующая матрица */ S21Matrix S21Matrix::operator+(const S21Matrix &other) const { S21Matrix result(*this); result.SumMatrix(other); return result; } /** * Вычитание матрицы A - B = C * @param other вычитаемая матрица * @return разностная матрица */ S21Matrix S21Matrix::operator-(const S21Matrix &other) const { S21Matrix result(*this); result.SubMatrix(other); return result; } /** * Умножение матриц А * B = C * @param other множимая матрица * @return матрица произведений */ S21Matrix S21Matrix::operator*(const S21Matrix &other) const { S21Matrix result(*this); result.MulMatrix(other); return result; } /** * Умножение матрицы на число А * num = C * @param num множитель * @return матрица произведений */ S21Matrix S21Matrix::operator*(const double num) const { S21Matrix result(*this); result.MulNumber(num); return result; } /** * Проверяет матрицы на равенство между собой * @param other сравнимая матрица * @return результат сравнения true, false */ bool S21Matrix::operator==(const S21Matrix &other) const { return EqMatrix(other); } /** * Присвоение матрицы (копирование) * @param other исходная матрица * @return копия матрицы */ S21Matrix &S21Matrix::operator=(const S21Matrix &other) noexcept { if (this == &other) { return *this; } delete[] matrix_; Copy(other); return *this; } /** * Присвоение матрицы (переноса) * @param other исходная матрица * @return копия матрицы */ S21Matrix &S21Matrix::operator=(S21Matrix &&other) noexcept { if (this == &other) { return *this; } delete[] matrix_; Move(other); return *this; } /** * Получение i, j - элемента матрицы * @param row номер строки * @param col номер столбца * @return ссылка на i, j - элемент матрицы */ double &S21Matrix::operator()(int row, int col) & { if (row < 0 || col < 0 || row >= rows_ || col >= cols_) { throw std::out_of_range("Incorrect input, index is out of range"); } return this->matrix_[row * cols_ + col]; } /** * Получение i, j - элемента матрицы * @param row номер строки * @param col номер столбца * @return ссылка на i, j - элемент матрицы */ double &S21Matrix::operator()(int row, int col) const & { if (row < 0 || col < 0 || row >= rows_ || col >= cols_) { throw std::out_of_range("Incorrect input, index is out of range"); } return this->matrix_[row * cols_ + col]; } /** * Сложение матриц А = A + B * @param other слагаемая матрица * @return суммирующая матрица */ void S21Matrix::operator+=(const S21Matrix &other) { SumMatrix(other); } /** * Вычитание матрицы A = A - B * @param other вычитаемая матрица * @return разностная матрица */ void S21Matrix::operator-=(const S21Matrix &other) { SubMatrix(other); } /** * Умножение матриц А = A * B * @param other множимая матрица * @return матрица произведений */ void S21Matrix::operator*=(const S21Matrix &other) { MulMatrix(other); } /** * Умножение матрицы на число А = A * num * @param num множитель * @return матрица произведений */ void S21Matrix::operator*=(const double num) { MulNumber(num); } /** * Возвращает количество строк матрицы * @return количество строк */ int S21Matrix::get_rows() { return rows_; } /** * Возвращает количество столбцов матрицы * @return количество столбцов */ int S21Matrix::get_cols() { return cols_; } /** * Устанавливает количество строк матрицы * @param rows количество строк */ void S21Matrix::set_rows(int rows) { rows_ = rows; } /** * Устанавливает количество столбцов матрицы * @param rows количество столбцов */ void S21Matrix::set_cols(int cols) { cols_ = cols; } /** * Возвращает массив элементов матрицы * @return массив элементов матрицы */ double *S21Matrix::get_matrix() { return matrix_; }