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,282 @@
1
+ # Multi-index class for MPolymial
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 2.00 (2002.02.04)
6
+
7
+ module Algebra
8
+ class MIndex
9
+ include Enumerable
10
+
11
+ module Lex
12
+ def <=>(other)
13
+ @body <=> other.to_a
14
+ end
15
+ end
16
+
17
+ module Grlex
18
+ def <=>(other)
19
+ s = (totdeg <=> other.totdeg)
20
+ return s unless s.zero?
21
+ @body <=> other.to_a
22
+ end
23
+ end
24
+
25
+ module Grevlex
26
+ def <=>(other)
27
+ s = (totdeg <=> other.totdeg)
28
+ return s unless s.zero?
29
+ n = [size, other.size].max
30
+ (n - 1).downto 0 do |i|
31
+ x = other[i] - self[i]
32
+ return x unless x.zero?
33
+ end
34
+ 0
35
+ end
36
+ end
37
+
38
+ module V_lex
39
+ def <=>(other)
40
+ # n = [size, other.size].max
41
+ # 0.upto (n-1) do |i|
42
+ V_ORDER.each do |i|
43
+ # x = self[V_ORDER[i]] - other[V_ORDER[i]]
44
+ x = self[i] - other[i]
45
+ return x unless x.zero?
46
+ end
47
+ # p [111111111, self, other]
48
+ 0
49
+ end
50
+ end
51
+
52
+ module V_grlex
53
+ def <=>(other)
54
+ s = (totdeg <=> other.totdeg)
55
+ return s unless s.zero?
56
+ # n = [size, other.size].max
57
+ # 0.upto (n-1) do |i|
58
+ V_ORDER.each do |i|
59
+ # x = self[V_ORDER[i]] - other[V_ORDER[i]]
60
+ x = self[i] - other[i]
61
+ return x unless x.zero?
62
+ end
63
+ 0
64
+ end
65
+ end
66
+
67
+ module V_grevlex
68
+ def <=>(other)
69
+ s = (totdeg <=> other.totdeg)
70
+ return s unless s.zero?
71
+ # n = [size, other.size].max
72
+ # (n-1).downto 0 do |i|
73
+ V_ORDER.reverse_each do |i|
74
+ # x = other[V_ORDER[i]] - self[V_ORDER[i]]
75
+ x = other[i] - self[i]
76
+ return x unless x.zero?
77
+ end
78
+ 0
79
+ end
80
+ end
81
+
82
+ def initialize(array = [])
83
+ @body = array
84
+ end
85
+
86
+ def to_a
87
+ @body
88
+ end
89
+
90
+ def empty?
91
+ @body.empty?
92
+ end
93
+
94
+ def size
95
+ @body.size
96
+ end
97
+
98
+ def each
99
+ @body.each do |x|
100
+ yield x
101
+ end
102
+ end
103
+
104
+ # def ==(other)
105
+ # @body == other.to_a
106
+ # end
107
+
108
+ def eql?(other)
109
+ @body.eql? other.to_a
110
+ end
111
+
112
+ def hash
113
+ @body.hash
114
+ end
115
+
116
+ Unity = new
117
+
118
+ def self.[](*ind)
119
+ new(ind)
120
+ end
121
+
122
+ def unity
123
+ Unity.dup
124
+ end
125
+
126
+ def unity?
127
+ self == Unity
128
+ end
129
+
130
+ def [](i)
131
+ @body[i] || 0
132
+ end
133
+
134
+ def []=(i, x)
135
+ k = (self[i] = x)
136
+ raise 'illegal operation' if totdeg == 0
137
+ k
138
+ end
139
+
140
+ def self.monomial(idx, height = 1)
141
+ ind0 = []
142
+ (0..idx).each do |i|
143
+ ind0.push(i == idx ? height : 0)
144
+ end
145
+ new(ind0)
146
+ end
147
+
148
+ def multideg
149
+ @body
150
+ end
151
+
152
+ def devide?(other)
153
+ each_with_index do |x, i|
154
+ return false if x > other[i]
155
+ end
156
+ true
157
+ end
158
+
159
+ def devide_or?(other0, other1)
160
+ each_with_index do |x, i|
161
+ return false if x > other0[i] || x > other1[i]
162
+ end
163
+ true
164
+ end
165
+
166
+ def prime_to?(other)
167
+ each_with_index do |x, i|
168
+ return false if x > 0 && other[i] > 0
169
+ end
170
+ true
171
+ end
172
+
173
+ def totdeg
174
+ s = 0
175
+ each { |n| s += n; }
176
+ s
177
+ end
178
+
179
+ def ==(other)
180
+ 0.upto [size, other.size].max - 1 do |i|
181
+ return false if self[i] != other[i]
182
+ end
183
+ true
184
+ end
185
+
186
+ def +(other)
187
+ self.class.new((0...[size, other.size].max).collect do |i|
188
+ self[i] + other[i]
189
+ end)
190
+ end
191
+
192
+ def -(other)
193
+ self.class.new((0...[size, other.size].max).collect do |i|
194
+ x = self[i] - other[i]
195
+ raise "#{self} is not devided by #{other}" if x < 0
196
+ x
197
+ end).compact!
198
+ end
199
+
200
+ def annihilate(at)
201
+ self - self.class.monomial(at, self[at])
202
+ end
203
+
204
+ def lcm(other)
205
+ self.class.new((0...[size, other.size].max).collect do |i|
206
+ [self[i], other[i]].max
207
+ end)
208
+ end
209
+
210
+ def gcm(other)
211
+ self.class.new((0...[size, other.size].max).collect do |i|
212
+ [self[i], other[i]].min
213
+ end).compact!
214
+ end
215
+
216
+ def compact! # be careful, when this index is used plural places!!
217
+ i = size - 1
218
+ i -= 1 while i >= 0 && self[i].zero?
219
+ @body.slice!((i + 1)..-1) if i < size - 1
220
+ self
221
+ end
222
+
223
+ def compact # more safe
224
+ dup.compact!
225
+ end
226
+
227
+ def dup
228
+ self.class.new(@body)
229
+ end
230
+
231
+ def to_s!(vars = nil, pr = nil, po = nil)
232
+ return @body.inspect unless vars
233
+ a = ''
234
+ each_with_index do |n, i|
235
+ case n
236
+ when 0
237
+ else
238
+ # u = n == 1 ? vars[i].to_s : vars[i].to_s + "#{po}#{n}"
239
+ u = if n == 1
240
+ vars[i].to_s
241
+ elsif /^\}/ =~ po
242
+ "{#{vars[i]}#{po}#{n}"
243
+ else
244
+ "#{vars[i]}#{po}#{n}"
245
+ end
246
+ a.concat(a.empty? ? u : "#{pr}#{u}")
247
+ end
248
+ end
249
+ a
250
+ end
251
+
252
+ def to_s(var = nil, pr = nil, po = nil)
253
+ $DEBUG ? @body.inspect.gsub(/\s+/, '') : to_s!(var, pr, po)
254
+ end
255
+
256
+ def inspect(var = nil, po = nil)
257
+ to_s(var, po)
258
+ end
259
+
260
+ def self.set_ord(ord)
261
+ mod = get_module(ord)
262
+ adopt_module(mod)
263
+ end
264
+
265
+ def self.set_V_ORDER(v_ord)
266
+ remove_const 'V_ORDER' if const_defined? 'V_ORDER'
267
+ const_set('V_ORDER', v_ord)
268
+ end
269
+
270
+ def self.set_v_ord(ord, v_ord)
271
+ set_V_ORDER(v_ord)
272
+ vord = get_module(ord, v_ord)
273
+ adopt_module(vord)
274
+ end
275
+
276
+ def self.get_module(ord, v_ord = nil)
277
+ ord = ord.id2name
278
+ ord = 'V_' + ord if v_ord
279
+ eval(ord.capitalize)
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,186 @@
1
+ # Factorization of Multivariate polynomial / Integer, Rational
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.0 (2001.09.14)
6
+
7
+ require 'algebra/m-polynomial'
8
+ require 'algebra/polynomial'
9
+ require 'algebra/polynomial-factor'
10
+ require 'algebra/residue-class-ring'
11
+ require 'algebra/rational'
12
+ require 'algebra/chinese-rem-th'
13
+ require 'algebra/m-polynomial-gcd'
14
+ # require "algebra/combinatorial"
15
+
16
+ module Algebra
17
+ module MPolynomialFactorization
18
+ include PolynomialFactorization::Z
19
+ # include PolynomialFactorization::Q
20
+
21
+ def factorize_int(an = 0)
22
+ return Factors.new([[self, 1]]) if constant?
23
+ f = self
24
+ f = f.sqfree if an == 0
25
+ an += 1 while f.deg_at(an) <= 0
26
+ f = f.pp(an)
27
+ lc_of_f = f.lc_at(an)
28
+ f = f.monic_int(an)
29
+ facts = f._factorize(an)
30
+ facts = facts.map! do |f2|
31
+ f3 = f2.project(self.class) { |c, j| c * lc_of_f**j[an] }
32
+ f3.pp(an)
33
+ end
34
+ facts = facts.fact_all_u(self)
35
+ facts.mcorrect_lc!(self, an) do |fac|
36
+ fac.factorize_int(an + 1)
37
+ end
38
+ facts
39
+ end
40
+
41
+ def sqfree
42
+ _sqfree
43
+ end
44
+
45
+ def gelfond_bound(char)
46
+ n = vars.size
47
+ ds = (0...n).collect { 0 }
48
+ c0 = 0
49
+ each do |ind, c|
50
+ next if c.zero?
51
+ ind.each_with_index do |d0, i|
52
+ ds[i] = d0 if d0 > ds[i]
53
+ end
54
+ c0 = c.abs if c.abs > c0
55
+ end
56
+ tot = 0
57
+ ds.each do |x|
58
+ tot += x
59
+ end
60
+ b = Math::E**tot * c0
61
+ l = 0
62
+ s = 1
63
+ while s <= 2 * b
64
+ s *= char
65
+ l += 1
66
+ end
67
+ l
68
+ end
69
+
70
+ # def hensel_lift_int(g0, f0, char, height)
71
+ def hensel_lift_int(g0, f0, char, height, where)
72
+ # self in MPolynomial/int
73
+ # g0 in Polyomial/Z, candidate of factor of f0
74
+ # f0 in Polyomial/Z, one variable reduction of self
75
+
76
+ pheight = gelfond_bound(char)
77
+
78
+ fk = _hensel_lift(g0, f0, char, height, where) do |ha, ary, cofacts|
79
+ # fk = _hensel_lift(g0, f0, char, height) {|ha, ary, cofacts|
80
+ decompose_on_cofactors_p_adic(ha, ary, cofacts, char, pheight)
81
+ end
82
+ mod = char**pheight
83
+ g = centorize(fk[0], mod)
84
+ h = centorize(fk[1], mod)
85
+
86
+ r = self - g * h
87
+ return [g, h] if r.zero?
88
+
89
+ nil
90
+ end
91
+
92
+ def centorize(f, n)
93
+ half = n / 2
94
+ # f.class.new(*f.collect{|c| c > half ? c - n : c })
95
+ f.project(f.class) do |c, _ind|
96
+ c = c % n
97
+ c > half ? c - n : c
98
+ end
99
+ end
100
+
101
+ module Q
102
+ def contQ
103
+ ns = collect { |_ind, q| q.numerator }
104
+ ds = collect { |_ind, q| q.denominator }
105
+ n = ns.first.gcd_all(* ns[1..-1])
106
+ d = ds.first.lcm_all(* ds[1..-1])
107
+ # if ground == Rational #in 1.8.0, Rational.new is private.
108
+ # ground.new!(n, d)
109
+ # else
110
+ # raise "unknown gound type #{ground}" #20030606
111
+ # ground.new(n, d)
112
+ # end
113
+ if ground == Rational
114
+ Rational(n, d)
115
+ else
116
+ ground.new(n, d)
117
+ end
118
+ end
119
+
120
+ def ppQ(ring)
121
+ (self / contQ).project(ring) { |c, _j| c.to_i }
122
+ end
123
+
124
+ def factorize_rational
125
+ pz = Algebra.MPolynomial(Integer)
126
+ pz.vars(*self.class.variables)
127
+ fz = ppQ(pz)
128
+ a = fz.factorize_int
129
+
130
+ # ground == Rational, ground.ground == Integer
131
+ u = ground.ground.unity
132
+ b = a.collect do |f, i|
133
+ [f.project(self.class) do |c, _j|
134
+ if ground == Rational
135
+ Rational(c, u)
136
+ else
137
+ ground.new(c, u)
138
+ end
139
+ end, i]
140
+ end
141
+ contQ == ground.unity ? b : b.unshift([self.class.const(contQ), 1])
142
+ end
143
+ end
144
+ include Q
145
+ end
146
+ end
147
+
148
+ if __FILE__ == $PROGRAM_NAME
149
+ require 'algebra/m-polynomial-factor'
150
+ include Algebra
151
+
152
+ def test(f)
153
+ print "#{f}\n => \n"
154
+ a = f.factorize_int
155
+ sw = (f == a.pi)
156
+ puts "#{a.inspect}, #{sw}"
157
+ raise unless sw
158
+ end
159
+
160
+ # P = MPolynomial(Rational)
161
+ P = MPolynomial(Integer)
162
+ PS = Polynomial(Integer, 't')
163
+ x, y, z = P.vars('xyz')
164
+ # x, y, z, t = P.vars("xyzt")
165
+
166
+ # f = (x + y + z)**3*(2*z + x)**2*(4*z + y)
167
+ # g = (x + y + z)*(2*z + x)*(4*z + y)
168
+ # p f
169
+ # fs = f.sqfree
170
+ # p fs
171
+ # p g == fs
172
+
173
+ fs = [
174
+ x**3 + y**3 + z**3 - 3 * x * y * z,
175
+ x**2 + (-z**2 - y * z + y + z + 2) * x + (y * z**3 - z**3 - y**2 * z - y * z + 2 * z),
176
+ (x + y) * (x + z**2 + 1) * (x**2 + y * z + 1),
177
+ (x + y) * (x + y**2 + z**2 + 1 + y * z) * (x**2 + z + y * 3),
178
+ (x + y) * (x + z + y * 3) * (x + 1),
179
+ (x + y)**2 * (x + z)
180
+ # (t + x)*(t + y)*(t + z),
181
+ ]
182
+
183
+ fs.each do |f|
184
+ test(f)
185
+ end
186
+ end