algebra 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +53 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +28 -0
- data/LICENSE.txt +21 -0
- data/README-ja.txt +60 -0
- data/README.md +61 -0
- data/Rakefile +43 -0
- data/algebra.gemspec +33 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc-ja/README-ja.html +69 -0
- data/doc-ja/README-ja.rd +60 -0
- data/doc-ja/README.html +0 -0
- data/doc-ja/README.rd +0 -0
- data/doc-ja/algebra-ja.html +66 -0
- data/doc-ja/algebra-ja.rd +60 -0
- data/doc-ja/algebraic-equation-ja.html +36 -0
- data/doc-ja/algebraic-equation-ja.rd +26 -0
- data/doc-ja/algebraic-extension-field-ja.html +122 -0
- data/doc-ja/algebraic-extension-field-ja.rd +118 -0
- data/doc-ja/algebraic-parser-ja.html +87 -0
- data/doc-ja/algebraic-parser-ja.rd +95 -0
- data/doc-ja/changes.html +161 -0
- data/doc-ja/changes.rd +119 -0
- data/doc-ja/elementary-divisor-ja.html +56 -0
- data/doc-ja/elementary-divisor-ja.rd +45 -0
- data/doc-ja/euclidian-ring-ja.html +78 -0
- data/doc-ja/euclidian-ring-ja.rd +69 -0
- data/doc-ja/finite-group-ja.html +285 -0
- data/doc-ja/finite-group-ja.rd +276 -0
- data/doc-ja/finite-map-ja.html +224 -0
- data/doc-ja/finite-map-ja.rd +227 -0
- data/doc-ja/finite-set-ja.html +393 -0
- data/doc-ja/finite-set-ja.rd +408 -0
- data/doc-ja/index-ja.html +113 -0
- data/doc-ja/index-ja.rd +112 -0
- data/doc-ja/jordan-form-ja.html +106 -0
- data/doc-ja/jordan-form-ja.rd +99 -0
- data/doc-ja/localized-ring-ja.html +121 -0
- data/doc-ja/localized-ring-ja.rd +131 -0
- data/doc-ja/m-polynomial-ja.html +542 -0
- data/doc-ja/m-polynomial-ja.rd +596 -0
- data/doc-ja/matrix-algebra-ja.html +686 -0
- data/doc-ja/matrix-algebra-ja.rd +727 -0
- data/doc-ja/matrix-algebra-triplet-ja.html +124 -0
- data/doc-ja/matrix-algebra-triplet-ja.rd +129 -0
- data/doc-ja/permutation-group-ja.html +159 -0
- data/doc-ja/permutation-group-ja.rd +151 -0
- data/doc-ja/polynomial-converter-ja.html +64 -0
- data/doc-ja/polynomial-converter-ja.rd +54 -0
- data/doc-ja/polynomial-ja.html +446 -0
- data/doc-ja/polynomial-ja.rd +473 -0
- data/doc-ja/residue-class-ring-ja.html +112 -0
- data/doc-ja/residue-class-ring-ja.rd +113 -0
- data/doc-ja/sample-algebraic-equation01.rb.v.rd +11 -0
- data/doc-ja/sample-algebraic-equation02.rb.v.rd +11 -0
- data/doc-ja/sample-algebraic-root01.rb.v.rd +20 -0
- data/doc-ja/sample-algebraicfield01.rb.v.rd +26 -0
- data/doc-ja/sample-algebraicfield02.rb.v.rd +15 -0
- data/doc-ja/sample-cayleyhamilton01.rb.v.rd +14 -0
- data/doc-ja/sample-diagonalization01.rb.v.rd +48 -0
- data/doc-ja/sample-divmod01.rb.v.rd +17 -0
- data/doc-ja/sample-elementary-divisor01.rb.v.rd +48 -0
- data/doc-ja/sample-factorize01.rb.v.rd +11 -0
- data/doc-ja/sample-factorize02.rb.v.rd +13 -0
- data/doc-ja/sample-factorize03.rb.v.rd +14 -0
- data/doc-ja/sample-factorize04.rb.v.rd +14 -0
- data/doc-ja/sample-factorize05.rb.v.rd +53 -0
- data/doc-ja/sample-galois-group01.rb.v.rd +27 -0
- data/doc-ja/sample-gaussian-elimination01.rb.v.rd +19 -0
- data/doc-ja/sample-geometry01.rb.v.rd +33 -0
- data/doc-ja/sample-geometry02.rb.v.rd +34 -0
- data/doc-ja/sample-geometry03.rb.v.rd +45 -0
- data/doc-ja/sample-geometry04.rb.v.rd +33 -0
- data/doc-ja/sample-geometry07.rb.v.rd +62 -0
- data/doc-ja/sample-groebner01.rb.v.rd +13 -0
- data/doc-ja/sample-groebner02.rb.v.rd +18 -0
- data/doc-ja/sample-groebner03.rb.v.rd +19 -0
- data/doc-ja/sample-group01.rb.v.rd +21 -0
- data/doc-ja/sample-jordan-form01.rb.v.rd +56 -0
- data/doc-ja/sample-jordanform01.rb.v.rd +55 -0
- data/doc-ja/sample-lagrange-multiplier01.rb.v.rd +35 -0
- data/doc-ja/sample-m-factorize01.rb.v.rd +15 -0
- data/doc-ja/sample-m-factorize02.rb.v.rd +12 -0
- data/doc-ja/sample-m-polynomial01.rb.v.rd +10 -0
- data/doc-ja/sample-map01.rb.v.rd +9 -0
- data/doc-ja/sample-polynomial01.rb.v.rd +9 -0
- data/doc-ja/sample-polynomial02.rb.v.rd +11 -0
- data/doc-ja/sample-primefield01.rb.v.rd +13 -0
- data/doc-ja/sample-quotientfield01.rb.v.rd +11 -0
- data/doc-ja/sample-quotientfield02.rb.v.rd +18 -0
- data/doc-ja/sample-quotientfield03.rb.v.rd +16 -0
- data/doc-ja/sample-quotientfield04.rb.v.rd +16 -0
- data/doc-ja/sample-set01.rb.v.rd +18 -0
- data/doc-ja/sample-splitting-field01.rb.v.rd +19 -0
- data/doc-ja/samples-ja.html +885 -0
- data/doc-ja/samples-ja.rd +221 -0
- data/doc-ja/style.css +85 -0
- data/doc-ja/todo.html +20 -0
- data/doc-ja/todo.rd +9 -0
- data/lib/algebra.rb +36 -0
- data/lib/algebra/algebraic-equation.rb +56 -0
- data/lib/algebra/algebraic-extension-field.rb +135 -0
- data/lib/algebra/algebraic-parser.rb +160 -0
- data/lib/algebra/algebraic-system.rb +224 -0
- data/lib/algebra/annihilate.rb +52 -0
- data/lib/algebra/array-supplement.rb +53 -0
- data/lib/algebra/auto-require.rb +84 -0
- data/lib/algebra/chinese-rem-th.rb +135 -0
- data/lib/algebra/combinatorial.rb +145 -0
- data/lib/algebra/elementary-divisor.rb +193 -0
- data/lib/algebra/euclidian-ring.rb +161 -0
- data/lib/algebra/factors.rb +305 -0
- data/lib/algebra/finite-group.rb +374 -0
- data/lib/algebra/finite-map.rb +201 -0
- data/lib/algebra/finite-set.rb +456 -0
- data/lib/algebra/galois-group.rb +129 -0
- data/lib/algebra/gaussian-elimination.rb +385 -0
- data/lib/algebra/groebner-basis-coeff.rb +228 -0
- data/lib/algebra/groebner-basis.rb +197 -0
- data/lib/algebra/import-module-single-thread.rb +86 -0
- data/lib/algebra/import-module.rb +491 -0
- data/lib/algebra/jordan-form.rb +114 -0
- data/lib/algebra/linear-algebra.rb +143 -0
- data/lib/algebra/localized-ring.rb +294 -0
- data/lib/algebra/m-index.rb +282 -0
- data/lib/algebra/m-polynomial-factor-int.rb +186 -0
- data/lib/algebra/m-polynomial-factor-zp.rb +114 -0
- data/lib/algebra/m-polynomial-factor.rb +315 -0
- data/lib/algebra/m-polynomial-gcd.rb +40 -0
- data/lib/algebra/m-polynomial.rb +875 -0
- data/lib/algebra/matrix-algebra-triplet.rb +292 -0
- data/lib/algebra/matrix-algebra.rb +929 -0
- data/lib/algebra/numeric-supplement.rb +123 -0
- data/lib/algebra/permutation-group.rb +257 -0
- data/lib/algebra/polynomial-converter.rb +193 -0
- data/lib/algebra/polynomial-factor-alg.rb +148 -0
- data/lib/algebra/polynomial-factor-int.rb +252 -0
- data/lib/algebra/polynomial-factor-zp.rb +165 -0
- data/lib/algebra/polynomial-factor.rb +140 -0
- data/lib/algebra/polynomial.rb +592 -0
- data/lib/algebra/powers.rb +31 -0
- data/lib/algebra/prime-gen.rb +32 -0
- data/lib/algebra/rational.rb +81 -0
- data/lib/algebra/residue-class-ring.rb +219 -0
- data/lib/algebra/sets-system.rb +43 -0
- data/lib/algebra/splitting-field.rb +103 -0
- data/lib/algebra/version.rb +3 -0
- data/sample/Makefile +10 -0
- data/sample/do-testscripts.rb +100 -0
- data/sample/sample-algebraic-equation01.rb +6 -0
- data/sample/sample-algebraic-equation02.rb +6 -0
- data/sample/sample-algebraic-root01.rb +15 -0
- data/sample/sample-algebraicfield01.rb +21 -0
- data/sample/sample-algebraicfield02.rb +10 -0
- data/sample/sample-cayleyhamilton01.rb +9 -0
- data/sample/sample-diagonalization01.rb +43 -0
- data/sample/sample-divmod01.rb +12 -0
- data/sample/sample-elementary-divisor01.rb +43 -0
- data/sample/sample-factorize01.rb +6 -0
- data/sample/sample-factorize02.rb +8 -0
- data/sample/sample-factorize03.rb +9 -0
- data/sample/sample-factorize04.rb +9 -0
- data/sample/sample-factorize05.rb +48 -0
- data/sample/sample-galois-group01.rb +22 -0
- data/sample/sample-gaussian-elimination01.rb +14 -0
- data/sample/sample-geometry01.rb +28 -0
- data/sample/sample-geometry02.rb +29 -0
- data/sample/sample-geometry03.rb +40 -0
- data/sample/sample-geometry04.rb +28 -0
- data/sample/sample-geometry07.rb +58 -0
- data/sample/sample-groebner01.rb +8 -0
- data/sample/sample-groebner02.rb +13 -0
- data/sample/sample-groebner03.rb +14 -0
- data/sample/sample-group01.rb +16 -0
- data/sample/sample-jordan-form01.rb +51 -0
- data/sample/sample-lagrange-multiplier01.rb +30 -0
- data/sample/sample-m-factorize01.rb +10 -0
- data/sample/sample-m-factorize02.rb +7 -0
- data/sample/sample-m-polynomial01.rb +5 -0
- data/sample/sample-map01.rb +4 -0
- data/sample/sample-polynomial01.rb +4 -0
- data/sample/sample-polynomial02.rb +6 -0
- data/sample/sample-primefield01.rb +8 -0
- data/sample/sample-quotientfield01.rb +6 -0
- data/sample/sample-quotientfield02.rb +13 -0
- data/sample/sample-quotientfield03.rb +11 -0
- data/sample/sample-quotientfield04.rb +11 -0
- data/sample/sample-set01.rb +13 -0
- data/sample/sample-splitting-field01.rb +14 -0
- data/sample/test-00-cayley-hamilton.rb +76 -0
- data/sample/test-00-groebner-basis.rb +274 -0
- data/sample/test-00-polynomial-factor-alg.rb +89 -0
- data/sample/test-00.list +4 -0
- data/sample/time-trial.rb +65 -0
- 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
|