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,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