algebra 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.travis.yml +7 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.lock +28 -0
  7. data/LICENSE.txt +21 -0
  8. data/README-ja.txt +60 -0
  9. data/README.md +61 -0
  10. data/Rakefile +43 -0
  11. data/algebra.gemspec +33 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/doc-ja/README-ja.html +69 -0
  15. data/doc-ja/README-ja.rd +60 -0
  16. data/doc-ja/README.html +0 -0
  17. data/doc-ja/README.rd +0 -0
  18. data/doc-ja/algebra-ja.html +66 -0
  19. data/doc-ja/algebra-ja.rd +60 -0
  20. data/doc-ja/algebraic-equation-ja.html +36 -0
  21. data/doc-ja/algebraic-equation-ja.rd +26 -0
  22. data/doc-ja/algebraic-extension-field-ja.html +122 -0
  23. data/doc-ja/algebraic-extension-field-ja.rd +118 -0
  24. data/doc-ja/algebraic-parser-ja.html +87 -0
  25. data/doc-ja/algebraic-parser-ja.rd +95 -0
  26. data/doc-ja/changes.html +161 -0
  27. data/doc-ja/changes.rd +119 -0
  28. data/doc-ja/elementary-divisor-ja.html +56 -0
  29. data/doc-ja/elementary-divisor-ja.rd +45 -0
  30. data/doc-ja/euclidian-ring-ja.html +78 -0
  31. data/doc-ja/euclidian-ring-ja.rd +69 -0
  32. data/doc-ja/finite-group-ja.html +285 -0
  33. data/doc-ja/finite-group-ja.rd +276 -0
  34. data/doc-ja/finite-map-ja.html +224 -0
  35. data/doc-ja/finite-map-ja.rd +227 -0
  36. data/doc-ja/finite-set-ja.html +393 -0
  37. data/doc-ja/finite-set-ja.rd +408 -0
  38. data/doc-ja/index-ja.html +113 -0
  39. data/doc-ja/index-ja.rd +112 -0
  40. data/doc-ja/jordan-form-ja.html +106 -0
  41. data/doc-ja/jordan-form-ja.rd +99 -0
  42. data/doc-ja/localized-ring-ja.html +121 -0
  43. data/doc-ja/localized-ring-ja.rd +131 -0
  44. data/doc-ja/m-polynomial-ja.html +542 -0
  45. data/doc-ja/m-polynomial-ja.rd +596 -0
  46. data/doc-ja/matrix-algebra-ja.html +686 -0
  47. data/doc-ja/matrix-algebra-ja.rd +727 -0
  48. data/doc-ja/matrix-algebra-triplet-ja.html +124 -0
  49. data/doc-ja/matrix-algebra-triplet-ja.rd +129 -0
  50. data/doc-ja/permutation-group-ja.html +159 -0
  51. data/doc-ja/permutation-group-ja.rd +151 -0
  52. data/doc-ja/polynomial-converter-ja.html +64 -0
  53. data/doc-ja/polynomial-converter-ja.rd +54 -0
  54. data/doc-ja/polynomial-ja.html +446 -0
  55. data/doc-ja/polynomial-ja.rd +473 -0
  56. data/doc-ja/residue-class-ring-ja.html +112 -0
  57. data/doc-ja/residue-class-ring-ja.rd +113 -0
  58. data/doc-ja/sample-algebraic-equation01.rb.v.rd +11 -0
  59. data/doc-ja/sample-algebraic-equation02.rb.v.rd +11 -0
  60. data/doc-ja/sample-algebraic-root01.rb.v.rd +20 -0
  61. data/doc-ja/sample-algebraicfield01.rb.v.rd +26 -0
  62. data/doc-ja/sample-algebraicfield02.rb.v.rd +15 -0
  63. data/doc-ja/sample-cayleyhamilton01.rb.v.rd +14 -0
  64. data/doc-ja/sample-diagonalization01.rb.v.rd +48 -0
  65. data/doc-ja/sample-divmod01.rb.v.rd +17 -0
  66. data/doc-ja/sample-elementary-divisor01.rb.v.rd +48 -0
  67. data/doc-ja/sample-factorize01.rb.v.rd +11 -0
  68. data/doc-ja/sample-factorize02.rb.v.rd +13 -0
  69. data/doc-ja/sample-factorize03.rb.v.rd +14 -0
  70. data/doc-ja/sample-factorize04.rb.v.rd +14 -0
  71. data/doc-ja/sample-factorize05.rb.v.rd +53 -0
  72. data/doc-ja/sample-galois-group01.rb.v.rd +27 -0
  73. data/doc-ja/sample-gaussian-elimination01.rb.v.rd +19 -0
  74. data/doc-ja/sample-geometry01.rb.v.rd +33 -0
  75. data/doc-ja/sample-geometry02.rb.v.rd +34 -0
  76. data/doc-ja/sample-geometry03.rb.v.rd +45 -0
  77. data/doc-ja/sample-geometry04.rb.v.rd +33 -0
  78. data/doc-ja/sample-geometry07.rb.v.rd +62 -0
  79. data/doc-ja/sample-groebner01.rb.v.rd +13 -0
  80. data/doc-ja/sample-groebner02.rb.v.rd +18 -0
  81. data/doc-ja/sample-groebner03.rb.v.rd +19 -0
  82. data/doc-ja/sample-group01.rb.v.rd +21 -0
  83. data/doc-ja/sample-jordan-form01.rb.v.rd +56 -0
  84. data/doc-ja/sample-jordanform01.rb.v.rd +55 -0
  85. data/doc-ja/sample-lagrange-multiplier01.rb.v.rd +35 -0
  86. data/doc-ja/sample-m-factorize01.rb.v.rd +15 -0
  87. data/doc-ja/sample-m-factorize02.rb.v.rd +12 -0
  88. data/doc-ja/sample-m-polynomial01.rb.v.rd +10 -0
  89. data/doc-ja/sample-map01.rb.v.rd +9 -0
  90. data/doc-ja/sample-polynomial01.rb.v.rd +9 -0
  91. data/doc-ja/sample-polynomial02.rb.v.rd +11 -0
  92. data/doc-ja/sample-primefield01.rb.v.rd +13 -0
  93. data/doc-ja/sample-quotientfield01.rb.v.rd +11 -0
  94. data/doc-ja/sample-quotientfield02.rb.v.rd +18 -0
  95. data/doc-ja/sample-quotientfield03.rb.v.rd +16 -0
  96. data/doc-ja/sample-quotientfield04.rb.v.rd +16 -0
  97. data/doc-ja/sample-set01.rb.v.rd +18 -0
  98. data/doc-ja/sample-splitting-field01.rb.v.rd +19 -0
  99. data/doc-ja/samples-ja.html +885 -0
  100. data/doc-ja/samples-ja.rd +221 -0
  101. data/doc-ja/style.css +85 -0
  102. data/doc-ja/todo.html +20 -0
  103. data/doc-ja/todo.rd +9 -0
  104. data/lib/algebra.rb +36 -0
  105. data/lib/algebra/algebraic-equation.rb +56 -0
  106. data/lib/algebra/algebraic-extension-field.rb +135 -0
  107. data/lib/algebra/algebraic-parser.rb +160 -0
  108. data/lib/algebra/algebraic-system.rb +224 -0
  109. data/lib/algebra/annihilate.rb +52 -0
  110. data/lib/algebra/array-supplement.rb +53 -0
  111. data/lib/algebra/auto-require.rb +84 -0
  112. data/lib/algebra/chinese-rem-th.rb +135 -0
  113. data/lib/algebra/combinatorial.rb +145 -0
  114. data/lib/algebra/elementary-divisor.rb +193 -0
  115. data/lib/algebra/euclidian-ring.rb +161 -0
  116. data/lib/algebra/factors.rb +305 -0
  117. data/lib/algebra/finite-group.rb +374 -0
  118. data/lib/algebra/finite-map.rb +201 -0
  119. data/lib/algebra/finite-set.rb +456 -0
  120. data/lib/algebra/galois-group.rb +129 -0
  121. data/lib/algebra/gaussian-elimination.rb +385 -0
  122. data/lib/algebra/groebner-basis-coeff.rb +228 -0
  123. data/lib/algebra/groebner-basis.rb +197 -0
  124. data/lib/algebra/import-module-single-thread.rb +86 -0
  125. data/lib/algebra/import-module.rb +491 -0
  126. data/lib/algebra/jordan-form.rb +114 -0
  127. data/lib/algebra/linear-algebra.rb +143 -0
  128. data/lib/algebra/localized-ring.rb +294 -0
  129. data/lib/algebra/m-index.rb +282 -0
  130. data/lib/algebra/m-polynomial-factor-int.rb +186 -0
  131. data/lib/algebra/m-polynomial-factor-zp.rb +114 -0
  132. data/lib/algebra/m-polynomial-factor.rb +315 -0
  133. data/lib/algebra/m-polynomial-gcd.rb +40 -0
  134. data/lib/algebra/m-polynomial.rb +875 -0
  135. data/lib/algebra/matrix-algebra-triplet.rb +292 -0
  136. data/lib/algebra/matrix-algebra.rb +929 -0
  137. data/lib/algebra/numeric-supplement.rb +123 -0
  138. data/lib/algebra/permutation-group.rb +257 -0
  139. data/lib/algebra/polynomial-converter.rb +193 -0
  140. data/lib/algebra/polynomial-factor-alg.rb +148 -0
  141. data/lib/algebra/polynomial-factor-int.rb +252 -0
  142. data/lib/algebra/polynomial-factor-zp.rb +165 -0
  143. data/lib/algebra/polynomial-factor.rb +140 -0
  144. data/lib/algebra/polynomial.rb +592 -0
  145. data/lib/algebra/powers.rb +31 -0
  146. data/lib/algebra/prime-gen.rb +32 -0
  147. data/lib/algebra/rational.rb +81 -0
  148. data/lib/algebra/residue-class-ring.rb +219 -0
  149. data/lib/algebra/sets-system.rb +43 -0
  150. data/lib/algebra/splitting-field.rb +103 -0
  151. data/lib/algebra/version.rb +3 -0
  152. data/sample/Makefile +10 -0
  153. data/sample/do-testscripts.rb +100 -0
  154. data/sample/sample-algebraic-equation01.rb +6 -0
  155. data/sample/sample-algebraic-equation02.rb +6 -0
  156. data/sample/sample-algebraic-root01.rb +15 -0
  157. data/sample/sample-algebraicfield01.rb +21 -0
  158. data/sample/sample-algebraicfield02.rb +10 -0
  159. data/sample/sample-cayleyhamilton01.rb +9 -0
  160. data/sample/sample-diagonalization01.rb +43 -0
  161. data/sample/sample-divmod01.rb +12 -0
  162. data/sample/sample-elementary-divisor01.rb +43 -0
  163. data/sample/sample-factorize01.rb +6 -0
  164. data/sample/sample-factorize02.rb +8 -0
  165. data/sample/sample-factorize03.rb +9 -0
  166. data/sample/sample-factorize04.rb +9 -0
  167. data/sample/sample-factorize05.rb +48 -0
  168. data/sample/sample-galois-group01.rb +22 -0
  169. data/sample/sample-gaussian-elimination01.rb +14 -0
  170. data/sample/sample-geometry01.rb +28 -0
  171. data/sample/sample-geometry02.rb +29 -0
  172. data/sample/sample-geometry03.rb +40 -0
  173. data/sample/sample-geometry04.rb +28 -0
  174. data/sample/sample-geometry07.rb +58 -0
  175. data/sample/sample-groebner01.rb +8 -0
  176. data/sample/sample-groebner02.rb +13 -0
  177. data/sample/sample-groebner03.rb +14 -0
  178. data/sample/sample-group01.rb +16 -0
  179. data/sample/sample-jordan-form01.rb +51 -0
  180. data/sample/sample-lagrange-multiplier01.rb +30 -0
  181. data/sample/sample-m-factorize01.rb +10 -0
  182. data/sample/sample-m-factorize02.rb +7 -0
  183. data/sample/sample-m-polynomial01.rb +5 -0
  184. data/sample/sample-map01.rb +4 -0
  185. data/sample/sample-polynomial01.rb +4 -0
  186. data/sample/sample-polynomial02.rb +6 -0
  187. data/sample/sample-primefield01.rb +8 -0
  188. data/sample/sample-quotientfield01.rb +6 -0
  189. data/sample/sample-quotientfield02.rb +13 -0
  190. data/sample/sample-quotientfield03.rb +11 -0
  191. data/sample/sample-quotientfield04.rb +11 -0
  192. data/sample/sample-set01.rb +13 -0
  193. data/sample/sample-splitting-field01.rb +14 -0
  194. data/sample/test-00-cayley-hamilton.rb +76 -0
  195. data/sample/test-00-groebner-basis.rb +274 -0
  196. data/sample/test-00-polynomial-factor-alg.rb +89 -0
  197. data/sample/test-00.list +4 -0
  198. data/sample/time-trial.rb +65 -0
  199. metadata +373 -0
