Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <Cmath>
  3. #include <complex>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. double getAbs(complex<double> x) {
  9.     return sqrt(x.imag() * x.imag() + x.real() * x.real());
  10. }
  11.  
  12. vector<complex<double>> derriativeCoefficients(vector<complex<double>> coef) {
  13.     vector<complex<double>> temp;
  14.     int N = coef.size() - 1;
  15.     for (int i = 0; i < N; i++) {
  16.         temp.push_back(coef[i] * (double) (N - i));
  17.     }
  18.     return temp;
  19. }
  20.  
  21. vector<complex<double>> coefficients = {complex<double>(25, 0), complex<double>(16, 0), complex<double>(18, 0),
  22.                                         complex<double>(1, 0), complex<double>(13, 0), complex<double>(0, 1)};
  23. vector<complex<double>> coefficients1 = derriativeCoefficients(coefficients);
  24.  
  25. double A(vector<complex<double>> coefficients) {
  26.     double max = getAbs(coefficients[0].real());
  27.     for (int i = 1; i < coefficients.size(); i++) {
  28.         if (getAbs(coefficients[i].real()) > max)
  29.             max = getAbs(coefficients[i].real());
  30.     }
  31.     return max;
  32. }
  33.  
  34. double an(vector<complex<double>> coefficients) {
  35.     return getAbs(coefficients[0]);
  36. }
  37.  
  38. vector<complex<double>> horners_method(complex<double> x, vector<complex<double>> coefficients) {
  39.     vector<complex<double>> newcoefficients;
  40.     newcoefficients.push_back(coefficients.operator[](0));
  41.     for (int i = 1; i < coefficients.size(); i++) {
  42.         newcoefficients.push_back(x * newcoefficients[i - 1] + coefficients[i]);
  43.     }
  44.     return newcoefficients;
  45. }
  46.  
  47. double W(complex<double> z, vector<complex<double>> coefficients) {
  48.     vector<complex<double>> temp = horners_method(z, coefficients);
  49.     return getAbs(temp.operator[](temp.size() - 1));
  50. }
  51.  
  52. complex<double> grad(complex<double> z, vector<complex<double>> coefficients) {
  53.     complex<double> Pz = horners_method(z, coefficients).back();
  54.     complex<double> Pzconj(Pz.real(), -Pz.imag());
  55.     complex<double> Pz1 = horners_method(z, derriativeCoefficients(coefficients)).back();
  56.     complex<double> gr = Pzconj * Pz1;
  57.     gr = complex<double>(gr.real(), -gr.imag());
  58.     return gr;
  59. }
  60.  
  61. float failed_attempts = 0;
  62. int N = 0;
  63.  
  64. complex<double>
  65. coordinate_descent_method(complex<double> z0, double Epsilon, double alpha1, double alpha2,
  66.                           vector<complex<double>> coefficients) {
  67.     complex<double> z;
  68.     double w0, w;
  69.     bool check1 = false;
  70.     bool check2 = false;
  71.     complex<double> delta = complex<double>(Epsilon, Epsilon);
  72.     double deltaW;
  73.     while (getAbs(delta) >= Epsilon || deltaW >= Epsilon) {
  74.         N++;
  75.         if (failed_attempts >= 10) {
  76.             failed_attempts = 0;
  77.             cout << "Root is " << z0 << "  " << "W(z0) =  " << W(z0, coefficients) << '\t' << N << endl;
  78.             return z0;
  79.         }
  80.         complex<double> z1 = z0;
  81.         z = z0 + complex<double>(alpha1, 0);
  82.         w = getAbs(W(z, coefficients));
  83.         w0 = getAbs(W(z0, coefficients));
  84.         if (w <= w0) {
  85.             z0 = z0 + complex<double>(alpha1, 0);
  86.         } else {
  87.             z = z0 - complex<double>(alpha1, 0);
  88.             w = getAbs(W(z, coefficients));
  89.             N++;
  90.             if (w <= w0) {
  91.                 z0 = z0 - complex<double>(alpha1, 0);
  92.             } else { check1 = true; }
  93.         }
  94.         z = z0 + complex<double>(0, alpha2);
  95.         w = getAbs(W(z, coefficients));
  96.         if (w <= w0) {
  97.             z0 = z0 + complex<double>(0, alpha2);
  98.         } else {
  99.             z = z0 - complex<double>(0, alpha2);
  100.             w = getAbs(W(z, coefficients));
  101.  
  102.             if (w <= w0) {
  103.                 z0 = z0 - complex<double>(0, alpha2);
  104.             } else { check2 = true; }
  105.         }
  106.         delta = z1 - z0;
  107.         deltaW = getAbs(W(z1, coefficients) - W(z0, coefficients));
  108.     }
  109.     if (check1) {
  110.         alpha1 /= 12.0;
  111.         failed_attempts++;
  112.         return coordinate_descent_method(z0, Epsilon, alpha1, alpha2, coefficients);
  113.     } else if (check2) {
  114.         alpha2 /= 12.0;
  115.         failed_attempts++;
  116.         return coordinate_descent_method(z0, Epsilon, alpha1, alpha2, coefficients);
  117.     } else {
  118.         cout << "Root is " << z0 << "  " << "W(z0) =  " << W(z0, coefficients) << '\t' << N << endl;
  119.         N = 0;
  120.         return z0;
  121.     }
  122. }
  123.  
  124.  
  125. complex<double> gradient_method_with_crushing_step(complex<double> z, double Epsilon, double delta, double alpha,
  126.                                                    vector<complex<double>> coefficients) {
  127.     cout << "gradient_method_with_crushing_step" << endl;
  128.     complex<double> zi, zi1;
  129.     complex<double> gr = grad(z, coefficients);
  130.     N++;
  131.     double wi, wi1;
  132.     zi1 = z;
  133.     wi = W(zi1, coefficients);
  134.     while (getAbs(gr) > delta) {
  135.         zi = zi1;
  136.         zi1 = zi - alpha * gr;
  137.         wi1 = W(zi1, coefficients);
  138.         gr = grad(zi1, coefficients);
  139.         N++;
  140.         if (wi1 - wi > -alpha * Epsilon * getAbs(gr)) {
  141.             alpha /= 10.0;
  142.         }
  143. //        cout << wi1 << "  " << zi1 << '\t' << gr << endl;
  144.     }
  145.     cout << "Answer: " << wi1 << "  " << zi1 << '\t' << gr << '\t' << N << endl;
  146.     N = 0;
  147.     return zi1;
  148. }
  149.  
  150. complex<double>
  151. gradient_method_with_const_step(complex<double> z, double Epsilon, vector<complex<double>> coefficients) {
  152.     cout << "gradient_method_with_const_step:" << endl;
  153.     complex<double> zi, zi1;
  154.     complex<double> gr = grad(z, coefficients);
  155.     N++;
  156.     double wi1;
  157.     double x = 1.0 + A(coefficients) / an(coefficients);
  158.     int L = (int) round(pow(horners_method(complex<double>(x, 0), coefficients1).back().real(), 2) +
  159.                         horners_method(complex<double>(x, 0), coefficients).back().real() *
  160.                         horners_method(complex<double>(x, 0), derriativeCoefficients(coefficients1)).back().real());
  161.     cout << "L = " << L << endl;
  162.     zi1 = z;
  163.     double alpha = (1 - Epsilon) / (double) L;
  164.     while (getAbs(gr) > Epsilon) {
  165.         zi = zi1;
  166.         zi1 = zi - alpha * gr;
  167.         wi1 = W(zi1, coefficients);
  168.         gr = grad(zi1, coefficients);
  169.         N++;
  170.         //cout << wi1 << "  " << zi1 << '\t' << gr << endl;
  171.     }
  172.     complex<double> minimizer, minimum;
  173.     minimizer = zi1;
  174.     minimum = W(minimizer, coefficients);
  175.     cout << "Answer: minimizer " << minimizer << '\t' << "minimum " << minimum << 't' << N << endl;
  176.     N = 0;
  177.     return zi1;
  178. }
  179.  
  180. complex<double>
  181. gradient_method_with_predictable_step(complex<double> z, double Epsilon, vector<complex<double>> coefficients) {
  182.     cout << "gradient_method_with_predictable_step" << endl;
  183.     complex<double> zi;
  184.     complex<double> gr = grad(z, coefficients);
  185.     N++;
  186.     int k = 10000;
  187.     zi = z;
  188.     while (getAbs(gr) > Epsilon) {
  189.         zi = zi - (1 / (double) (k)) * gr;
  190.         gr = grad(zi, coefficients);
  191.         N++;
  192. //        cout << W(zi, coefficients) << "  " << zi << '\t' << gr << endl;
  193.         k = k + 1;
  194.     }
  195.     complex<double> minimizer, minimum;
  196.     minimizer = zi;
  197.     minimum = W(minimizer, coefficients);
  198.     cout << "Answer: minimizer " << minimizer << '\t' << "minimum " << minimum << '\t' << N << endl;
  199.     N = 0;
  200.     return zi;
  201. }
  202.  
  203. vector<complex<double>> root_search(vector<complex<double>> coefficients) {
  204.     cout << "root_search by coordinate_descent_method" << endl;
  205.     vector<complex<double>> roots;
  206.     int degree = coefficients.size();
  207.     vector<complex<double>> tempcoeff = coefficients;
  208.     complex<double> root;
  209.     for (int i = 1; i < degree; i++) {
  210.         cout << "W(z0)" << "  " << "z0" << endl;
  211.         double alpha = 10e-5;
  212.         double alpha1 = 0.5;
  213.         double alpha2 = 0.5;
  214.         double Epsilon = 10e-4;
  215.         double delta = 10e-3;
  216.         //root = coordinate_descent_method(complex<double>(0.0, 0.0), Epsilon, alpha1, alpha2, tempcoeff);
  217.         //root = coordinate_descent_method(root, Epsilon, alpha1, alpha2, coefficients);
  218.         root = gradient_method_with_crushing_step(complex<double>(0, 0), Epsilon, delta, alpha, tempcoeff);
  219.         root = gradient_method_with_crushing_step(root, Epsilon, delta, alpha, coefficients);
  220. //        root = gradient_method_with_const_step(complex<double>(0, 0), Epsilon, tempcoeff);
  221. //        root = gradient_method_with_const_step(root, Epsilon, coefficients);
  222. //        root = gradient_method_with_predictable_step(complex<double>(0, 0), Epsilon, tempcoeff);
  223. //        root = gradient_method_with_predictable_step(root, Epsilon, coefficients);
  224.         tempcoeff = horners_method(root, tempcoeff);
  225.         tempcoeff.resize(degree - i);
  226.         cout << endl;
  227.         roots.push_back(root);
  228.     }
  229.     for (int i = 0; i < roots.size(); i++) {
  230.         cout << "Root is " << roots[i] << "  " << "W(root) =  " << W(roots[i], coefficients) << endl;
  231.     }
  232.     return roots;
  233. }
  234.  
  235. int main() {
  236.  
  237.     double delta = 10e-10;
  238.     double alpha = 10e-5;
  239.     double alpha1 = 5;
  240.     double alpha2 = 5;
  241.     double Epsilon = 10e-5;
  242. //    coordinate_descent_method(complex<double>(0, 0), Epsilon, alpha1, alpha2, coefficients);
  243.     vector<complex<double>> roots = root_search(coefficients);
  244. //    gradient_method_with_crushing_step(complex<double>(0, 0), Epsilon, delta, alpha, coefficients);
  245.     //gradient_method_with_const_step(complex<double>(0, 0), Epsilon, coefficients);
  246. //    gradient_method_with_predictable_step(complex<double>(0, 0), Epsilon, coefficients);
  247.     return 0;
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement