algebra 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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