Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
- //
- #include <iostream>
- #include <vector>
- #include <stack>
- #include <algorithm>
- #include <string>
- #include <optional>
- #include <map>
- #include <numeric>
- #include <set>
- #include <functional>
- using namespace std;
- class matrix
- {
- vector<vector<double>> m;
- public:
- matrix() {};
- matrix(size_t rows, size_t cols) { m.resize(rows, vector<double>(cols)); }
- matrix(size_t n) { m.resize(n, vector<double>(n)); }
- matrix(const vector<vector<double>>& data) { m = data; }
- matrix(const vector<double>& diag);
- matrix(const matrix& other) { m = other.m; };
- static matrix unit_matrix(size_t n) {
- matrix res(n);
- for (size_t i = 0; i < n; i++)
- res.m[i][i] = 1.0;
- return res;
- }
- const vector<double>& operator[](int row)const { return m[row]; }
- vector<double>& operator[](int row) { return m[row]; }
- size_t rows()const { return m.size(); }
- size_t cols()const { return m.size() ? m[0].size() : 0; }
- matrix& operator=(const matrix& other) { m = other.m; return *this; }
- matrix& operator=(matrix&& other)noexcept { m = other.m; return *this; }
- matrix operator*(const matrix& other) const
- {
- if (cols() != other.rows())
- std::invalid_argument(R"(Incompatible matrices for multiplication)");
- matrix res(rows(), other.cols());
- for (int i = 0; i < rows(); ++i)
- for (int j = 0; j < other.cols(); j++)
- for (int k = 0; k < cols(); ++k)
- res[i][j] += m[i][k] * other[k][j];
- return res;
- }
- std::optional<matrix> inverse() const;
- double det() const;
- size_t size() const { return m.size(); }
- };
- std::optional<matrix> matrix::inverse() const
- {
- if (cols() != rows())
- throw std::string("Row's count and column's count are distinct");
- matrix M{ *this }, E = matrix::unit_matrix(size());
- size_t n = M.size();
- for (int i = 0; i < n; ++i)
- {
- auto it = std::max_element(begin(M.m) + i, end(M.m), [&i](auto& x, auto& y)
- {return abs(x[i]) < abs(y[i]); });
- std::iter_swap(begin(M.m) + i, it);
- std::iter_swap(begin(E.m) + i, begin(E.m) + (it - begin(M.m)));
- double mii = M[i][i];
- if (abs(mii) < 10E-8) //возможно это условие необратимости нужно уточнить
- return std::nullopt;
- std::transform(M[i].begin() + i, M[i].end(), M[i].begin() + i,
- [&mii](auto el) {return el / mii; });
- std::transform(E[i].begin(), E[i].end(), E[i].begin(),
- [&mii](auto el) {return el / mii; });
- for (int j = 0; j < n; ++j)
- {
- if (i == j) continue;
- double mji = M[j][i];
- std::transform(M[i].begin() + i, M[i].end(), M[j].begin() + i,
- M[j].begin() + i, [&mji](auto a, auto b) {return b - mji * a; });
- std::transform(E[i].begin(), E[i].end(), E[j].begin(),
- E[j].begin(), [&mji](auto a, auto b) {return b - mji * a; });
- }
- }
- return E;
- }
- double matrix::det() const
- {
- if (cols() != rows())
- throw std::string("Row's count and column's count are distinct");
- matrix M{ *this };
- double result = 1;
- size_t n = M.size();
- for (int i = 0; i < n; ++i)
- {
- auto it = std::max_element(begin(M.m) + i, end(M.m), [&i](auto& x, auto& y) {
- return abs(x[i]) < abs(y[i]);
- });
- std::iter_swap(begin(M.m) + i, it);
- double mii = M[i][i];
- if (abs(mii) < 10E-8)
- return 0;
- result *= mii * (begin(M.m) + i == it ? 1 : -1);
- std::transform(M[i].begin() + i, M[i].end(), M[i].begin() + i,
- [&mii](auto el) {return el / mii; });
- for (int j = i + 1; j < n; ++j)
- {
- double mji = M[j][i];
- std::transform(M[i].begin() + i, M[i].end(), M[j].begin() + i,
- M[j].begin() + i, [&mji](auto a, auto b) {return b - mji * a; });
- }
- }
- return result;
- }
- int main()
- {
- matrix M({ {1,1,1},{1,2,3},{1,4,9} });
- cout << M.det() << endl;
- std::cout << "\nHello World!\n";
- }
- // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
- // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
- // Советы по началу работы
- // 1. В окне обозревателя решений можно добавлять файлы и управлять ими.
- // 2. В окне Team Explorer можно подключиться к системе управления версиями.
- // 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
- // 4. В окне "Список ошибок" можно просматривать ошибки.
- // 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
- // 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement