Advertisement
Ladies_Man

Matrix - СЛАУ - Linear System

Apr 5th, 2014
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 6.26 KB | None | 0 0
  1. package main
  2. import "fmt"
  3. import "os"
  4.  
  5. type frc struct {
  6.         numer int
  7.         denom int
  8.         //           numerator
  9.         //fraction=  ----------
  10.         //           denominator
  11. }
  12.  
  13. //print matrix
  14. func output_matrix(matrix [][]frc, n int) {
  15.         for i := 0; i < n; i++ {
  16.                 for j := 0; j < n+1; j++ {
  17.                         fmt.Printf("%d ", matrix[i][j].numer)
  18.                 }
  19.                 fmt.Printf("\n")
  20.         }
  21.         fmt.Printf("\n")
  22.         return
  23. }
  24.  
  25. //scan matrix
  26. func get_matrix(matrix [][]frc, n int) {
  27.         fmt.Printf("Insert elements:\n")
  28.         for i := 0; i < n; i++ {    //i-th row (row), j-th symbol in a row (column)
  29.                 for j := 0; j < n+1; j++ {
  30.                         fmt.Scanf("%d", &(matrix[i][j].numer))
  31.                         matrix[i][j].denom = 1
  32.                 }
  33.                 fmt.Scanf("\n")
  34.         }
  35.         return
  36. }
  37.  
  38. //swap 2 rows
  39. func swap_rows(matrix [][]frc, str_1, str_2, n int) {
  40.         for j := 0; j < n+1; j++ {
  41.                 matrix[str_1][j].numer, matrix[str_2][j].numer = matrix[str_2][j].numer, matrix[str_1][j].numer
  42.                 matrix[str_1][j].denom, matrix[str_2][j].denom = matrix[str_2][j].denom, matrix[str_1][j].denom
  43.         }
  44.         return
  45. }
  46. //================================================================================
  47. func gcd(x, y int) int {
  48.         for y != 0 { x, y = y, x%y }
  49.         return x
  50. }
  51.  
  52. func lcm(m, n int) int { return m / gcd(m, n) * n }
  53.  
  54. func fraction_reduce(x frc) frc { //   14/88 -> 7/44
  55.         for 1 != gcd(x.numer, x.denom) {
  56.                 i := gcd(x.numer, x.denom)
  57.                 x.numer /= i
  58.                 x.denom /= i
  59.         }
  60.         return x
  61. }
  62. //=================================================================================
  63.  
  64. //check for negative diag elements (if exist -> mulitiply them by '-1')
  65. func neg_diag_elements(matrix [][]frc, n, j int) {
  66.         for i := j; i < n; i++ {
  67.                 if matrix[i][i].numer < 0 { for k := 0; k < n+1; k++ { matrix[i][k].numer *= -1 } } //multiplied by '-1'
  68.         }
  69. }
  70.  
  71. //check if null diag elements exist
  72. func check_null_diag(matrix [][]frc, n, i int) [][]frc {
  73.         for i < n {
  74.                 if 0 == matrix[i][i].numer {
  75.                         for t := i + 1; t < n; t++ {
  76.                                 if 0 != matrix[t][i].numer {
  77.                                         swap_rows(matrix, i, t, n)
  78.                                         break
  79.                                 }
  80.                         }
  81.                 }
  82.                 i++
  83.         }
  84.         return matrix
  85. }
  86.  
  87. func direct_gauss_method(matrix [][]frc, n int) {
  88.         for j := 0; j < n; j++ {
  89.                 check_null_diag(matrix, n, j)
  90.                 //fmt.Printf("_check_null_diag_direct\n")
  91.                 output_matrix(matrix, n)
  92.                 for i := j + 1; i < n; i++ {
  93.                        
  94.                         neg_diag_elements(matrix, n, j)
  95.  
  96.                         a, b := matrix[j][j].numer, matrix[i][j].numer
  97.                         //fmt.Printf("a=%d, b=%d, ", a, b)
  98.                         if 0 == b { continue }
  99.                         if 0 == a {
  100.                                 fmt.Printf("No solution :(\n")
  101.                                 os.Exit(0)
  102.                         }
  103.  
  104.                         g := lcm(a, b)
  105.                         k_a, k_b := g/a, g/b
  106.                         //fmt.Printf("lcm=%d, k_a=%d, k_b=%d\n", g, k_a, k_b)
  107.                        
  108.             for k := 0; k < n+1; k++ { matrix[i][k].numer *= k_b } //mul
  109.                         for k := 0; k < n+1; k++ { matrix[i][k].numer -= k_a * (matrix[j][k].numer) } //sub
  110.  
  111.                         output_matrix(matrix, n)
  112.                 }
  113.         }
  114. }
  115.  
  116. func reverse_gauss_method(matrix [][]frc, n int) {
  117.         for j := n - 1; j > 0; j-- {
  118.                 output_matrix(matrix, n)
  119.                 for i := j - 1; i >= 0; i-- {
  120.                         neg_diag_elements(matrix, n, j)
  121.  
  122.                         a, b := matrix[j][j].numer, matrix[i][j].numer
  123.                         //fmt.Printf("a=%d, b=%d, ", a, b)
  124.                         if 0 == b { continue }
  125.                         if 0 == a {
  126.                                 fmt.Printf("No solution :(\n")
  127.                                 os.Exit(0)
  128.                         }
  129.  
  130.                         g := lcm(a, b)
  131.                         k_a, k_b := g/a, g/b
  132.                         //fmt.Printf("lcm=%d, k_a=%d, k_b=%d\n", g, k_a, k_b)
  133.  
  134.                         for k := 0; k < n+1; k++ { matrix[i][k].numer *= k_b }
  135.                         for k := 0; k < n+1; k++ { matrix[i][k].numer -= k_a * (matrix[j][k].numer) }
  136.  
  137.                         output_matrix(matrix, n)
  138.                 }
  139.         }
  140. }
  141.  
  142. func get_answers(matrix [][]frc, n int) {
  143.         for i := 0; i < n; i++ {
  144.                 if 0 == matrix[i][i].numer {
  145.                         fmt.Printf("No solution :(\n")
  146.                         return
  147.                 }
  148.         }
  149.  
  150.         for i := 0; i < n; i++ {
  151.                 var ans frc
  152.                 ans.numer, ans.denom = matrix[i][n].numer, matrix[i][i].numer
  153.                 x := fraction_reduce(ans)
  154.                     if x.denom < 0 && x.numer > 0 { x.numer, x.denom = -x.numer, -x.denom }
  155.                 fmt.Printf("X%d=%d/%d\n", i, x.numer, x.denom)
  156.         }
  157. }
  158.  
  159. func gauss(matrix [][]frc, n int) int {
  160.    
  161.         direct_gauss_method(matrix, n)
  162.         //fmt.Printf("_direct_gauss: DONE\n")
  163.         reverse_gauss_method(matrix, n)
  164.         //fmt.Printf("_reverse_gauss: DONE\n\n")
  165.         get_answers(matrix, n)
  166.  
  167.         /* calculate one more time... */
  168.         var mark int
  169.         fmt.Printf("\n\nCalculate another matrix? ('1' == YES; any == NOPE):")
  170.         fmt.Scanf("%d\n", &mark)
  171.  
  172.         if mark == 1 { return 1 } else { return 0 }
  173. }
  174.  
  175. func main() {
  176.     one_more_time:
  177.         var n, i int
  178.         fmt.Printf("Insert N - rank of matrix (N rows; N+1 columns):\n")
  179.         fmt.Scanf("%d\n", &n)
  180.  
  181.         matrix := make([][]frc, n)
  182.         for i = 0; i < n; i++ { matrix[i] = make([]frc, n+1) }
  183.  
  184.         get_matrix(matrix, n)
  185.         mark := gauss(matrix, n)
  186.  
  187.         /*calculate one more time */
  188.         if mark == 1 { goto one_more_time }
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement