Advertisement
Argent007

Matrix 2024

Dec 21st, 2024
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.70 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <stack>
  7. #include <algorithm>
  8. #include <string>
  9. #include <optional>
  10. #include <map>
  11. #include <numeric>
  12. #include <set>
  13. #include <functional>
  14.  
  15. using namespace std;
  16.  
  17. class matrix
  18. {
  19.     vector<vector<double>> m;
  20. public:
  21.     matrix() {};
  22.     matrix(size_t rows, size_t cols) { m.resize(rows, vector<double>(cols)); }
  23.     matrix(size_t n) { m.resize(n, vector<double>(n)); }
  24.     matrix(const vector<vector<double>>& data) { m = data; }
  25.     matrix(const vector<double>& diag);
  26.     matrix(const matrix& other) { m = other.m; };
  27.     static matrix unit_matrix(size_t n) {
  28.         matrix res(n);
  29.         for (size_t i = 0; i < n; i++)
  30.             res.m[i][i] = 1.0;
  31.         return res;
  32.     }
  33.     const vector<double>& operator[](int row)const { return m[row]; }
  34.     vector<double>& operator[](int row) { return m[row]; }
  35.     size_t rows()const { return m.size(); }
  36.     size_t cols()const { return m.size() ? m[0].size() : 0; }
  37.     matrix& operator=(const matrix& other) { m = other.m; return *this; }
  38.     matrix& operator=(matrix&& other)noexcept { m = other.m; return *this; }
  39.     matrix operator*(const matrix& other) const
  40.     {
  41.         if (cols() != other.rows())
  42.             std::invalid_argument(R"(Incompatible matrices for multiplication)");
  43.         matrix res(rows(), other.cols());
  44.         for (int i = 0; i < rows(); ++i)
  45.             for (int j = 0; j < other.cols(); j++)
  46.                 for (int k = 0; k < cols(); ++k)
  47.                     res[i][j] += m[i][k] * other[k][j];
  48.         return res;
  49.     }
  50.     std::optional<matrix> inverse() const;
  51.     double det() const;
  52.     size_t size() const { return m.size(); }
  53. };
  54.  
  55. std::optional<matrix> matrix::inverse() const
  56. {
  57.     if (cols() != rows())
  58.         throw std::string("Row's count and column's count are distinct");
  59.     matrix M{ *this }, E = matrix::unit_matrix(size());
  60.     size_t n = M.size();
  61.     for (int i = 0; i < n; ++i)
  62.     {
  63.         auto it = std::max_element(begin(M.m) + i, end(M.m), [&i](auto& x, auto& y)
  64.             {return abs(x[i]) < abs(y[i]); });
  65.         std::iter_swap(begin(M.m) + i, it);
  66.         std::iter_swap(begin(E.m) + i, begin(E.m) + (it - begin(M.m)));
  67.         double mii = M[i][i];
  68.         if (abs(mii) < 10E-8) //возможно это условие необратимости нужно уточнить
  69.             return std::nullopt;
  70.         std::transform(M[i].begin() + i, M[i].end(), M[i].begin() + i,
  71.             [&mii](auto el) {return el / mii; });
  72.         std::transform(E[i].begin(), E[i].end(), E[i].begin(),
  73.             [&mii](auto el) {return el / mii; });
  74.  
  75.         for (int j = 0; j < n; ++j)
  76.         {
  77.             if (i == j) continue;
  78.             double mji = M[j][i];
  79.             std::transform(M[i].begin() + i, M[i].end(), M[j].begin() + i,
  80.                 M[j].begin() + i, [&mji](auto a, auto b) {return b - mji * a; });
  81.             std::transform(E[i].begin(), E[i].end(), E[j].begin(),
  82.                 E[j].begin(), [&mji](auto a, auto b) {return b - mji * a; });
  83.         }
  84.     }
  85.     return E;
  86. }
  87.  
  88. double matrix::det() const
  89. {
  90.     if (cols() != rows())
  91.         throw std::string("Row's count and column's count are distinct");
  92.     matrix M{ *this };
  93.     double result = 1;
  94.     size_t n = M.size();
  95.     for (int i = 0; i < n; ++i)
  96.     {
  97.         auto it = std::max_element(begin(M.m) + i, end(M.m), [&i](auto& x, auto& y) {
  98.             return abs(x[i]) < abs(y[i]);
  99.             });
  100.         std::iter_swap(begin(M.m) + i, it);
  101.         double mii = M[i][i];
  102.         if (abs(mii) < 10E-8)
  103.             return 0;
  104.         result *= mii * (begin(M.m) + i == it ? 1 : -1);
  105.         std::transform(M[i].begin() + i, M[i].end(), M[i].begin() + i,
  106.             [&mii](auto el) {return el / mii; });
  107.         for (int j = i + 1; j < n; ++j)
  108.         {
  109.             double mji = M[j][i];
  110.             std::transform(M[i].begin() + i, M[i].end(), M[j].begin() + i,
  111.                 M[j].begin() + i, [&mji](auto a, auto b) {return b - mji * a; });
  112.         }
  113.     }
  114.     return result;
  115. }
  116.  
  117. int main()
  118. {
  119.     matrix M({ {1,1,1},{1,2,3},{1,4,9} });
  120.     cout << M.det() << endl;
  121.     std::cout << "\nHello World!\n";
  122. }
  123.  
  124. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  125. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  126.  
  127. // Советы по началу работы
  128. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  129. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  130. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  131. //   4. В окне "Список ошибок" можно просматривать ошибки.
  132. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  133. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  134.  
  135.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement