frustration

DPF

Nov 7th, 2019
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.05 KB | None | 0 0
  1. /*  Function Rosenbrock
  2. F(x,y)=(1-x)^2+100(y-x^2)^2
  3. partial derivative x : f = -2+2*x-400*y*x+400*x^3
  4. partial derivative y : f = 200*(y-x^2)
  5. */
  6.  
  7. #include <conio.h>
  8. #include <math.h>
  9. #include <iostream>
  10.  
  11. using namespace std;
  12.  
  13. double function_Rosenbroke(double * vector) {
  14.     return pow((1 - vector[0]), 2) + 100 * pow((vector[1] - pow(vector[0], 2)), 2);
  15. }
  16. //zeroing matrix
  17.  
  18. double ** zeroing(double **A,int N) {
  19.     for (int i = 0; i < N; i++) {
  20.         for (int j = 0; j < N; j++)  
  21.             A[i][j] = 0;
  22.     }
  23.     return A;
  24. }
  25. //multiply matrixes
  26.  
  27. double** product(double **A, double **U,int N) {
  28.  
  29.     double **c = new double*[N];
  30.     for (int i = 0; i < N; i++)
  31.         c[i] = new double[N];
  32.  
  33.     for (int i = 0; i < N; i++) {
  34.         for (int j = 0; j < N; j++) {
  35.             c[i][j] = 0;
  36.             for (int t = 0; t < N; t++)
  37.                 c[i][j] += A[i][t] * U[t][j];
  38.         }
  39.     }
  40.     return c;
  41. }
  42. // multiply matrix on vector
  43.  
  44. double* product_vector(double **A, double *b, int N) {
  45.  
  46.     double *a = new double[N];
  47.  
  48.     for (int i = 0; i < N; i++) {
  49.         a[i] = 0;
  50.         for (int j = 0; j < N; j++)
  51.             a[i] += A[i][j] * b[j];
  52.     }
  53.     return a;
  54. }
  55. // find gradients
  56. double grad1(double* vector, int N) {
  57.     return -2 + 2 * vector[0] - 400 * vector[1] * vector[0] + 400 * pow(vector[0], 3);  //partial derivative x
  58. }
  59. double grad2(double* vector, int N) {
  60.     return 200 * (vector[1] - pow(vector[0], 2)); //partial derivative y
  61. }
  62.  
  63. //find direction
  64.  
  65. double * func_direction(double **A, double *b, int N) {
  66.  
  67.     double *direction = new double[N];
  68.     for (int i = 0; i < N; i++)
  69.         direction[i] = 0;
  70.  
  71.     direction = product_vector(A, b,  N);
  72.  
  73.     for (int i = 0; i < N; i++)                      
  74.         direction[i] = -direction[i];
  75.     return direction;
  76. }
  77.  
  78. double **make_matrix(double * a, double * b, int N) {
  79.     double **matrix = new double*[N];
  80.     for (int i = 0; i < N; i++)
  81.         matrix[i] = new double[N];
  82.     zeroing(matrix,N);
  83.  
  84.     for (int i = 0; i < N; i++) {
  85.         for (int j = 0; j < N; j++)
  86.             matrix[i][j] = a[i] * b[j];
  87.     }
  88.     return matrix;
  89. }
  90.  
  91. double make_number(double * a, double *b, int N) {
  92.     double number = 0;
  93.     for (int i = 0; i < N; i++)
  94.         number += a[i] * b[i];
  95.     return number;
  96. }
  97. //division matrix by number
  98. double ** division_matrix_by_number(double ** matrix, double number, int N) {
  99.  
  100.     double **matrix1 = new double*[N];
  101.     for (int i = 0; i < N; i++)
  102.         matrix1[i] = new double[N];
  103.     zeroing(matrix1,N);
  104.  
  105.     for (int i = 0; i < N; i++) {
  106.         for (int j = 0; j < N; j++)
  107.             matrix1[i][j] = matrix[i][j] / number;
  108.     }
  109.     return matrix1;
  110. }
  111.  //find reverse Hesse's  matrix
  112. double ** formula(double ** matrix, double *alpha, double *beta, int N) {
  113.     double number1 = 0, number2 = 0;
  114.  
  115.     double **matrix1 = new double*[N];
  116.     for (int i = 0; i <N; i++)
  117.         matrix1[i] = new double[N];
  118.     zeroing(matrix1,N);
  119.  
  120.     double **matrix2 = new double*[N];
  121.     for (int i = 0; i < N; i++)
  122.         matrix2[i] = new double[N];
  123.     zeroing(matrix2,N);
  124.  
  125.     double **B = new double*[N];
  126.     for (int i = 0; i < N; i++)
  127.         B[i] = new double[N];
  128.     zeroing(B,N);
  129.  
  130.     double **C = new double*[N];
  131.     for (int i = 0; i < N; i++)
  132.         C[i] = new double[N];
  133.     zeroing(C,N);
  134.  
  135.     double *a = new double[N];
  136.     for (int i = 0; i < N; i++)
  137.         a[i] = 0;
  138.  
  139.     double *b = new double[N];
  140.     for (int i = 0; i < N; i++)
  141.         b[i] = 0;
  142.  
  143.     matrix1 = make_matrix(alpha, alpha,N);                            
  144.     number1 = make_number(alpha, beta,N);
  145.     B = division_matrix_by_number(matrix1, number1,N);
  146.     a = product_vector(matrix, beta,N);
  147.     matrix2 = make_matrix(a, beta,N);
  148.     matrix2 = product(matrix2, matrix,N);
  149.     b = product_vector(matrix, beta,N);
  150.     number2 = make_number(b, beta,N);
  151.     C = division_matrix_by_number(matrix2, number2,N);
  152.  
  153.     for (int i = 0; i < N; i++) {
  154.         for (int j = 0; j < N; j++)
  155.             matrix[i][j] = matrix[i][j] + B[i][j] - C[i][j];          
  156.     }
  157.  
  158.     return matrix;
  159. }
  160.  
  161. double length_of_grad(double *gradient) {
  162.     return sqrt(pow(gradient[0], 2) + pow(gradient[1], 2));
  163. }
  164.  
  165. int main() {
  166.     int N = 2;
  167.     double k = 0, k_max, eps = 0.00016, t, number1, number2;
  168.     cout << "enter max approximation: ";
  169.     cin >> k_max;
  170.     cout << "enter point of min 0<t<1: ";
  171.     cin >> t;
  172.  
  173.     double **A = new double*[N]; //identity matrix
  174.     for (int i = 0; i < N; i++)
  175.         A[i] = new double[N];
  176.  
  177.     double *direction = new double[N];
  178.     for (int i = 0; i < N; i++)
  179.         direction[i] = 0;
  180.  
  181.     for (int i = 0; i < N; i++) { // enter identity matrix
  182.         for (int j = 0; j < N; j++) {
  183.             if (i == j)
  184.                 A[i][j] = 1;
  185.             else
  186.                 A[i][j] = 0;
  187.         }
  188.     }
  189.    
  190.     double *vector = new double[N];
  191.     for (int i = 0; i < N; i++)
  192.         vector[i] = 0;
  193.     cout << "enter points x and y: ";
  194.     cin >> vector[0] >> vector[1];
  195.    
  196.     double *gradient = new double[N];
  197.     for (int i = 0; i < N; i++)
  198.         gradient[i] = 0;
  199.    
  200.     double *alpha = new double[N];
  201.     for (int i = 0; i < N; i++)
  202.         alpha[i] = 0;
  203.    
  204.     double *beta = new double[N];
  205.     for (int i = 0; i < N; i++)
  206.         beta[i] = 0;
  207.  
  208.     gradient[0] = grad1(vector,N);    // function's gradient evaluation at a point X
  209.     gradient[1] = grad2(vector,N);    // function's gradient evaluation at a point Y
  210.  
  211.     do {
  212.         number1 = 0, number2 = 0;
  213.  
  214.         direction = func_direction(A, gradient,N);            //to find direction
  215.  
  216.         for (int i = 0; i < N; i++)                        // old points
  217.             alpha[i] = vector[i];
  218.  
  219.         for (int i = 0; i < N; i++)                        // new points
  220.             vector[i] = vector[i] + t * direction[i];
  221.  
  222.         for (int i = 0; i < N; i++)                        // new points - old points
  223.             alpha[i] = vector[i] - alpha[i];
  224.  
  225.         for (int i = 0; i < N; i++)                       //old values of grad
  226.             beta[i] = gradient[i];
  227.  
  228.         gradient[0] = grad1(vector,N);                      // new values of grads
  229.         gradient[1] = grad2(vector,N);
  230.  
  231.         for (int i = 0; i < N; i++)                         //new grad - old grad
  232.             beta[i] = gradient[i] - beta[i];
  233.  
  234.         A = formula(A, alpha, beta,N);                          //Ak=Ak-1 + B - C;
  235.  
  236.         k++;
  237.  
  238.         cout << endl << "grad " << length_of_grad(gradient) << " " << k << endl;
  239.  
  240.     } while ((length_of_grad(gradient) > eps) && (k < k_max));
  241.  
  242.     cout << vector[0] << " " << vector[1] << endl;
  243.     cout << function_Rosenbroke(vector);
  244.  
  245.     _getch();
  246.     return 0;
  247. }
Add Comment
Please, Sign In to add comment