gaussian_elimination_GF2_matrix.sf 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/ruby
  2. # Perform Gauss elimination on a bit-matrix, where rows are integers.
  3. # Code inspired from:
  4. # https://github.com/martani/Quadratic-Sieve/blob/master/matrix.c
  5. func display_bitMatrix(A, n) {
  6. A.each { |r|
  7. var d = r.digits(2)
  8. d += (n-d.len + 1 -> of(0))
  9. say d.join(' ')
  10. }
  11. say ''
  12. }
  13. func gauss_elimination(A, n) {
  14. var m = A.end
  15. var I = (m+1).of {|i| 1 << i }
  16. var nrow = -1
  17. for col in (0 .. min(m, n)) {
  18. var npivot = -1
  19. for row in (nrow+1 .. m) {
  20. if (A[row].bit(col)) {
  21. npivot = row
  22. nrow++
  23. break
  24. }
  25. }
  26. next if (npivot < 0)
  27. if (npivot != nrow) {
  28. A.swap(npivot, nrow)
  29. I.swap(npivot, nrow)
  30. }
  31. for row in (nrow+1 .. m) {
  32. if (A[row].bit(col)) {
  33. A[row] ^= A[nrow]
  34. I[row] ^= I[nrow]
  35. }
  36. }
  37. }
  38. return I
  39. }
  40. var n = 5 # number of columns-1
  41. var A = [
  42. 0b001100, # 12
  43. 0b001011, # 11
  44. 0b010111, # 23
  45. 0b010011, # 19
  46. 0b010001, # 17
  47. 0b001111, # 15
  48. ]
  49. say "=> Matrix A before Gaussian elimination"
  50. display_bitMatrix(A, n)
  51. var I = gauss_elimination(A, n)
  52. say "=> Matrix A after Gaussian elimination"
  53. display_bitMatrix(A, n)
  54. say "=> Matrix I"
  55. display_bitMatrix(I, n)
  56. say "A = #{A}"
  57. say "I = #{I}"
  58. assert_eq(I, [2, 18, 6, 10, 7, 46])
  59. assert_eq(A, [11, 26, 28, 24, 16, 0])