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,292 @@
1
+ # Matrix Algebra Triplet
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.0 (2001.11.01)
6
+
7
+ require 'algebra/gaussian-elimination'
8
+ require 'algebra/elementary-divisor'
9
+
10
+ module Algebra
11
+ class MatrixAlgebra
12
+ def to_triplet
13
+ Algebra::MatrixAlgebraTriplet.new(self)
14
+ end
15
+
16
+ def to_quint
17
+ Algebra::MatrixAlgebraQuint.new(self)
18
+ end
19
+ end
20
+
21
+ class MatrixAlgebraTriplet
22
+ include GaussianElimination
23
+ include ElementaryDivisor
24
+
25
+ attr_reader :left, :body, :right, :ground
26
+ def initialize(matrix, left = nil, right = nil)
27
+ @body = matrix
28
+ @type = @body.class
29
+ @ground = @type.ground
30
+ @left_type = Algebra.SquareMatrix(@type.ground, @type.rsize)
31
+ @right_type = Algebra.SquareMatrix(@type.ground, @type.csize)
32
+ @left = left ? left : @left_type.unity
33
+ @right = right ? right : @right_type.unity
34
+ end
35
+
36
+ def to_ary
37
+ [body, left, right]
38
+ end
39
+
40
+ alias to_a to_ary
41
+
42
+ def dup
43
+ self.class.new(body.dup, left.dup, right.dup)
44
+ end
45
+
46
+ def transpose
47
+ self.class.new(body.transpose, right.transpose, left.transpose)
48
+ end
49
+
50
+ def replace(other)
51
+ initialize(other.body, other.left, other.right)
52
+ self
53
+ end
54
+
55
+ def display
56
+ puts '============= begin'
57
+ @left.display
58
+ puts
59
+ @body.display
60
+ puts
61
+ @right.display
62
+ puts '============= end'
63
+ end
64
+
65
+ def [](i, j)
66
+ @body[i, j]
67
+ end
68
+
69
+ def rsize
70
+ @body.rsize
71
+ end
72
+
73
+ def csize
74
+ @body.csize
75
+ end
76
+
77
+ def each_i(&block)
78
+ @body.each_i(&block)
79
+ end
80
+
81
+ def each_j(&block)
82
+ @body.each_j(&block)
83
+ end
84
+
85
+ def row!(i)
86
+ @body.row!(i)
87
+ end
88
+
89
+ # ElementaryOpeartion
90
+ def sswap_r!(i, j)
91
+ @left.sswap_r!(i, j)
92
+ @body.sswap_r!(i, j)
93
+ self
94
+ end
95
+
96
+ def swap_r!(i, j)
97
+ @left.swap_r!(i, j)
98
+ @body.swap_r!(i, j)
99
+ self
100
+ end
101
+
102
+ # def swap_r(i, j)
103
+ # dup.swap_r!(i, j)
104
+ # end
105
+
106
+ def swap_c!(i, j)
107
+ @body.swap_c!(i, j)
108
+ @right.swap_c!(i, j)
109
+ self
110
+ end
111
+
112
+ # def swap_c(i, j)
113
+ # dup.swap_c!(i, j)
114
+ # end
115
+
116
+ def multiply_r!(i, c)
117
+ @left.multiply_r!(i, c)
118
+ @body.multiply_r!(i, c)
119
+ self
120
+ end
121
+
122
+ # def multiply_r(i, c)
123
+ # dup.multiply_r!(i, c)
124
+ # end
125
+
126
+ def multiply_c!(j, c)
127
+ @body.multiply_c!(j, c)
128
+ @right.multiply_c!(j, c)
129
+ self
130
+ end
131
+
132
+ # def multiply_c(j, c)
133
+ # dup.multiply_c!(j, c)
134
+ # end
135
+
136
+ def divide_r!(i, c)
137
+ @left.divide_r!(i, c)
138
+ @body.divide_r!(i, c)
139
+ end
140
+
141
+ # def divide_r(i, c)
142
+ # dup.divide_r!(i, c)
143
+ # end
144
+
145
+ def divide_c!(j, c)
146
+ @body.divide_c!(j, c)
147
+ @right.divide_c!(j, c)
148
+ end
149
+
150
+ # def divide_c(j, c)
151
+ # dup.divide_c!(j, c)
152
+ # end
153
+
154
+ def mix_r!(i, j, c = nil)
155
+ @left.mix_r!(i, j, c)
156
+ @body.mix_r!(i, j, c)
157
+ self
158
+ end
159
+
160
+ # def mix_r(i, j, c = nil)
161
+ # dup.mix_r!(i, j, c)
162
+ # end
163
+
164
+ def mix_c!(i, j, c = nil)
165
+ @body.mix_c!(i, j, c)
166
+ @right.mix_c!(i, j, c)
167
+ self
168
+ end
169
+
170
+ # def mix_c(i, j, c = nil)
171
+ # dup.mix_c!(i, j, c)
172
+ # end
173
+
174
+ def left_eliminate!
175
+ # inv = Algebra.SquareMatrix(ground, rsize).unity
176
+ k = ground.unity
177
+ pi = 0
178
+ each_j do |j|
179
+ next unless i = (pi...rsize).find { |i1| !self[i1, j].zero? }
180
+ if i != pi
181
+ swap_r!(pi, i) # ; inv.swap_r!(pi, i)
182
+ k = -k
183
+ end
184
+ c = ground.unity / self[pi, j] # this lets the entries be in ground
185
+ multiply_r!(pi, c) # ; inv.multiply_r!(pi, c)
186
+ k *= c
187
+ each_i do |i0|
188
+ next if i0 == pi
189
+ d = self[i0, j] # / self[pi, j]
190
+ mix_r!(i0, pi, -d) # ; inv.mix_r!(i0, pi, -d)
191
+ end
192
+ pi += 1
193
+ end
194
+ [left, k]
195
+ end
196
+ end
197
+
198
+ class MatrixAlgebraQuint < MatrixAlgebraTriplet
199
+ attr_reader :lefti, :righti
200
+ def initialize(matrix, left = nil, right = nil, lefti = nil, righti = nil)
201
+ super(matrix, left, right)
202
+ @lefti = lefti ? lefti : @left_type.unity
203
+ @righti = righti ? righti : @right_type.unity
204
+ end
205
+
206
+ def to_ary
207
+ [body, left, right, lefti, righti]
208
+ end
209
+
210
+ alias to_a to_ary
211
+
212
+ def dup
213
+ self.class.new(body.dup, left.dup, right.dup, lefti.dup, righti.dup)
214
+ end
215
+
216
+ def transpose
217
+ self.class.new(body.transpose, right.transpose, left.transpose,
218
+ righti.transpose, lefti.transpose)
219
+ end
220
+
221
+ def replace(other)
222
+ initialize(other.body, other.left, other.right, other.lefti, other.righti)
223
+ self
224
+ end
225
+
226
+ # ElementaryOpeartion
227
+ def sswap_r!(i, j)
228
+ @lefti.swap_c!(i, j) # sswap_c doesn't exist
229
+ super
230
+ end
231
+
232
+ def swap_r!(i, j)
233
+ @lefti.swap_c!(i, j)
234
+ super
235
+ end
236
+
237
+ def swap_c!(i, j)
238
+ @righti.swap_r!(i, j)
239
+ super
240
+ end
241
+
242
+ def multiply_r!(i, c)
243
+ @lefti.divide_c!(i, c)
244
+ super
245
+ end
246
+
247
+ def multiply_c!(j, c)
248
+ @righti.divide_r!(j, c)
249
+ super
250
+ end
251
+
252
+ def divide_r!(i, c)
253
+ @lefti.multiply_c!(i, c)
254
+ super
255
+ end
256
+
257
+ def divide_c!(j, c)
258
+ @righti.multiply_r!(j, c)
259
+ super
260
+ end
261
+
262
+ def mix_r!(i, j, c = nil)
263
+ @lefti.mix_c!(j, i, c ? -c : -1)
264
+ super
265
+ end
266
+
267
+ def mix_c!(i, j, c = nil)
268
+ @righti.mix_r!(j, i, c ? -c : -1)
269
+ super
270
+ end
271
+ end
272
+ end
273
+
274
+ if $PROGRAM_NAME == __FILE__
275
+ require 'algebra/m-polynomial'
276
+ require 'algebra/polynomial'
277
+ require 'algebra/rational'
278
+ require 'algebra/matrix-algebra'
279
+ # class Rational# < Numeric
280
+ # def inspect; to_s; end
281
+ # end
282
+ # include Algebra
283
+
284
+ G = Algebra.MatrixAlgebra(Rational, 2, 2)
285
+ a = G[[1, 1], [1, -1]]
286
+ a0 = Algebra::MatrixAlgebraTriplet.new(a)
287
+ a0.display
288
+ a0.left_eliminate!
289
+ puts '-------'
290
+ a0.display
291
+ # p a.kernel_basis
292
+ end
@@ -0,0 +1,929 @@
1
+ # MatrixAlgebra over Ring
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.05 (2003.06.24)
6
+
7
+ require "algebra/algebraic-system"
8
+ require "algebra/gaussian-elimination"
9
+
10
+ module Enumerable
11
+ def collecti
12
+ a = []
13
+ each_with_index do |x, i|
14
+ a.push yield(x, i)
15
+ end
16
+ a
17
+ end
18
+
19
+ def sum(z)
20
+ sum = z
21
+ each do |i|
22
+ sum += yield(i)
23
+ end
24
+ sum
25
+ end
26
+ end
27
+
28
+ module Algebra
29
+ def MatrixAlgebra(ground, rsize, csize)
30
+ MatrixAlgebra.create(ground, rsize, csize)
31
+ end
32
+
33
+ def SquareMatrix(ground, size)
34
+ SquareMatrix.create(ground, size)
35
+ end
36
+
37
+ def Vector(ground, size)
38
+ Vector.create(ground, size)
39
+ end
40
+
41
+ def Covector(ground, size)
42
+ Covector.create(ground, size)
43
+ end
44
+ module_function :MatrixAlgebra, :SquareMatrix, :Vector, :Covector
45
+
46
+ class MatrixAlgebra
47
+ extend AlgebraCreator
48
+ include AlgebraBase
49
+ include Enumerable
50
+ auto_req_init
51
+ auto_req :solve_eigen_value_problem, "algebra/linear-algebra"
52
+ auto_req :diagonalize, "algebra/linear-algebra"
53
+ auto_req :to_triplet, "algebra/matrix-algebra-triplet"
54
+ auto_req :to_quint, "algebra/matrix-algebra-triplet"
55
+ auto_req :e_inverse, "algebra/elementary-divisor"
56
+ auto_req :elementary_divisor, "algebra/elementary-divisor"
57
+ auto_req :e_diagonalize, "algebra/elementary-divisor"
58
+ auto_req :e_diagonalize!, "algebra/elementary-divisor"
59
+ autoload :JordanForm, "algebra/jordan-form"
60
+ auto_req :jordan_form, "algebra/jordan-form"
61
+ auto_req :jordan_form_info, "algebra/jordan-form"
62
+ # require 'algebra/linear-algebra'
63
+ # require 'algebra/matrix-algebra-triplet'
64
+ # require 'algebra/elementary-divisor'
65
+ # require 'algebra/jordan-form'
66
+
67
+ Matrices = {}
68
+
69
+ def initialize(array, conv = false)
70
+ raise "rsize error (#{array.size} for #{rsize})" if array.size != rsize
71
+ array.each do |v|
72
+ raise "csize error (#{v.size} for #{csize})" if v.size != csize
73
+ end
74
+ if conv
75
+ @bone = array.collect{|cv| cv.collect{|x|
76
+ ground.regulate(x) or
77
+ raise "initialize: unknown type #{x.class} (#{x})"
78
+ }}
79
+ else
80
+ @bone = array
81
+ end
82
+ end
83
+
84
+ def dup
85
+ # matrix{|x| self[* x.collect{|y| y.dup}]}
86
+ # matrix{|x| self[* x.collect{|y| y}]} #in 1.8.0, Integer can't be dup..
87
+ matrix{|i, j| self[i, j]} #in 1.8.0, Integer can't be dup..
88
+ end
89
+
90
+ def replace(m)
91
+ if m.is_a?(self.class) and sizes == m.sizes
92
+ each_index do |i, j|
93
+ @bone[i][j] = m[i, j]
94
+ end
95
+ else
96
+ raise "Type Error #{m.class}"
97
+ end
98
+ end
99
+
100
+ def simplify; matrix{|i, j| self[i, j].simplify}; end
101
+
102
+ def self.matrices; Matrices; end
103
+
104
+ def self.[](*a)
105
+ new(a, true)
106
+ end
107
+
108
+ ############################################
109
+ #
110
+ # matrix type conversion
111
+ #
112
+ #############################################
113
+
114
+ def self.*(otype)
115
+ if csize != otype.rsize
116
+ raise "type error (#{self} * #{otype}, #{csize}:#{otype.rsize})"
117
+ end
118
+
119
+ if ground.respond_to?(:wedge)
120
+ g = ground.wedge otype.ground
121
+ elsif ground <= Numeric
122
+ g = otype.ground
123
+ else
124
+ raise "*: unkown type conversion (#{ground}) * (#{oground})"
125
+ end
126
+
127
+ if otype <= Vector
128
+ Algebra::Vector.create(g, rsize)
129
+ elsif self <= Covector
130
+ Algebra::Covector.create(g, csize)
131
+ elsif rsize == otype.csize
132
+ SquareMatrix.create(g, rsize)
133
+ else
134
+ MatrixAlgebra.create(g, rsize, otype.csize)
135
+ end
136
+ end
137
+
138
+ # def self.vector_type
139
+ # Algebra::Vector.create(ground, rsize)
140
+ # end
141
+
142
+ # def self.covector_type
143
+ # Algebra::Covector.create(ground, csize)
144
+ # end
145
+
146
+ def self.minor
147
+ if self <= SquareMatrix
148
+ superclass.create(ground, size-1)
149
+ elsif self <= MatrixAlgebra
150
+ superclass.create(ground, rsize-1, csize-1)
151
+ else
152
+ raise "minor: unknown type #{self.class}"
153
+ end
154
+ end
155
+
156
+ def self.dsum(otype)
157
+ #unless ground == otype.ground
158
+ # raise "type error #{ground}.dsum #{otype.ground}"
159
+ #end
160
+ if self <= SquareMatrix and otype <= SquareMatrix
161
+ superclass.create(ground, size + otype.size)
162
+ else
163
+ superclass.create(ground, rsize + otype.rsize, csize + otype.csize)
164
+ end
165
+ end
166
+
167
+ def self.dsum_r(otype); raise "not implemented"; end
168
+
169
+ def self.dsum_c(otype); raise "not implemented"; end
170
+
171
+ ################################
172
+
173
+
174
+ # def [](i, j = nil)
175
+ # j ? @bone[i][j] : @bone[i]
176
+ # end
177
+
178
+ def [](i, j)
179
+ @bone[i][j]
180
+ end
181
+
182
+ def []=(i, j, x)
183
+ @bone[i][j] = x
184
+ end
185
+
186
+ def rows
187
+ (0...rsize).collect{|i| row(i)}
188
+ end
189
+
190
+ def row(i)
191
+ raise "size error" unless 0 <= i && i < rsize
192
+ @bone[i].clone
193
+ end
194
+
195
+ def row!(i) # column!(j) is not defined!
196
+ raise "size error" unless 0 <= i && i < rsize
197
+ @bone[i]
198
+ end
199
+
200
+ def set_row(i, array)
201
+ raise "size error" unless 0 <= i && i < rsize
202
+ raise "size error" unless csize == array.size
203
+ @bone[i] = array
204
+ self
205
+ end
206
+
207
+ def columns
208
+ (0...csize).collect{|j| column(j)}
209
+ end
210
+
211
+ def vectors
212
+ # vc = self.class.vector_type
213
+ vc = Algebra::Vector.create(ground, rsize)
214
+ columns.collect{|v| vc[*v]}
215
+ end
216
+
217
+ def column(j)
218
+ raise "size error" unless 0 <= j && j < csize
219
+ (0...rsize).collect{|i| @bone[i][j]}
220
+ end
221
+
222
+ def set_column(j, array)
223
+ raise "size error" unless 0 <= j && j < csize
224
+ raise "size error" unless rsize == array.size
225
+ (0...rsize).each{|i| @bone[i][j] = array[i]}
226
+ self
227
+ end
228
+
229
+
230
+ def sizes; self.class.sizes; end
231
+ def rsize; self.class.rsize; end
232
+ def csize; self.class.csize; end
233
+
234
+ def self.create(ground, rsize, csize)
235
+ if klass = matrices[[ground, rsize, csize]] #flyweight
236
+ klass
237
+ else
238
+ klass = super(ground)
239
+ klass.sysvar(:sizes, [rsize, csize])
240
+ klass.sysvar(:rsize, rsize)
241
+ klass.sysvar(:csize, csize)
242
+ matrices[[ground, rsize, csize]] = klass
243
+ klass
244
+ end
245
+ end
246
+
247
+ def self.transpose
248
+ if sizes == [csize, rsize]
249
+ self
250
+ else
251
+ superclass.create(ground, csize, rsize)
252
+ end
253
+ end
254
+
255
+ def to_s
256
+ @bone.inspect
257
+ end
258
+
259
+ def display(out = $stdout)
260
+ @bone.each do |col|
261
+ # out << col.inspect << "\n"
262
+ first = true
263
+ col.each do |x|
264
+ if first
265
+ first = false
266
+ else
267
+ out << ", "
268
+ end
269
+ out << sprintf("%3s", x)
270
+ end
271
+ out << "\n"
272
+ end
273
+ out
274
+ end
275
+
276
+ def display_by_latex(out = $stdout)
277
+ # out << "\\left(\n"
278
+ # out "\\begin{array}{" + "c" * @bone[0].size + "}\n"
279
+ @bone.each do |col|
280
+ # out << col.inspect << "\n"
281
+ first = true
282
+ col.each do |x|
283
+ if first
284
+ first = false
285
+ else
286
+ out << " & "
287
+ end
288
+ out << sprintf("%3s", x)
289
+ end
290
+ out << "\\\\\n"
291
+ end
292
+ # out << "\\end{array}"
293
+ # out << "\\right)"
294
+ out
295
+ end
296
+
297
+ def latex(env = "pmatrix")
298
+ s = ""
299
+ s << "\\begin{#{env}}\n" if env
300
+ s << display_by_latex("")
301
+ s << "\\end{#{env}}\n" if env
302
+ s
303
+ end
304
+
305
+ def inspect
306
+ "#{self.class}#{to_s}"
307
+ end
308
+
309
+ #check entries
310
+ def types
311
+ matrix{|i, j| self[i, j].class}
312
+ end
313
+
314
+ def self.zero
315
+ # new((0...rsize).collect{(0...csize).collect{ground.zero}})
316
+ matrix{ground.zero}
317
+ end
318
+
319
+ def self.regulate(x)
320
+ case x
321
+ when Vector, Covector, MatrixAlgebra #,SquareMatrix
322
+ x
323
+ else
324
+ nil
325
+ end
326
+ end
327
+
328
+ def coerce(other)#MatrixAlgebra
329
+ if x = ground.regulate(other)
330
+ [Algebra::Scalar.new(x), self]
331
+ else
332
+ super
333
+ end
334
+ end
335
+
336
+ def each(&b)
337
+ @bone.each(&b)
338
+ end
339
+
340
+ def self.each_index
341
+ (0...rsize).each do |i|
342
+ (0...csize).each do |j|
343
+ yield i, j
344
+ end
345
+ end
346
+ end
347
+
348
+ class << self
349
+ alias each_ij each_index
350
+ end
351
+
352
+ def each_index(&b)
353
+ self.class.each_index(&b)
354
+ end
355
+
356
+ alias each_ij each_index
357
+
358
+ def each_i
359
+ (0...rsize).each do |i|
360
+ yield i
361
+ end
362
+ end
363
+
364
+ def each_j
365
+ (0...csize).each do |j|
366
+ yield j
367
+ end
368
+ end
369
+
370
+ def each_row
371
+ (0...rsize).each do |i|
372
+ yield row(i)
373
+ end
374
+ end
375
+
376
+ def each_column
377
+ (0...rsize).each do |i|
378
+ yield column(i)
379
+ end
380
+ end
381
+
382
+ def ==(other)
383
+ super{ |o|
384
+ rais "type error" unless sizes == o.sizes
385
+ each_index do |i, j|
386
+ return false unless self[i, j] == o[i, j]
387
+ end
388
+ true
389
+ }
390
+ end
391
+
392
+ def self.collect_ij(m = rsize, n = csize)
393
+ (0...m).collect do |i|
394
+ (0...n).collect do |j|
395
+ yield(i, j)
396
+ end
397
+ end
398
+ end
399
+
400
+ def collect_ij(*x, &b); self.class.collect_ij(*x, &b); end
401
+
402
+ def self.matrix(m = rsize, n = csize)
403
+ new(collect_ij(m, n) {|i, j| yield i, j})
404
+ end
405
+
406
+ def matrix(m = rsize, n = csize)
407
+ self.class.matrix(m, n){|i, j| yield i, j}
408
+ end
409
+
410
+ def minor(i, j)
411
+ self.class.minor.matrix{|a, b|
412
+ self[a < i ? a : a+1, b < j ? b : b+1]
413
+ }
414
+ end
415
+
416
+ def cofactor(i, j)
417
+ minor(i, j).determinant * (-1)**(i+j)
418
+ end
419
+
420
+ def cofactor_matrix
421
+ self.transpose.matrix{|i, j| cofactor(j, i)}
422
+ end
423
+
424
+ alias adjoint cofactor_matrix
425
+
426
+ def self.collect_row(m = rsize)
427
+ new((0...m).collect{|i| yield i})
428
+ end
429
+
430
+ def collect_row(m = rsize)
431
+ self.class.collect_row(m){|i| yield i}
432
+ end
433
+
434
+ def self.collect_column(n = csize)
435
+ columns = (0...n).collect{|j| yield j}
436
+ matrix{|i, j| columns[j][i]}
437
+ end
438
+
439
+ def collect_column(n = csize)
440
+ self.class.collect_columns(n){|j| yield j}
441
+ end
442
+
443
+ def +(other)
444
+ super{ |o|
445
+ raise "type error" unless sizes == o.sizes
446
+ matrix{|i, j| self[i, j] + o[i, j]}
447
+ }
448
+ end
449
+
450
+ def -(other)
451
+ super{ |o|
452
+ raise "type error" unless sizes == o.sizes
453
+ matrix{|i, j| self[i, j] - o[i, j]}
454
+ }
455
+ end
456
+
457
+ def old_mul(other)
458
+ #without regulation
459
+ case other
460
+ when ground, Numeric # 1.is_a?(Rational) is false
461
+ matrix{|i, j| self[i, j]*other}
462
+ else
463
+ super{|o|
464
+ msize = csize
465
+ raise "type error" unless msize == o.rsize
466
+ (self.class * o.class).matrix(rsize, o.csize){|i, j|
467
+ (0...msize).sum(ground.zero){|k| self[i, k] * o[k, j]}
468
+ }
469
+ }
470
+ end
471
+ end
472
+
473
+ def *(other)
474
+ #without regulation!
475
+ if other.is_a?(ground) || other.is_a?(Numeric)#1.is_a?(Rational) is false
476
+ matrix{|i, j| self[i, j]*other}
477
+ elsif self.is_a?(other.ground)
478
+ other.matrix{|i, j| self*other[i, j]}
479
+ else
480
+ super{|o|
481
+ msize = csize
482
+ raise "type error" unless msize == o.rsize
483
+ (self.class * o.class).matrix(rsize, o.csize){|i, j|
484
+ (0...msize).sum(ground.zero){|k| self[i, k] * o[k, j]}
485
+ }
486
+ }
487
+ end
488
+ end
489
+
490
+ def /(other)
491
+ case other
492
+ when ground, Numeric
493
+ matrix{|i, j| self[i, j] / other}
494
+ else
495
+ raise "(/): unknown type #{other.class}"
496
+ end
497
+ end
498
+
499
+ def map
500
+ matrix{|i, j| yield(self[i, j])}
501
+ end
502
+
503
+ def transpose
504
+ self.class.transpose.matrix(csize, rsize){|i, j| self[j, i]}
505
+ end
506
+
507
+ alias t transpose
508
+
509
+ def dsum(other)
510
+ mytype = self.class.dsum(other.class)
511
+ mytype.matrix{|i, j|
512
+ if i < rsize
513
+ if j < csize
514
+ self[i, j]
515
+ else
516
+ other.ground.zero
517
+ end
518
+ else
519
+ if j < csize
520
+ ground.zero
521
+ else
522
+ other[i - rsize, j - csize]
523
+ end
524
+ end
525
+ }
526
+ end
527
+
528
+ def to_ary
529
+ to_a
530
+ end
531
+
532
+ def flatten
533
+ #'to_a' is defined in Enumerable
534
+ to_a.flatten
535
+ end
536
+
537
+ def diag
538
+ ed = []
539
+ size = rsize < csize ? rsize : csize
540
+ (0...size).each do |i|
541
+ break if self[i, i].zero?
542
+ ed.push self[i, i]
543
+ end
544
+ ed
545
+ end
546
+
547
+ def convert_to(mat_alg)
548
+ mat_alg.matrix{|i, j| mat_alg.ground.regulate(self[i, j])}
549
+ end
550
+
551
+ def self.convert_from(m)
552
+ matrix{|i, j| m[i, j].convert_to(ground)}
553
+ end
554
+
555
+ def self.**(m)
556
+ m.convert_to(self)
557
+ end
558
+ end
559
+
560
+ module InnerProductSpace
561
+ def inner_product(other)
562
+ ip = defined?(ground) ? ground.zero : first.zero
563
+ each_with_index do |x, i|
564
+ ip += x * other[i]
565
+ end
566
+ ip
567
+ end
568
+
569
+ def inner_product_complex(other)
570
+ inner_product(other.conjugate)
571
+ end
572
+
573
+ def norm2
574
+ inner_product(self)
575
+ end
576
+
577
+ def norm2_complex
578
+ inner_product_complex(self)
579
+ end
580
+ end
581
+
582
+ class Vector < MatrixAlgebra
583
+ include InnerProductSpace
584
+
585
+ Matrices = {}
586
+
587
+ def initialize(array, conv = false)
588
+ @bone0 = array
589
+ super(array.collect{|x| [x]}, conv)
590
+ end
591
+
592
+ def each
593
+ @bone0.each do |x|
594
+ yield x
595
+ end
596
+ end
597
+
598
+ def size; self.class.size; end
599
+
600
+ #def to_a
601
+ # column(0)
602
+ #end
603
+
604
+ def [](*x)
605
+ case x.size
606
+ when 1
607
+ super(x[0], 0)
608
+ when 2
609
+ super(*x)
610
+ else
611
+ raise "size of index be 1 or 2"
612
+ end
613
+ end
614
+
615
+ def self.create(ground, n)
616
+ klass = super(ground, n, 1)
617
+ klass.sysvar(:size, n)
618
+ klass
619
+ end
620
+
621
+ def transpose
622
+ Algebra::Covector.create(ground, size).new(to_a)
623
+ end
624
+
625
+ def self.vector(conv = false, &b)
626
+ new((0...size).collect(&b), conv)
627
+ end
628
+
629
+ def self.[](*a)
630
+ vector(true){|i| a[i]}
631
+ end
632
+
633
+ def self.matrix(r = size, s = 1)
634
+ vector{|i| yield(i, 0)}
635
+ end
636
+
637
+ def inspect
638
+ @bone0.inspect
639
+ end
640
+
641
+ def to_s
642
+ @bone0.inspect
643
+ end
644
+ end
645
+
646
+ class Covector < MatrixAlgebra
647
+ include InnerProductSpace
648
+
649
+ Matrices = {}
650
+
651
+ def initialize(array, conv = false)
652
+ @bone0 = array
653
+ super([array], conv)
654
+ end
655
+
656
+ def each
657
+ @bone0.each do |x|
658
+ yield x
659
+ end
660
+ end
661
+
662
+ def size; self.class.size; end
663
+
664
+ # def to_a
665
+ # row(0)
666
+ # end
667
+
668
+ def [](*x)
669
+ case x.size
670
+ when 1; super(0, x[0])
671
+ when 2; super(*x)
672
+ else
673
+ raise "size of index be 1 or 2"
674
+ end
675
+ end
676
+
677
+ def self.create(ground, n)
678
+ klass = super(ground, 1, n)
679
+ klass.sysvar(:size, n)
680
+ klass
681
+ end
682
+
683
+ def transpose
684
+ Algebra::Vector.create(ground, size).new(to_a)
685
+ end
686
+
687
+ def self.[](*a)
688
+ covector(true){|i| a[i]}
689
+ end
690
+
691
+ def self.covector(conv = false, &b)
692
+ new((0...size).collect(&b), true)
693
+ end
694
+
695
+ def self.matrix(r = 1, s = size)
696
+ covector{|j| yield(0, j)}
697
+ end
698
+
699
+ def inspect
700
+ @bone0.inspect
701
+ end
702
+
703
+ def to_s
704
+ super
705
+ end
706
+ end
707
+
708
+ class SquareMatrix < MatrixAlgebra
709
+ Matrices = {}
710
+
711
+ def self.unity
712
+ matrix{|i, j| i == j ? ground.unity : ground.zero }
713
+ end
714
+
715
+ def self.const(x)
716
+ matrix{|i, j| i == j ? ground.regulate(x) : ground.zero }
717
+ end
718
+
719
+ def const(x)
720
+ self.class.const(x)
721
+ end
722
+
723
+ def self.matrices
724
+ Matrices
725
+ end
726
+
727
+ def initialzie(array, conv = false)
728
+ super
729
+ end
730
+
731
+ def self.create(ground, n, m = nil)
732
+ if m && n != m
733
+ raise "type error to create SquareMatrix"
734
+ end
735
+ klass = super(ground, n, n)
736
+ klass.sysvar(:size, n)
737
+ klass
738
+ end
739
+
740
+ def size; self.class.size; end
741
+
742
+ def self.regulate(x)
743
+ if x.is_a? superclass #SquareMatrix
744
+ x
745
+ elsif y = ground.regulate(x)
746
+ const(y)
747
+ else
748
+ super
749
+ end
750
+ end
751
+
752
+ def self.determinant(aa)
753
+ r = create(Integer, aa.size)
754
+ m = r.new(aa)
755
+ m.determinant
756
+ end
757
+
758
+ class << self
759
+ alias det determinant
760
+ end
761
+
762
+ def /(other)
763
+ #It might be better to use regulate ...
764
+ case other
765
+ # when ground, Numeric
766
+ # matrix{|i, j| self[i, j] / other}
767
+ when self.class.superclass #SquareMatrix
768
+ self * other.inverse
769
+ else
770
+ super
771
+ end
772
+ end
773
+
774
+ def determinant
775
+ sum = ground.zero
776
+ perm do |idx|
777
+ product = ground.unity
778
+ idx.each_with_index do |i, j|
779
+ product *= self[i, j]
780
+ end
781
+ sum += product * sign(idx)
782
+ end
783
+ sum
784
+ end
785
+
786
+ alias determinant! determinant
787
+ alias det determinant
788
+
789
+ def inverse
790
+ #gaussian-elimination.rb
791
+ if ground.field? &&
792
+ (!ground.respond_to?(:reducible) || ground.reducible)
793
+ inverse_field
794
+ else
795
+ a = adjoint
796
+ d = determinant
797
+ unless d.unit?
798
+ warn("#{a}/#{d} may not be done.")
799
+ end
800
+ a / d
801
+ end
802
+ end
803
+
804
+ def sign(a)
805
+ n = a.size
806
+ a = a.dup
807
+ b = (0...n).collect{|i| a.index(i)}
808
+ s = 1
809
+ (0...(n-1)).each do |i|
810
+ if (j = a[i]) != i
811
+ a[b[i]], b[j], s = j, b[i], -s
812
+ end
813
+ end
814
+ s
815
+ end
816
+
817
+ def perm(n = size, stack = [])
818
+ (0...n).each do |x|
819
+ unless stack.include? x
820
+ stack.push x
821
+ if stack.size < n
822
+ perm(n, stack) do |y|; yield y; end
823
+ else
824
+ yield stack
825
+ end
826
+ stack.pop
827
+ end
828
+ end
829
+ end
830
+
831
+ def char_polynomial0(obj = "x")
832
+ require "algebra/polynomial"
833
+ a = Algebra.Polynomial(ground, obj)
834
+ k = Algebra.SquareMatrix(a, size)
835
+ (k.unity * a.var - self).determinant
836
+ # (k.unity * a.var - k.matrix{|i, j| self[i,j]}).determinant
837
+ end
838
+
839
+ def _char_matrix(mop)
840
+ # assume mop.ground.ground == self.ground
841
+ mop.unity * mop.ground.var - self
842
+ end
843
+
844
+ def char_matrix(polyring)
845
+ matrix_over_poly = Algebra.SquareMatrix(polyring, size)
846
+ _char_matrix(matrix_over_poly)
847
+ end
848
+
849
+ def char_polynomial(polyring)
850
+ matrix_over_poly = Algebra.SquareMatrix(polyring, size)
851
+ _char_matrix(matrix_over_poly).determinant
852
+ end
853
+ end
854
+
855
+ class Scalar # fake class for SCALAR * MATRIX
856
+ def initialize(x)
857
+ @value = x
858
+ end
859
+
860
+ def +(other)
861
+ case other
862
+ when Algebra::SquareMatrix
863
+ other.const(@value) + other
864
+ else
865
+ raise "Fail: Scalar(#{@value}) + #{other}"
866
+ end
867
+ end
868
+
869
+ def -(other)
870
+ case other
871
+ when Algebra::SquareMatrix
872
+ other.const(@value) - other
873
+ else
874
+ raise "Fail: Scalar(#{@value}) - #{other}"
875
+ end
876
+ end
877
+
878
+ def *(other)
879
+ case other
880
+ when Algebra::MatrixAlgebra
881
+ other.matrix{|i, j| @value * other[i, j]}
882
+ else
883
+ raise "Fail: Scalar(#{@value}) * #{other}"
884
+ end
885
+ end
886
+ end
887
+ end
888
+
889
+ if $0 == __FILE__
890
+ # include Algebra
891
+ M33 = Algebra.MatrixAlgebra(Integer, 3, 3)
892
+ M34 = Algebra.MatrixAlgebra(Integer, 3, 4)
893
+ a33 = [
894
+ [1, 1, 2],
895
+ [3, 4, 5],
896
+ [6, 7, 8]
897
+ ]
898
+ m0 = M33.new(a33)
899
+ m0[0, 0] = 0
900
+ m1 = M33[
901
+ [10, 11, 12],
902
+ [13, 14, 15],
903
+ [16, 17, 18]]
904
+ m2 = M34[[20, 21, 22, 23], [24, 25, 26, 27], [28, 29, 30, 31]]
905
+ p m0 + m1
906
+ p m0 * m0
907
+ p( (m0 * m0).t )
908
+ # m = m0 * m2
909
+ M43 = M34.transpose
910
+ p M34.sizes
911
+ p M43.sizes
912
+ M44 = M43 * M34
913
+ p m2.t * m2
914
+ p m0.dsum(m1).display
915
+
916
+
917
+ require "algebra/rational"
918
+
919
+ M3 = Algebra.SquareMatrix(Rational, 3)
920
+ # m3 = M3[
921
+ # [0, 1, 2],
922
+ # [3, 4, 5],
923
+ # [6, 7, 8]]
924
+
925
+ # require "algebra/polynomial"
926
+ # Px = Algebra.Polynomial(Rational, "x")
927
+ # require "algebra/polynomial"
928
+ # p f = m3.char_polynomial(Px)
929
+ end