@@ -0,0 +1,129 @@
1
+ # Galois Group
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.13 (2002.07.22)
6
+ #
7
+ # This algorithm is founded on the paper:
8
+ # "Computaion of the splitting fields and the Galois groups of polynomials"
9
+ # by H. Anai, M. Noro and K. Yokoyama
10
+ # (Progress in Mathematics, 29-50, Vol. 143, 1996, Birkhuaser Verlag
11
+ # Basel/Swizerland)
12
+
13
+ # require 'algebra/ruby-version'
14
+ require 'algebra/permutation-group'
15
+
16
+ module Algebra
17
+ module Galois
18
+ def galois_group(pre_facts = nil, sw = nil)
19
+ # sw : Ordinary, sw is asumed to be nil.
20
+
21
+ poly = sqfree
22
+
23
+ sf = poly.splitting_field(pre_facts, nil, true)
24
+
25
+ gens = []
26
+ reps0 = []
27
+ n = poly.deg
28
+ dpn = sf.def_polys.size
29
+ for i in 0...dpn do
30
+ reps = []
31
+ for j in (sw ? i : i + 1)...n do
32
+ if g = prolong((0...i).to_a + [j], sf)
33
+ reps << g
34
+ end
35
+ end
36
+ gens.unshift reps
37
+ # gens.push reps
38
+ end
39
+
40
+ for i in dpn...n; gens << [(0...n).to_a]; end if sw
41
+ gs = gens.map { |a| a.map { |g| complete(g, sf) } }
42
+ ary_of_gens = gs.collect { |a| a.collect { |x| Permutation.new(x) } }
43
+ PermutationGroup.generate_strong(Permutation.unity(n), *ary_of_gens)
44
+ end
45
+
46
+ def prolong(ary, sf)
47
+ # INPUT
48
+ # ary: a set of defining polynomial
49
+ # sf: splitting field
50
+ # OUTPUT:
51
+ # ary0: the first l-part of g if g exists; nil other wize
52
+
53
+ t = ary.size
54
+ roots = sf.proots
55
+
56
+ pn = sf.def_polys.size
57
+ defs = sf.def_polys
58
+ for i in 0...t do
59
+ r = roots.values_at(*ary)[0..i]
60
+ return nil unless defs[i].abs_lift.evaluate(*r).zero? # this eval. needs no_sq
61
+ end
62
+
63
+ ary0 = ary.dup
64
+ for k in t...defs.size do
65
+ sw = false
66
+ for c in (0...roots.size).to_a - ary0 do
67
+ r = roots.values_at(* ary0 + [c])[0..k]
68
+ next unless defs[k].abs_lift.evaluate(*r).zero? # this eval. needs no_sq
69
+ ary0.push c
70
+ sw = true
71
+ break
72
+ end
73
+ return nil unless sw
74
+ end
75
+ ary0
76
+ end
77
+
78
+ def complete(ary, sf)
79
+ # INPUT:
80
+ # ary: the first l-part of g
81
+ # sf: splitting field
82
+ # OUTPUT:
83
+ # ary0: the complete expression of g
84
+
85
+ ary0 = ary.dup
86
+ roots = sf.proots
87
+
88
+ n = roots.size
89
+ m = sf.def_polys.size
90
+ for i in m...n
91
+ ri = roots[i].abs_lift
92
+ h = if ri.is_a? Algebra::Polynomial
93
+ r = roots.values_at(*ary0[0...m])
94
+ ri.evaluate(*r)
95
+ else
96
+ ri
97
+ end
98
+ for k in 0...n
99
+ ary0.push k if !ary0.include?(k) && roots[k] == h
100
+ end
101
+ end
102
+ raise "complete: #{ary.inspect} is not extendable." if ary0.size != n
103
+ ary0
104
+ end
105
+ end
106
+ end
107
+
108
+ if __FILE__ == $PROGRAM_NAME
109
+ require 'algebra/rational'
110
+ require 'algebra/polynomial'
111
+ require 'algebra/splitting-field'
112
+
113
+ P = Algebra.Polynomial(Rational, 'x')
114
+ x = P.var
115
+ f = [
116
+ x**3 - 2, # 0
117
+ (x**2 - 2) * (x**2 - 3), # 1
118
+ x**3 - 3 * x + 1, # 2
119
+ x**3 - x + 1, # 3
120
+ (x**3 - 2)**2, # 4
121
+ x**4 + 1,
122
+ x**4 - x + 1
123
+ ][ARGV.shift.to_i]
124
+
125
+ puts "Galois Group of #{f} is:"
126
+ f.galois_group.each do |reps|
127
+ p reps
128
+ end
129
+ end
@@ -0,0 +1,385 @@
1
+ # Gussian Elimination Algorism
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.1 (2001.09.12)
6
+
7
+ module Algebra
8
+ module GaussianElimination
9
+ #ElementaryOpeartion
10
+ def sswap_r!(i, j)
11
+ a, b = row!(i), row!(j)
12
+ set_row(i, b).set_row(j, a)
13
+ end
14
+
15
+ def swap_r!(i, j)
16
+ a, b = row(i), row(j)
17
+ set_row(i, b).set_row(j, a)
18
+ end
19
+
20
+ def swap_r(i, j)
21
+ dup.swap_r!(i, j)
22
+ end
23
+
24
+ def swap_c!(i, j)
25
+ a, b = column(i), column(j)
26
+ set_column(i, b).set_column(j, a)
27
+ end
28
+
29
+ def swap_c(i, j)
30
+ dup.swap_c!(i, j)
31
+ end
32
+
33
+ def multiply_r!(i, c)
34
+ set_row(i, row(i).collect{|x| x * c})
35
+ end
36
+
37
+ def multiply_r(i, c)
38
+ dup.multiply_r!(i, c)
39
+ end
40
+
41
+ def multiply_c!(j, c)
42
+ set_column(j, column(j).collect{|x| x * c})
43
+ end
44
+
45
+ def multiply_c(j, c)
46
+ dup.multiply_c!(j, c)
47
+ end
48
+
49
+ def divide_r!(i, c)
50
+ set_row(i, row(i).collect{|x| x / c})
51
+ end
52
+
53
+ def divide_r(i, c)
54
+ dup.divide_r!(i, c)
55
+ end
56
+
57
+ def divide_c!(j, c)
58
+ set_column(j, column(j).collect{|x| x / c})
59
+ end
60
+
61
+ def divide_c(j, c)
62
+ dup.divide_c!(j, c)
63
+ end
64
+
65
+ def mix_r!(i, j, c = nil)
66
+ row_i = row(i)
67
+ row_j = row(j)
68
+ set_row(i,
69
+ (0...csize).collect {|k|
70
+ row_i[k] + (c ? row_j[k]*c : row_j[k])
71
+ }
72
+ )
73
+ end
74
+
75
+ def mix_r(i, j, c = nil)
76
+ dup.mix_r!(i, j, c)
77
+ end
78
+
79
+ def mix_c!(i, j, c = nil)
80
+ column_i = column(i)
81
+ column_j = column(j)
82
+ set_column(i, (0...rsize).collect{|k|
83
+ column_i[k] + (c ? column_j[k]*c : column_j[k])
84
+ }
85
+ )
86
+ end
87
+
88
+ def mix_c(i, j, c = nil)
89
+ dup.mix_c!(i, j, c)
90
+ end
91
+
92
+ def left_eliminate!
93
+ inv = Algebra.SquareMatrix(ground, rsize).unity
94
+ k = ground.unity
95
+ pi = 0
96
+ each_j do |j|
97
+ if i = (pi...rsize).find{|i1| !self[i1, j].zero?}
98
+ # pivots.push j
99
+ if i != pi
100
+ swap_r!(pi, i); inv.swap_r!(pi, i)
101
+ k = -k
102
+ end
103
+ ##### this lets the entries be in ground #####
104
+ c = ground.unity / self[pi, j]
105
+ ##############################################
106
+ multiply_r!(pi, c); inv.multiply_r!(pi, c)
107
+ k = k * c
108
+ each_i do |i0|
109
+ next if i0 == pi
110
+ d = self[i0, j]# / self[pi, j]
111
+ mix_r!(i0, pi, -d); inv.mix_r!(i0, pi, -d)
112
+ end
113
+ pi += 1
114
+ end
115
+ end
116
+ [inv, k, pi]
117
+ end
118
+
119
+ def _normalize!(pi, j, inv)
120
+ c = ground.unity
121
+ e = self[pi, j]
122
+ if !e.unity? && e.unit?
123
+ c /= e
124
+ multiply_r!(pi, c); inv.multiply_r!(pi, c)
125
+ end
126
+ c
127
+ end
128
+ private :_normalize!
129
+
130
+ def left_eliminate_euclidian!
131
+ inv = Algebra.SquareMatrix(ground, rsize).unity
132
+ k = ground.unity
133
+ pi = 0
134
+ each_j do |j|
135
+ if i = (pi...rsize).find{|i1| !self[i1, j].zero?}
136
+ # pivots.push j
137
+ if i != pi
138
+ swap_r!(pi, i); inv.swap_r!(pi, i)
139
+ k = -k
140
+ end
141
+ k *= _normalize!(pi, j, inv)
142
+ (pi+1...rsize).each do |i0|
143
+ # each_i do |i0|; next if i0 == pi
144
+ d = self[i0, j] / self[pi, j]
145
+ mix_r!(i0, pi, -d); inv.mix_r!(i0, pi, -d)
146
+ if !self[i0, j].zero? && i0 > pi
147
+ swap_r!(i0, pi); inv.swap_r!(i0, pi);
148
+ k = -k
149
+ k *= _normalize!(pi, j, inv)
150
+ redo
151
+ end
152
+ end
153
+
154
+ pi += 1
155
+ end
156
+ end
157
+ [inv, k, pi]
158
+ end
159
+
160
+ def left_inverse
161
+ dup.left_eliminate![0]
162
+ end
163
+
164
+ def left_sweep
165
+ m = dup
166
+ m.left_eliminate!
167
+ m
168
+ end
169
+
170
+ def step_matrix?
171
+ pivots = []
172
+ i = j = 0
173
+ each_j do |j|
174
+ if !self[i, j].zero?
175
+ 0.upto rsize - 1 do |i0|
176
+ return nil if i0 != i && !self[i0, j].zero?
177
+ end
178
+ pivots << j
179
+ return pivots if (i += 1) >= rsize
180
+ else
181
+ (i+1).upto rsize - 1 do |i0|
182
+ return nil if i0 != i && !self[i0, j].zero?
183
+ end
184
+ end
185
+ end
186
+ pivots
187
+ end
188
+
189
+ def kernel_basis
190
+ if pivots = step_matrix?
191
+ m = self
192
+ else
193
+ m = left_sweep
194
+ pivots = m.step_matrix?
195
+ end
196
+ basis = []
197
+
198
+ v = Algebra.Vector(ground, csize)
199
+ (0...csize).each do |i|
200
+ unless pivots.include? i
201
+ base = v.vector{|j|
202
+ if j == i
203
+ ground.unity
204
+ elsif k = pivots.index(j)
205
+ -m[k, i] / m[k, j] #m[k, j] may not be an unit.
206
+ else
207
+ ground.zero
208
+ end
209
+ }
210
+ basis.push base
211
+ end
212
+ end
213
+ basis
214
+ end
215
+ end
216
+
217
+ class MatrixAlgebra
218
+ include GaussianElimination
219
+ def rank
220
+ n, k, pi = dup.left_eliminate!
221
+ pi
222
+ end
223
+
224
+ def orthogonal_basis
225
+ transpose.kernel_basis
226
+ end
227
+ end
228
+
229
+ class SquareMatrix < MatrixAlgebra
230
+ def inverse_field
231
+ n, k, pi = dup.left_eliminate!
232
+ if pi != size
233
+ raise "Error: invert non invertible SquareMatrix"
234
+ end
235
+ n
236
+ end
237
+ # def inverse_euclidian; left_inverse_euclidian; end
238
+
239
+ def determinant_by_elimination_old
240
+ m = dup
241
+ inv, k = m.left_eliminate!
242
+ s = ground.unity
243
+ (0...size).each do |i|
244
+ s *= m[i, i]
245
+ end
246
+ s / k
247
+ end
248
+
249
+ def determinant_by_elimination_euclidian_old
250
+ m = dup
251
+ inv, k = m.left_eliminate_euclidian!
252
+ s = ground.unity
253
+ (0...size).each do |i|
254
+ s *= m[i, i]
255
+ end
256
+ s / k
257
+ end
258
+
259
+ #ground ring must be a field
260
+ def determinant_by_elimination
261
+ m = dup
262
+ det = ground.unity
263
+ each_j do |d|
264
+ if i = (d...size).find{|i| !m[i, d].zero?}
265
+ if i != d
266
+ m.sswap_r!(d, i)
267
+ det = -det
268
+ end
269
+ c = m[d, d]
270
+ det *= c
271
+ (d+1...size).each do |i0|
272
+ r = m.row!(i0)
273
+ q = ground.unity * m[i0, d] / c #this lets the entries be in ground
274
+ (d+1...size).each do |j0|
275
+ r[j0] -= q * m[d, j0]
276
+ end
277
+ end
278
+ else
279
+ return ground.zero
280
+ end
281
+ end
282
+ det
283
+ end
284
+
285
+ #ground ring must be an euclidian domain
286
+ def determinant_by_elimination_euclidian#_new
287
+ m = dup
288
+ det = ground.unity
289
+ each_j do |d|
290
+ if i = (d...size).find{|i| !m[i, d].zero?}
291
+ if i != d
292
+ m.sswap_r!(d, i)
293
+ det = -det
294
+ end
295
+ (d+1...size).each do |i0|
296
+ r = m.row!(i0)
297
+ q = m[i0, d] / m[d, d]
298
+ (d...size).each do |j0|; r[j0] -= q * m[d, j0]; end
299
+ unless m[i0, d].zero?
300
+ m.sswap_r!(d, i0)
301
+ det = -det
302
+ redo
303
+ end
304
+ end
305
+ det *= m[d, d]
306
+ else
307
+ return ground.zero
308
+ end
309
+ end
310
+ det
311
+ end
312
+
313
+ def determinant
314
+ if ground.field?
315
+ determinant_by_elimination
316
+ elsif ground.euclidian?
317
+ determinant_by_elimination_euclidian
318
+ else
319
+ determinant!
320
+ end
321
+ end
322
+
323
+ end
324
+ end
325
+
326
+ if $0 == __FILE__
327
+ require "algebra/m-polynomial"
328
+ require "algebra/polynomial"
329
+ require "algebra/rational"
330
+ require "algebra/matrix-algebra"
331
+ class Rational# < Numeric
332
+ def inspect; to_s; end
333
+ end
334
+ # include Algebra
335
+
336
+ G = Algebra.MatrixAlgebra(Rational, 2, 2)
337
+ a = G[[0, 0], [1, -1]]
338
+ p a
339
+ p a.kernel_basis
340
+
341
+ # R = MPolynomial(Integer)
342
+ R = Algebra.MPolynomial(Rational)
343
+ a, b, c, d, e, f, g, h, i, j, k, l, x, y, z = R.vars("abcdefghijklxyz")
344
+ M3 = Algebra.MatrixAlgebra(R, 3, 4)
345
+ m = M3[
346
+ [a, b, c, d],
347
+ [e, f, g, h],
348
+ [i, j, k, l]
349
+ ]
350
+ m.display
351
+ m.swap_r(0, 2).display
352
+ # m.set_column(1, [1,2,3]).display
353
+ # puts
354
+ m.swap_c(0, 2).display
355
+ m.multiply_r(2, x).display
356
+ m.multiply_c(0, x).display
357
+ m.mix_r(0, 2, x).display
358
+ m.mix_c(0, 2, x).display
359
+
360
+ u, z = R.unity, R.zero
361
+ require "algebra/residue-class-ring"
362
+ F = Algebra.ResidueClassRing(Integer, 2)
363
+ # M = SquareMatrix(Rational, 8)
364
+ M = Algebra.SquareMatrix(F, 8)
365
+ m = M[
366
+ "10001101".scan(/./).collect{|x|x.to_i},
367
+ "00000011".scan(/./).collect{|x|x.to_i},
368
+ "01001011".scan(/./).collect{|x|x.to_i},
369
+ "00001111".scan(/./).collect{|x|x.to_i},
370
+ "00101011".scan(/./).collect{|x|x.to_i},
371
+ "00001001".scan(/./).collect{|x|x.to_i},
372
+ "00011011".scan(/./).collect{|x|x.to_i},
373
+ "00000111".scan(/./).collect{|x|x.to_i}
374
+ ]
375
+ m = m - m.unity
376
+ puts "m = "
377
+ m.display
378
+ m.kernel_basis.each do |b|
379
+ puts b.class
380
+ puts b
381
+ #[1, 0, 0, 0, 0, 0, 0, 0]
382
+ #[0, 1, 1, 1, 1, 1, 1, 0]
383
+ #[0, 1, 1, 0, 1, 0, 0, 1]
384
+ end
385
+ end