Advertisement
Argent007

АОВС Вычисление корней многочлена

Mar 15th, 2023 (edited)
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.03 KB | None | 0 0
  1. // ConsoleApplication3.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //https://pastebin.com/W4B9bPhg
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <complex>
  7. #include <algorithm>
  8. #include <random>
  9. #include <numeric>
  10. #include <iomanip>
  11.  
  12. using cdouble = std::complex<long double>;
  13. using std::vector;
  14.  
  15. class matrix
  16. {
  17.     vector<vector<cdouble>> m;
  18. public:
  19.     matrix(size_t n) { m.assign(n, vector<cdouble>(n)); }
  20.     size_t size() const { return m.size(); }
  21.     vector<cdouble>& operator[](size_t row) { return m[row]; }
  22.     const vector<cdouble>& operator[](size_t row)const { return m[row]; }
  23.     matrix operator*(const matrix& other)const
  24.     {
  25.         auto n = size();
  26.         matrix res(n);
  27.         for (size_t i = 0; i < n; i++)
  28.             for (size_t j = 0; j < n; j++)
  29.                 for (size_t k = 0; k < n; k++)
  30.                     res[i][j] += m[i][k] * other[k][j];
  31.         return res;
  32.     }
  33.     matrix operator^(size_t n)const
  34.     {
  35.         matrix res(size()), p = *this;
  36.         for (size_t i = 0; i < size(); i++)
  37.             res[i][i] = 1;
  38.         while (n > 0)
  39.         {
  40.             if (n & 1) res = res * p;
  41.             n /= 2;
  42.             if (n > 0) p = p * p;
  43.         }
  44.         return res;
  45.     }
  46. };
  47.  
  48. class polynom
  49. {
  50.     vector<cdouble> c;
  51. public:
  52.     polynom(int deg = 0) { c.assign(deg + 1, 0); }
  53.     polynom(const vector<cdouble>& coefs) { c = coefs; }
  54.     polynom operator+(const polynom& arg)const;
  55.     polynom operator-(const polynom& arg)const;
  56.     polynom operator*(const polynom& arg)const;
  57.     cdouble operator[](size_t n)const;
  58.     cdouble& operator[](size_t n);
  59.     cdouble operator()(cdouble arg)const; //вычисление значения многочлена в т. arg
  60.     cdouble derivate(cdouble arg) const; //вычисление производной многочлена в т.arg
  61.     cdouble get_root()const;
  62.     vector<cdouble> roots()const;
  63.     polynom shift(cdouble x_0)const; // P(x) --> P(x+x_0)
  64.     polynom divide(cdouble r)const; // P(x) --> P(x)/(x-r)
  65.     size_t degree()const { return c.size() - 1; }
  66. };
  67.  
  68.  
  69.  
  70. int main()
  71. {
  72.     polynom P({ -6,2,-6,3,-3,1 });
  73.     polynom Q({ -6,2,-9,3,-3,1 }); //(x^2+1)(x^2+2)(x-3)
  74.     polynom R({ 7,6,5,4,3,2,1 });
  75.     std::cout << std::setprecision(20);
  76.     std::cout << P.get_root() << std::endl;
  77.     std::cout << Q.get_root() << std::endl;
  78.     std::cout << R.get_root() << std::endl;
  79.     std::cout << sizeof(long double) << std::endl;//"Hello World!\n";
  80. }
  81.  
  82. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  83. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  84.  
  85. // Советы по началу работы
  86. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  87. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  88. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  89. //   4. В окне "Список ошибок" можно просматривать ошибки.
  90. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  91. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  92.  
  93. polynom polynom::operator+(const polynom& arg) const
  94. {
  95.     auto deg = std::max(degree(), arg.degree());
  96.     polynom res(deg);
  97.     for (size_t i = 0; i <= deg; i++)
  98.     {
  99.         res[i] = (*this)[i] + arg[i];
  100.     }
  101.     return res;
  102. }
  103.  
  104. polynom polynom::operator-(const polynom& arg) const
  105. {
  106.     auto deg = std::max(degree(), arg.degree());
  107.     polynom res(deg);
  108.     for (size_t i = 0; i <= deg; i++)
  109.     {
  110.         res[i] = (*this)[i] - arg[i];
  111.     }
  112.     return res;
  113. }
  114.  
  115. polynom polynom::operator*(const polynom& arg) const
  116. {
  117.     polynom res(degree() + arg.degree());
  118.     for (size_t i = 0; i <= degree(); i++)
  119.     {
  120.         for (size_t j = 0; j <= arg.degree(); j++)
  121.         {
  122.             res[i + j] += (*this)[i] * arg[j];
  123.         }
  124.     }
  125.     return res;
  126. }
  127.  
  128. cdouble polynom::operator[](size_t n) const
  129. {
  130.     if (n > degree()) return 0;
  131.     return c[n];
  132. }
  133.  
  134. cdouble& polynom::operator[](size_t n)
  135. {
  136.     return c[n];
  137. }
  138.  
  139. cdouble polynom::operator()(cdouble arg) const
  140. {
  141.     int n = degree();
  142.     auto res = c[n];
  143.     for (int i = n - 1; i >= 0; i--)
  144.         res = res * arg + c[i];
  145.     return res;
  146. }
  147.  
  148. cdouble polynom::derivate(cdouble arg) const
  149. {
  150.     int n = degree();
  151.     cdouble res = c[n]*cdouble(n);
  152.     for (int i = n - 1; i > 0; i--)
  153.         res = res * arg + c[i]*cdouble(i);
  154.     return res;
  155. }
  156.  
  157. cdouble polynom::get_root() const
  158. {
  159.     size_t n = degree();
  160.     std::random_device rd;
  161.     std::mt19937_64 mtrand(rd());
  162.     std::uniform_real_distribution<> dist(0.1, 0.5);
  163.     cdouble a{ dist(mtrand),dist(mtrand) };
  164.     auto P = shift(a);
  165.     matrix A(n);
  166.     for (size_t i = 0; i < n; i++)
  167.     {
  168.         A[0][n - i - 1] = -P[i] / P[n];
  169.         if (i + 1 < n) A[i + 1][i] = 1;
  170.     }
  171.     for (size_t k = 0; k < 10; k++)
  172.     {
  173.         A = A * A;
  174.         cdouble maxA = 0;
  175.         for (size_t i = 0; i < n; i++)
  176.             for (size_t j = 0; j < n; j++)
  177.                 if (abs(A[i][j]) > abs(maxA))
  178.                     maxA = A[i][j];
  179.         for (size_t i = 0; i < n; i++)
  180.             for (size_t j = 0; j < n; j++)
  181.                 A[i][j] /= maxA;
  182.     }
  183.     std::uniform_real_distribution<> dst(0.5, 1);
  184.     std::vector<cdouble> init_vec(n);
  185.     for (size_t i = 0; i < n; i++)
  186.         init_vec[i] = dst(mtrand);
  187.     cdouble num, denom;
  188.     num = std::inner_product(begin(A[0]), end(A[0]), begin(init_vec), cdouble(0.0));
  189.     denom = std::inner_product(begin(A[1]), end(A[1]), begin(init_vec), cdouble(0.0));
  190.     cdouble r= num / denom + a;
  191.     for (int i = 0; i < 5; ++i)
  192.         r = r - (*this)(r) / derivate(r);
  193.     return r;
  194. }
  195.  
  196. vector<cdouble> polynom::roots() const
  197. {
  198.     return vector<cdouble>();
  199. }
  200.  
  201. polynom polynom::shift(cdouble x_0) const
  202. {
  203.     polynom res(0), m({ x_0,1 });
  204.     res[0] = c[degree()];
  205.     for (int i = (int)degree() - 1; i >= 0; i--)
  206.     {
  207.         res = res * m;
  208.         res[0] += c[i];
  209.     }
  210.     return res;
  211. }
  212.  
  213. polynom polynom::divide(cdouble r) const
  214. {
  215.     polynom res(degree() - 1);
  216.     res.c.back() = c.back();
  217.     for (int i = (int)degree() - 2; i >= 0; --i)
  218.         res[i] = res[i + 1] * r + c[i];
  219.     return res;
  220. }
  221.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement