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,161 @@
1
+ # G.C.D. and something for Euclidian ring (equipping 'divmod' and 'zero?')
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.01 (2001.03.22)
6
+
7
+ require "algebra/algebraic-system"
8
+ module Algebra
9
+ module EuclidianRing
10
+ def lcm(b)
11
+ self * b / gcd(b)
12
+ end
13
+
14
+ def lcm_all(*a)
15
+ t = self
16
+ a.each do |x|
17
+ t = t.lcm(x)
18
+ end
19
+ t
20
+ end
21
+
22
+ def gcd3(b)
23
+ x, y = self, b
24
+ until y.zero?
25
+ _q, r = x.divmod y
26
+ x, y = y, r
27
+ end
28
+ x
29
+ end
30
+
31
+ def gcd(n)
32
+ m = self
33
+ while n != 0
34
+ m %= n
35
+ tmp = m; m = n; n = tmp
36
+ end
37
+ m
38
+ end
39
+
40
+ def gcd_all(*a)
41
+ t = self
42
+ a.each do |x|
43
+ t = t.gcd(x)
44
+ end
45
+ t
46
+ end
47
+
48
+ def gcd_ext(g)
49
+ h, s = self, g
50
+ a, b = self.class.unity, self.class.zero
51
+ c, d = self.class.zero, self.class.unity
52
+ loop do
53
+ q, r = h.divmod s
54
+ return [s, c, d] if r.zero?
55
+ h, s = s, r # r == h - q * s
56
+ a, c = c, a - q * c
57
+ b, d = d, b - q * d
58
+ end
59
+ end
60
+
61
+ alias gcd_coeff gcd_ext
62
+
63
+ def gcd_coeff0(b)
64
+ if b.zero?
65
+ [self, unity, zero]
66
+ else
67
+ q, r = divmod b
68
+ d, x, y = b.gcd_coeff(r)
69
+ [d, y, x - y * q]
70
+ end
71
+ end
72
+
73
+ def gcd_coeff_all(*a0)
74
+ return [self, self] if a0.empty?
75
+ t, *a = a0
76
+ d, x, y = gcd_ext(t)
77
+ r = [x, y]
78
+ a.each do |u|
79
+ d, x, y = d.gcd_coeff(u)
80
+ r = r.collect{|v| x*v} + [y]
81
+ end
82
+ [d] + r
83
+ end
84
+
85
+ alias gcd_ext_all gcd_coeff_all
86
+
87
+ def pgcd(b)
88
+ x, y = self, b
89
+ until y.zero?
90
+ _q, r = x.pdivmod y
91
+ x, y = y, r
92
+ end
93
+ x
94
+ end
95
+
96
+ def gcd_rec(b)
97
+ return self if b.zero?
98
+ return b if zero?
99
+ if is_a?(Polynomial) && !ground.field?
100
+ ac, ap = cont_pp
101
+ bc, bp = b.cont_pp
102
+ c = ac.gcd_rec(bc)
103
+ x, y = ap, bp
104
+ until y.zero?
105
+ q, r = x.pdivmod y
106
+ x, y = y, r
107
+ end
108
+ x.pp * c
109
+ else
110
+ x, y = self, b
111
+ until y.zero?
112
+ q, r = x.pdivmod y
113
+ x, y = y, r
114
+ end
115
+ x
116
+ end
117
+ end
118
+
119
+ def cont
120
+ t = nil
121
+ each do |x|
122
+ break if t && t.unit?
123
+ t = t ? t.gcd_rec(x) : x
124
+ end
125
+ t ? t : self
126
+ end
127
+
128
+ def pp; self / cont; end
129
+ def cont_pp; [c = cont, self / c]; end
130
+ end
131
+ end
132
+
133
+ class Integer < Numeric
134
+ include Algebra::EuclidianRing
135
+ end
136
+
137
+ class Rational < Numeric
138
+ include Algebra::EuclidianRing
139
+ end
140
+
141
+ if $0 == __FILE__
142
+ include Algebra
143
+ a, b = 108, 221
144
+ d, x, y = a.gcd_coeff(b)
145
+ puts "#{x}*#{a} + #{y}*#{b} = #{x * a + y * b} = #{d}"
146
+ a, b, c, e = 36, 126, 81, 12
147
+ p a.gcd_all(b, c, e)
148
+ d, x, y, z, w = a.gcd_coeff_all(b, c, e)
149
+ p d == x*a + y*b + z*c + w*e
150
+ puts "#{d} == #{x}*#{a} + #{y}*#{b} + #{z}*#{c} + #{w}*#{e}"
151
+
152
+ require "algebra/polynomial"
153
+ require "algebra/residue-class-ring"
154
+ Z7 = ResidueClassRing(Integer, 7)
155
+ # P = Polynomial(Z7, "x", "y")
156
+ P = Polynomial(Integer, "x", "y")
157
+ x, y = P.vars
158
+ f = 6*(x + 1)*(x + 2)*(y - 1)* (y + 2)
159
+ g = 9*(x + 1)*(x - 3)*(y - 1)* (y - 1)
160
+ p [f, g, f.gcd_rec(g)]
161
+ end
@@ -0,0 +1,305 @@
1
+ # Expression of Divisors
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.1 (2001.08.12)
6
+
7
+ module Algebra
8
+ class Factors
9
+ include Enumerable
10
+
11
+ def self.[](*a)
12
+ fact = new
13
+ a.each do |x|
14
+ fact.multiply(x)
15
+ end
16
+ fact
17
+ end
18
+ def self.mk(*a)
19
+ k = 0
20
+ b = []
21
+ while k < a.size
22
+ f = a[k]; k += 1
23
+ i = a[k]; k += 1
24
+ raise "parameter error (#{i})" unless i.is_a? Integer
25
+ b.push [f, i]
26
+ end
27
+ new(b)
28
+ end
29
+ def self.seki(a)
30
+ k = a.first
31
+ a[1..-1].each do |m|
32
+ k *= m
33
+ end
34
+ k
35
+ end
36
+ def initialize(array = [])
37
+ @bone = array
38
+ end
39
+ def dup; self.class.new(@bone.collect{|f, i| [f, i]}); end
40
+ def to_a; @bone; end
41
+ alias to_ary to_a
42
+ def each(&b); @bone.each(&b); end
43
+ def size; @bone.size; end
44
+ def shift; @bone.shift; end
45
+ def fact_size;
46
+ n = 0
47
+ each do |f, i|; n += i; end
48
+ n
49
+ end
50
+ def fact(i); @bone[i].first; end
51
+ def empty?; @bone.empty?; end
52
+ def head; @bone.first; end
53
+ def tail; self.class.new(@bone[1..-1]); end
54
+ def push(other); @bone.push other; self; end
55
+ def unshift(other); @bone.unshift(other); self; end
56
+ def collect(&b); self.class.new(@bone.collect(&b)); end
57
+ def map(&b); self.class.new(@bone.collect{|f, i| [yield(f), i]}); end
58
+ def collect!(&b); @bone.collect!(&b); self; end
59
+ def map!(&b); @bone.collect!{|f, i| [yield(f), i]}; self; end
60
+
61
+ def normalize!
62
+ c = nil
63
+ @bone.delete_if do |fact|
64
+ f, i = fact
65
+ if f.respond_to?(:constant?) and f.constant?
66
+ c and c *= f**i or c = f**i
67
+ true
68
+ end
69
+ end
70
+ if c
71
+ unless c.respond_to?(:unity?) && c.unity? && @bone.size > 0
72
+ @bone.unshift [c, 1]
73
+ end
74
+ end
75
+ self
76
+ end
77
+
78
+ def multiply(other, n = 1)
79
+ flag = false
80
+ @bone.each do |fact|
81
+ f, _i = fact
82
+ if f == other
83
+ fact[1] = fact[1]+ 1
84
+ flag = true
85
+ break
86
+ end
87
+ end
88
+ @bone.push [other, n] unless flag
89
+ normalize!
90
+ self
91
+ end
92
+
93
+ def gcd(other)
94
+ bone = []
95
+ @bone.each do |f, n|
96
+ i = n
97
+ until i == 0 || (other % [f ** i]).zero?
98
+ i -= 1
99
+ end
100
+ bone.push [f, i]
101
+ end
102
+ self.class.new(bone)
103
+ end
104
+
105
+ def concat(facts)
106
+ facts.each do |f, i|
107
+ multiply f, i
108
+ end
109
+ self
110
+ end
111
+
112
+ def *(o)
113
+ case o
114
+ when self.class
115
+ dup.concat(o)
116
+ else
117
+ #self.class.new(dup.multiply(o).to_a)
118
+ dup.multiply(o)
119
+ end
120
+ end
121
+
122
+ alias << multiply
123
+
124
+ def **(n)
125
+ fac = self.class.new
126
+ n.times do
127
+ fac *= self
128
+ end
129
+ fac
130
+ end
131
+
132
+ def pi
133
+ x = 1
134
+ @bone.each do |f_i|
135
+ f, i = f_i
136
+ if i
137
+ x *= f**i
138
+ else
139
+ x *= f
140
+ end
141
+ end
142
+ x
143
+ end
144
+
145
+ def ==(fact)
146
+ if pi == fact.pi
147
+ # flag = false
148
+ @bone.each do |f, i|
149
+ fact.each do |g, j|
150
+ if f == g || f == -g # this will be improved.
151
+ unless i == j
152
+ return false
153
+ end
154
+ end
155
+ end
156
+ end
157
+ true
158
+ else
159
+ false
160
+ end
161
+ end
162
+
163
+ def to_s
164
+ return "1" if @bone.empty?
165
+ a, b = @bone.size == 1 && @bone.first.last == 1? ["", ""] : ["(", ")"]
166
+ @bone.collect{|x|
167
+ "#{a}#{x.first}#{b}" + (x.last > 1 ? "^#{x.last}" : "")
168
+ }.join("")
169
+ end
170
+ alias inspect to_s
171
+
172
+ def each_product0 #create non trivial powers
173
+ if size > 0
174
+ fact0, _e0 = head
175
+ yield fact0
176
+ tail.each_product do |fact, e|
177
+ yield fact
178
+ end
179
+ tail.each_product do |fact, e|
180
+ yield fact0*fact # e is ignored
181
+ end
182
+ end
183
+ end
184
+
185
+ def each_product #create non trivial powers
186
+ idx0 = (0...size).to_a
187
+ indices = []
188
+ idx0.each do |i|
189
+ break if i >= size
190
+ indices.push [idx0[i...size], [i], fact(i)]
191
+ end
192
+
193
+ avoid = []
194
+ until indices.empty?
195
+ idx, rdx, f = indices.shift
196
+ # i = idx.first
197
+ next if avoid.find{|x| !(rdx & x).empty? }
198
+ #print rdx.inspect + " : "
199
+ r = yield(f)
200
+ if r
201
+ avoid.push rdx
202
+ next
203
+ end
204
+ idx.each_index do |k|
205
+ if k > 0 and k < idx.size
206
+ idx1 = idx[k..-1]
207
+ rdx1 = rdx + [idx[k]]
208
+ next if avoid.find{|x| !(rdx1 & x).empty?}
209
+ f1 = f * fact(idx[k])
210
+ indices.push [idx1, rdx1, f1]
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ def fact_all(f)
217
+ facts = self.class.new
218
+ each do |g, e|
219
+ next if e <= 0
220
+ i = 0
221
+ loop do
222
+ q, r = f.divmod_ED g
223
+ if r.zero?
224
+ f = q
225
+ i += 1
226
+ else
227
+ facts.push [g, i]
228
+ break
229
+ end
230
+ end
231
+ end
232
+ facts
233
+ end
234
+
235
+ def fact_all_u(f)
236
+ facts = self.class.new
237
+ each do |g, e|
238
+ next if e <= 0
239
+ next if g.constant?
240
+ i = 0
241
+ loop do
242
+ q, r = f.divmod g
243
+ if r.zero?
244
+ f = q.first
245
+ i += 1
246
+ else
247
+ facts.push [g, i]
248
+ break
249
+ end
250
+ end
251
+ end
252
+ facts
253
+ end
254
+
255
+ def correct_lc!(f)
256
+ k = f.ground.unity
257
+ each_with_index do |(g, i), j|
258
+ glc = g.lc
259
+ if glc != glc.unity && glc.unit?
260
+ @bone[j] = [g/glc, i]
261
+ else
262
+ k *= glc ** i
263
+ end
264
+ end
265
+ m = f.lc / k
266
+ unless m == f.ground.unity
267
+ unshift([m*f.unity, 1])
268
+ end
269
+ self
270
+ end
271
+
272
+ def mcorrect_lc!(f, an)
273
+ # k = f.ground.unity
274
+ k = f.unity
275
+ each_with_index do |(g, i), j|
276
+ glc = g.lc_at(an)
277
+ if glc.unit? && glc != glc.unity
278
+ @bone[j] = [g/glc, i]
279
+ else
280
+ k *= glc ** i
281
+ end
282
+ end
283
+ m = f.lc_at(an).divmod(k).first.first
284
+ unless m == f.ground.unity
285
+ concat yield(m)
286
+ end
287
+ self
288
+ end
289
+ end
290
+ end
291
+
292
+ if $0 == __FILE__
293
+ include Algebra
294
+ p Factors.new([[2, 2], [3, 2], [5, 2]]).pi == (2*3*5)**2
295
+
296
+ facts = Factors.new
297
+ facts << 2 << 3 << 5 << 7 << 11 << 13
298
+ k = 0
299
+ facts.each_product do |x|
300
+ k += 1
301
+ p x
302
+ x == 21
303
+ end
304
+ p k
305
+ end