Gistrec

Метод Ньютона решение СНУ

Dec 26th, 2018
349
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.66 KB | None | 0 0
  1. int n = 2; // Кол-во переменных и функций
  2.  
  3. double epsilon1, epsilon2;
  4.  
  5. /**
  6.  * Норма вектора
  7.  */
  8. double norm(std::vector<double> a) {
  9.     double sum = 0;
  10.     for (auto i : a)
  11.         sum += i * i;
  12.     return sqrt(sum);
  13. }
  14.  
  15. /**
  16.  * Проверка условий, при которых нужно выходить
  17.  * 1. По шагу (т.е. если шаг стал меньше eps1)
  18.  * 2. По норме
  19.  */
  20. int exit_condition(std::vector<double> F, double beta) {
  21.     if (beta < epsilon1)
  22.         return 0;
  23.     if (norm(F) < epsilon2)
  24.         return 0;
  25.     return 1;
  26. }
  27.  
  28. /**
  29.  * Заданные функции (их кол-во должно быть равно n)
  30.  * X[0] - X[1]        <=>   Функция y = x
  31.  * X[0] + X[1] - 2    <=>   y = -x + 2
  32.  * X[0] - 1           <=>   y = 1
  33.  * Если все функции не пересекаются в одной точке, то одна из функций всегда будет возвращать большое значение в невязке
  34.  * и т.к. эпсилон очень маленький, то решение никогда не сойдется
  35.  * Поэтому нужно брать функции, которые пересекаются в одной точке
  36.  */
  37. double function(std::vector<double> X, int i) {
  38.     if (i == 0) return (X[0] - X[1] * X[1]);
  39.     //if (i == 0) return (X[0] - X[1]);
  40.     if (i == 1) return (X[0] + X[1] - 2);
  41.     if (i == 2) return (X[0] - 1);
  42. }
  43.  
  44. /**
  45.  * Решаем слау вида  A * DeltaX = F
  46.  * X нужен для вычисления A (матрица Якоби)
  47.  *
  48.  * Составляем матрицу якоби (матрица производных)
  49.  */
  50. void Matrix_Yacoby(std::vector<std::vector<double>> &A, std::vector<double> X, std::vector<double> F, std::vector<double> &DeltaX) {
  51.     double delta = 0.000001;
  52.    
  53.     // Формула производной f'(x) = ( f(x + Δx) - f(x) ) / Δx
  54.     for (int i = 0; i < n; i++) {
  55.         for (int j = 0; j < n; j++) {
  56.             X[j] += delta;
  57.             A[i][j] = function(X, i);
  58.             X[j] -= delta;
  59.             A[i][j] -= function(X, i);
  60.             A[i][j] /= delta;
  61.         }
  62.     }
  63.     slove(A, DeltaX, F, n);
  64. }
  65.  
  66. void input(int &max) {
  67.     std::ifstream A("Text.txt");
  68.     A >> max;
  69.     A >> epsilon1;
  70.     A >> epsilon2;
  71.     A.close();
  72. }
  73.  
  74. int main() {
  75.     std::vector<std::vector<double>> A(n, std::vector<double>(n, 0));
  76.     std::vector<double> oldF(n), F(n), X(n, 50.0), DeltaX(n, 0.0);
  77.  
  78.     int amount_iter = 0;
  79.     int max_amount_iter;
  80.     double beta = 1.0;
  81.     input(max_amount_iter);
  82.     for (int i = 0; i < n; i++)
  83.         F[i] = function(X, i);
  84.  
  85.     while (exit_condition(F, beta) && (amount_iter < max_amount_iter)) {
  86.         beta = 1.0;// начальное значение бета всегда 1
  87.         Matrix_Yacoby(A, X, F, DeltaX); // Считаем вектор DeltaX, т.е. вектор, куда нам нужно идти
  88.         oldF.swap(F);
  89.        
  90.         for (int i = 0; i < n; i++)
  91.             X[i] -= beta * DeltaX[i];// вычисляем новое приближение Х
  92.  
  93.         for (int i = 0; i < n; i++)
  94.             F[i] = function(X, i);
  95.         //int k = 0;
  96.         while ((norm(oldF) < norm(F))) {// если норма функции от нового Х больше, чем от старого
  97.             beta /= 2.0;// то уменьшаем бету в 2 раза, вычисляем Х и функцию от него заново
  98.             for (int i = 0; i < n; i++)
  99.                 X[i] += beta * DeltaX[i];
  100.             for (int i = 0; i < n; i++)
  101.                 F[i] = function(X, i);
  102.         }
  103.         for (auto i : X)
  104.             std::cout << i << " ";
  105.         std::cout << std::endl;
  106.  
  107.         amount_iter++;
  108.     }
  109.    
  110.     std::cout << "Amount iteration " << amount_iter << std::endl;
  111.     std::cout << "beta " << beta << std::endl;
  112.     system("pause");
  113.     return 0;
  114. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment