Guest User

Untitled

a guest
Jan 24th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4.  
  5. void swap_vec(float* x, float* y, unsigned n) {
  6.     unsigned i; float tmp;
  7.     for (i=0; i<n; ++i) { tmp=x[i]; x[i]=y[i]; y[i]=tmp; }
  8. }
  9.  
  10. void swap(float* x, float* y) {
  11.     float tmp; tmp=*x; *x=*y; *y=tmp;
  12. }
  13.  
  14. unsigned max_col(float* A, unsigned col, unsigned n) {
  15.     unsigned i, maxi; float max; max = A[n*col+col]; maxi = col;
  16.     for (i = col+1; i < n; ++i) {
  17.         if(fabsf(A[i*n+col]) > fabsf(max)) { max = A[i*n+col]; maxi=i; }
  18.     }
  19.     return maxi;
  20. }
  21.  
  22. int solve_gauss(float* A, float* x, float* b, unsigned n) {
  23.     /*
  24.      * Gaussian elimination based equation system solver
  25.      * solves equation Ax = b for x, where A is a
  26.      * square nxn matrix, x and b are n-dimensional vectors
  27.      * Puts solution in x (if possible), modifies A, x, b
  28.      * output: 0 - ok, 1 - A is singular (unsolvable system or
  29.      * has more than 1 solutions)
  30.      */
  31.     unsigned i, j, k, l;
  32.     float scaler;
  33.     // stage I
  34.     for (j = 0; j < n; ++j) {
  35.         // select new pivot and swap
  36.         l = max_col(A, j, n);
  37.         swap_vec(&A[j*n], &A[l*n], n);
  38.         swap(&b[j], &b[l]);
  39.         if (fabsf(A[j*n+j])<1e-15) return 1;
  40.         // ^ zero on diagonal -> singularity -> unsolvable
  41.         // eliminate A(j,j) from rows below
  42.         for (i = (j+1); i < n; ++i) {
  43.             scaler = A[i*n+j]/A[j*n+j];
  44.             b[i] -= b[j]*scaler;
  45.             for (k = 0; k < n; ++k) {
  46.                 A[i*n+k] -= A[j*n+k]*scaler;
  47.             }
  48.         }
  49.     }
  50.     // stage II
  51.     for (i = n; i > 0; --i) {
  52.         --i; x[i] = b[i];
  53.         for(j = n-1; j > i; --j ) x[i] -= x[j]*A[i*n+j];
  54.         x[i] /= A[i*n+i]; ++i;
  55.     }
  56.     return 0;
  57. }
  58. void print_vec(float* v, unsigned n) {
  59.     int i;
  60.     printf("[ ");
  61.     for (i = 0; i < n; ++i) printf("%5.3f ", v[i]);
  62.     printf("]");
  63. }
  64.  
  65. void print_mat(float* A, unsigned n) {
  66.     int i;
  67.     for (i = 0; i < n; ++i) {
  68.         print_vec(&A[i*n], n);
  69.         printf("\n");
  70.     }
  71. }
  72.  
  73. #define NUM 3
  74.  
  75. int main(void)
  76. {
  77.     int sing;
  78.     float A[NUM][NUM] = {{-6, 5, 4}, {-3, 7, 2}, {-2, 0, 2}};
  79.     float b[NUM] = { 1, 2, 3 };
  80.     float x[NUM];
  81.     printf("A =\n");
  82.     print_mat((float*) A, NUM);
  83.     printf("b =\n");
  84.     print_vec(b, NUM);
  85.     printf("\nEliminating...\n");
  86.     sing  = solve_gauss((float*) A, x, b, NUM);
  87.     printf("A =\n");
  88.     print_mat((float*) A, NUM);
  89.     printf("b =\n");
  90.     print_vec(b, NUM);
  91.     if (sing) printf("\nMatrix A is singular!\n");
  92.     else {
  93.     printf("\nx =\n");
  94.     print_vec(x, NUM);
  95.     printf("\n");
  96.     }
  97.     return 0;  
  98. }
Add Comment
Please, Sign In to add comment