Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.27 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