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,228 @@
|
|
1
|
+
# Groebner basis module (with coeffitients)
|
2
|
+
#
|
3
|
+
# by Shin-ichiro Hara
|
4
|
+
#
|
5
|
+
# Version 1.2 (2001.04.03)
|
6
|
+
|
7
|
+
module Algebra
|
8
|
+
module Groebner
|
9
|
+
def S_pair_coeff(other)
|
10
|
+
x = lm.lcm(other.lm)
|
11
|
+
a = x / lt
|
12
|
+
b = x / other.lt
|
13
|
+
y = a * rt - b * other.rt
|
14
|
+
[y, a, -b]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.basis_coeff_132D(g)
|
18
|
+
gbasis = g.dup
|
19
|
+
n0 = g.size
|
20
|
+
# coeff = (0...n0).collect{|k| [0]*k+[1]+[0]*(n0-k-1)}
|
21
|
+
zero = f.first.zero
|
22
|
+
unity = f.first.unity
|
23
|
+
coeff = (0...n0).collect { |k| [zero] * k + [unity] + [zero] * (n0 - k - 1) }
|
24
|
+
pairs = []
|
25
|
+
g.each_pair_with_index do |x, y, i, j|
|
26
|
+
pairs.push [x, y, i, j]
|
27
|
+
end
|
28
|
+
while pair = pairs.shift
|
29
|
+
x, y, i, j = pair
|
30
|
+
t, a, b = x.S_pair_coeff(y)
|
31
|
+
q, s = t.divmod(*gbasis)
|
32
|
+
next if s.zero?
|
33
|
+
n1 = gbasis.size
|
34
|
+
gbasis.each_with_index { |z, k| pairs.push([z, s, k, n1]) }
|
35
|
+
u = (0...n0).collect do |k|
|
36
|
+
sum = 0
|
37
|
+
(0...gbasis.size).each do |m|
|
38
|
+
sum += (m == i ? a - q[m] : (m == j ? b - q[m] : -q[m])) * coeff[m][k]
|
39
|
+
end
|
40
|
+
sum
|
41
|
+
end
|
42
|
+
coeff.push u
|
43
|
+
gbasis.push s
|
44
|
+
end
|
45
|
+
[coeff, gbasis]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.basis_coeff_159A(f)
|
49
|
+
n0 = f.size
|
50
|
+
glm = f.collect(&:lm)
|
51
|
+
# fc = (0...n0).collect{|k| [0]*k+[1]+[0]*(n0-k-1)}
|
52
|
+
zero = f.first.zero
|
53
|
+
unity = f.first.unity
|
54
|
+
fc = (0...n0).collect { |k| [zero] * k + [unity] + [zero] * (n0 - k - 1) }
|
55
|
+
|
56
|
+
indexes = (0...n0).sort { |i, j| glm[i] <=> glm[j] }
|
57
|
+
glm = glm.values_at(*indexes)
|
58
|
+
gbasis = f.values_at(*indexes)
|
59
|
+
coeff = fc.values_at(*indexes)
|
60
|
+
|
61
|
+
pairs = []
|
62
|
+
(0...n0).to_a.each_pair do |i, j|
|
63
|
+
pairs.push [i, j]
|
64
|
+
end
|
65
|
+
|
66
|
+
until pairs.empty?
|
67
|
+
i, j = pairs.first
|
68
|
+
if !glm[i].prime_to?(glm[j]) && !_ct(glm, pairs, i, j)
|
69
|
+
t, a, b = gbasis[i].S_pair_coeff(gbasis[j])
|
70
|
+
q, s = t.divmod(*gbasis)
|
71
|
+
unless s.zero?
|
72
|
+
0.upto glm.size - 1 do |k|
|
73
|
+
pairs.push [k, glm.size]
|
74
|
+
end
|
75
|
+
u = (0...n0).collect do |k|
|
76
|
+
sum = 0
|
77
|
+
(0...gbasis.size).each do |m|
|
78
|
+
sum += (m == i ? a - q[m] : (m == j ? b - q[m] : -q[m])) * coeff[m][k]
|
79
|
+
end
|
80
|
+
sum
|
81
|
+
end
|
82
|
+
coeff.push u
|
83
|
+
gbasis.push s
|
84
|
+
glm.push s.lm
|
85
|
+
end
|
86
|
+
end
|
87
|
+
pairs.shift
|
88
|
+
end
|
89
|
+
|
90
|
+
[coeff, gbasis]
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.minimal_basis_coeff(coeff, gbasis)
|
94
|
+
glm = gbasis.collect(&:lm)
|
95
|
+
indexes = (0...gbasis.size).sort { |i, j| glm[j] <=> glm[i] }
|
96
|
+
indexes.each_with_index do |i, s|
|
97
|
+
(s + 1).upto indexes.size - 1 do |k|
|
98
|
+
j = indexes[k]
|
99
|
+
if glm[j].divide? glm[i]
|
100
|
+
indexes[s] = nil
|
101
|
+
break
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
indexes.compact!
|
106
|
+
b = gbasis.values_at(*indexes)
|
107
|
+
c = coeff.values_at(*indexes)
|
108
|
+
[c, b]
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.reduced_basis_coeff(coeff, gbasis)
|
112
|
+
gbasis.each_with_index do |x, i|
|
113
|
+
(g = gbasis.dup).delete_at(i)
|
114
|
+
q, gbasis[i] = x.divmod(*g)
|
115
|
+
coeff[i] = (0...coeff[i].size).collect do |k|
|
116
|
+
sum = 0
|
117
|
+
(0...gbasis.size).each do |m|
|
118
|
+
d = (m < i ? -q[m] : m == i ? 1 : -q[m - 1])
|
119
|
+
sum += d * coeff[m][k]
|
120
|
+
end
|
121
|
+
sum
|
122
|
+
end
|
123
|
+
end
|
124
|
+
gbasis.each_with_index do |x, i|
|
125
|
+
c = x.lc
|
126
|
+
coeff[i].collect! { |v| v / c }
|
127
|
+
gbasis[i] = x / c
|
128
|
+
end
|
129
|
+
[coeff, gbasis]
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.basis_coeff(g)
|
133
|
+
# coeff, gbasis = basis_coeff_132D(g)
|
134
|
+
coeff, gbasis = basis_coeff_159A(g)
|
135
|
+
coeff, gbasis = minimal_basis_coeff(coeff, gbasis)
|
136
|
+
coeff, gbasis = reduced_basis_coeff(coeff, gbasis)
|
137
|
+
ind = (0...gbasis.size).to_a
|
138
|
+
ind.sort! { |i, j| gbasis[j] <=> gbasis[i] }
|
139
|
+
[coeff.values_at(*ind), gbasis.values_at(*ind)]
|
140
|
+
end
|
141
|
+
|
142
|
+
def divmod_s0(*f)
|
143
|
+
coeff, gbasis = Groebner.basis_coeff(f)
|
144
|
+
q, r = divmod(*gbasis)
|
145
|
+
q0 = (0...f.size).collect do |i|
|
146
|
+
sum = 0
|
147
|
+
(0...q.size).each do |j|
|
148
|
+
sum += q[j] * coeff[j][i]
|
149
|
+
end
|
150
|
+
sum
|
151
|
+
end
|
152
|
+
[q0, r]
|
153
|
+
end
|
154
|
+
|
155
|
+
def divmod_s(*f)
|
156
|
+
cg = Groebner.basis_coeff(f)
|
157
|
+
div_cg(f, cg)
|
158
|
+
end
|
159
|
+
|
160
|
+
def div_cg(f, cg = nil)
|
161
|
+
cg = Groebner.basis_coeff(f) unless cg
|
162
|
+
coeff, gbasis = cg
|
163
|
+
q, r = divmod(*gbasis)
|
164
|
+
q0 = (0...f.size).collect do |i|
|
165
|
+
sum = 0
|
166
|
+
(0...q.size).each do |j|
|
167
|
+
sum += q[j] * coeff[j][i]
|
168
|
+
end
|
169
|
+
sum
|
170
|
+
end
|
171
|
+
[q0, r]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
if $PROGRAM_NAME == __FILE__
|
177
|
+
require 'algebra/m-polynomial'
|
178
|
+
require 'algebra/groebner-basis'
|
179
|
+
require 'algebra/algebraic-parser'
|
180
|
+
# include Algebra
|
181
|
+
|
182
|
+
def gbc(f)
|
183
|
+
f0 = f.first
|
184
|
+
print 'Basis of: '
|
185
|
+
puts(f.join(', '))
|
186
|
+
c, g = Algebra::Groebner.basis_coeff(f)
|
187
|
+
print 'is: '
|
188
|
+
puts(g.join(', '))
|
189
|
+
puts 'Coeefitients are: '
|
190
|
+
c.each do |x|
|
191
|
+
puts x.join(', ')
|
192
|
+
end
|
193
|
+
p 3333
|
194
|
+
p g
|
195
|
+
p c.collect { |x| f.inner_product x }
|
196
|
+
|
197
|
+
if g == c.collect { |x| f.inner_product x }
|
198
|
+
puts 'Success!'
|
199
|
+
else
|
200
|
+
puts 'Fail.'
|
201
|
+
end
|
202
|
+
puts
|
203
|
+
end
|
204
|
+
|
205
|
+
# require "algebra/residue-class-ring"
|
206
|
+
# Z5 = ResidueClassRing(Integer, 5)
|
207
|
+
# P = MPolynomial(Z5)
|
208
|
+
require 'algebra/rational'
|
209
|
+
P = Algebra.MPolynomial(Rational)
|
210
|
+
|
211
|
+
x, y, z = P.vars('xyz')
|
212
|
+
|
213
|
+
f1 = x**2 + y**2 + z**2 - 1
|
214
|
+
f2 = x**2 + z**2 - y
|
215
|
+
f3 = x - z
|
216
|
+
|
217
|
+
gbc([f1, f2, f3])
|
218
|
+
|
219
|
+
g = x**3 + y**3 + z**3
|
220
|
+
q, r = g.divmod_s(f1, f2, f3)
|
221
|
+
p q
|
222
|
+
p r
|
223
|
+
if g == q.inner_product([f1, f2, f3]) + r
|
224
|
+
puts 'Success!'
|
225
|
+
else
|
226
|
+
puts 'Fail.'
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
# Groebner basis module
|
2
|
+
#
|
3
|
+
# by Shin-ichiro Hara
|
4
|
+
#
|
5
|
+
# Version 1.3 (2001.04.03)
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# x, y, z = MPolynomial.vars "xyz"
|
9
|
+
# require "algebra/mathn"
|
10
|
+
# p Groebner.basis([x**2 + y**2 + z**2 -1, x**2 + z**2 - y, x - z])
|
11
|
+
|
12
|
+
# require "algebra/ruby-version"
|
13
|
+
require "algebra/array-supplement"
|
14
|
+
require "algebra/groebner-basis-coeff"
|
15
|
+
#require "algebra/work/old-basis"
|
16
|
+
|
17
|
+
module Algebra
|
18
|
+
module Groebner
|
19
|
+
def S_pair(other)
|
20
|
+
x = lm.lcm(other.lm)
|
21
|
+
x / lt * rt - x / other.lt * other.rt
|
22
|
+
end
|
23
|
+
|
24
|
+
alias | S_pair
|
25
|
+
|
26
|
+
def self.basis?(f)
|
27
|
+
f.each_pair do |x, y|
|
28
|
+
unless ((x|y) % f).zero?
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.minimal_basis?(f)
|
36
|
+
return false unless basis?(f)
|
37
|
+
indexes = (0...f.size).to_a
|
38
|
+
indexes.each do |i|
|
39
|
+
others = f.values_at(*(indexes-[i])).collect{|x| x.lt}
|
40
|
+
if (f[i].lt % others).zero?
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.reduced_basis?(f)
|
48
|
+
return false unless basis?(f)
|
49
|
+
indexes = (0...f.size).to_a
|
50
|
+
indexes.each do |i|
|
51
|
+
others = f.values_at(*(indexes-[i])).collect{|x| x.lt}
|
52
|
+
f[i].each_term do |t|
|
53
|
+
if (t % others).zero?
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.basis_132D(f)
|
62
|
+
gbasis = f.dup
|
63
|
+
pairs = []
|
64
|
+
gbasis.each_pair do |x, y|
|
65
|
+
pairs.push [x, y]
|
66
|
+
end
|
67
|
+
while pair = pairs.shift
|
68
|
+
x, y = pair
|
69
|
+
s = (x|y) % gbasis
|
70
|
+
unless s.zero?
|
71
|
+
gbasis.each do |z| pairs.push([z, s]) end
|
72
|
+
gbasis.push s
|
73
|
+
end
|
74
|
+
end
|
75
|
+
gbasis
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.basis_159A(f)
|
79
|
+
gbasis = f.sort # little effort
|
80
|
+
glm = gbasis.collect{|x| x.lm}
|
81
|
+
pairs = []
|
82
|
+
(0...glm.size).to_a.each_pair do |i, j|
|
83
|
+
pairs.push [i, j]
|
84
|
+
end
|
85
|
+
|
86
|
+
until pairs.empty?
|
87
|
+
i, j = pairs.first
|
88
|
+
if !glm[i].prime_to?(glm[j]) && !_ct(glm, pairs, i, j)
|
89
|
+
s = (gbasis[i]|gbasis[j]) % gbasis
|
90
|
+
unless s.zero?
|
91
|
+
0.upto glm.size-1 do |k|
|
92
|
+
pairs.push [k, glm.size]
|
93
|
+
end
|
94
|
+
gbasis.push s
|
95
|
+
glm.push s.lm
|
96
|
+
end
|
97
|
+
end
|
98
|
+
pairs.shift
|
99
|
+
end
|
100
|
+
gbasis
|
101
|
+
end
|
102
|
+
|
103
|
+
def self._ct(fm, b, i, j)
|
104
|
+
0.upto fm.size-1 do |k|
|
105
|
+
next if k == i or
|
106
|
+
k == j or
|
107
|
+
i < k ? b.include?([i, k]) : b.include?([k, i]) or
|
108
|
+
j < k ? b.include?([j, k]) : b.include?([k, j])
|
109
|
+
return true if fm[k].divide_or?(fm[i], fm[j])
|
110
|
+
end
|
111
|
+
false
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.minimal_basis(gbasis)
|
115
|
+
# p [200, gbasis]
|
116
|
+
glm = gbasis.collect{|x| x.lm}
|
117
|
+
indexes = (0...gbasis.size).sort{|i, j| glm[j] <=> glm[i]}
|
118
|
+
indexes.each_with_index do |i, s|
|
119
|
+
(s+1).upto indexes.size-1 do |k| j = indexes[k]
|
120
|
+
# p [glm[j], glm[i], glm[j].divide? glm[i]]
|
121
|
+
if glm[j].divide? glm[i]
|
122
|
+
indexes[s] = nil
|
123
|
+
break
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
indexes.compact!
|
128
|
+
gbasis.values_at(*indexes)
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.reduced_basis(gbasis)
|
132
|
+
gbasis.each_with_index do |x, i|
|
133
|
+
(g = gbasis.dup).delete_at(i)
|
134
|
+
gbasis[i] = x % g
|
135
|
+
end
|
136
|
+
gbasis.collect{|t| t / t.lc}
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.basis(g)
|
140
|
+
gbasis = nil
|
141
|
+
|
142
|
+
# gbasis = basis_132D(g)
|
143
|
+
gbasis = basis_159A(g)
|
144
|
+
|
145
|
+
gbasis = minimal_basis(gbasis)
|
146
|
+
gbasis = reduced_basis(gbasis)
|
147
|
+
gbasis.sort!{|x, y| y <=> x}
|
148
|
+
gbasis
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class MPolynomial
|
153
|
+
include Algebra::Groebner
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
if $0 == __FILE__
|
159
|
+
require "algebra/m-polynomial"
|
160
|
+
# include Algebra
|
161
|
+
|
162
|
+
def gb(f, sw = false)
|
163
|
+
f0 = f.first
|
164
|
+
print "Basis of: "
|
165
|
+
sw ? puts('', *f) : puts(f.join(", "))
|
166
|
+
gbase = Algebra::Groebner.reduced_basis(f)
|
167
|
+
print "Is: "
|
168
|
+
sw ? puts('', *gbase) : puts(gbase.join(", "))
|
169
|
+
puts
|
170
|
+
end
|
171
|
+
|
172
|
+
puts "rational"
|
173
|
+
require "algebra/rational"
|
174
|
+
x, y, z = Algebra.MPolynomial(Rational).vars "xyz"
|
175
|
+
f1 = x**2 + y**2 + z**2 -1
|
176
|
+
f2 = x**2 + z**2 - y
|
177
|
+
f3 = x - z
|
178
|
+
gb([f1, f2, f3])
|
179
|
+
|
180
|
+
|
181
|
+
puts "mod 5"
|
182
|
+
require "algebra/residue-class-ring"
|
183
|
+
F5 = Algebra.ResidueClassRing(Integer, 5)
|
184
|
+
x, y, z = Algebra.MPolynomial(F5).vars "xyz"
|
185
|
+
f1 = x**2 + y**2 + z**2 -1
|
186
|
+
f2 = x**2 + z**2 - y
|
187
|
+
f3 = x - z
|
188
|
+
gb([f1, f2, f3])
|
189
|
+
|
190
|
+
puts "require 'algebra/mathn'"
|
191
|
+
require "algebra/mathn"
|
192
|
+
x, y, z = Algebra.MPolynomial(Integer).vars "xyz"
|
193
|
+
f1 = x**2 + y**2 + z**2 -1
|
194
|
+
f2 = x**2 + z**2 - y
|
195
|
+
f3 = x - z
|
196
|
+
gb([f1, f2, f3])
|
197
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# $IMPORT_MODULE_debug = true
|
2
|
+
require 'algebra/import-module'
|
3
|
+
module Import_Module
|
4
|
+
class Scope
|
5
|
+
def set_methods
|
6
|
+
meths = @target.get_orig_methods(@source)
|
7
|
+
@target.def_orig_methods meths
|
8
|
+
# def_methods
|
9
|
+
mod = @mod
|
10
|
+
@klass.class_eval { include mod }
|
11
|
+
end
|
12
|
+
|
13
|
+
def push
|
14
|
+
def_methods
|
15
|
+
c = @target.stack.current
|
16
|
+
@target.stack.push(update(c))
|
17
|
+
end
|
18
|
+
|
19
|
+
def pop
|
20
|
+
c = @target.stack.pop
|
21
|
+
recov_methods(c)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def update(c)
|
27
|
+
d = c.dup
|
28
|
+
@source.methods.__each__ do |meth|
|
29
|
+
d[meth] = @mod
|
30
|
+
end
|
31
|
+
d
|
32
|
+
end
|
33
|
+
|
34
|
+
def def_methods
|
35
|
+
mod = @mod
|
36
|
+
target = @target
|
37
|
+
@source.methods.__each__ do |meth|
|
38
|
+
@klass.module_eval do
|
39
|
+
alias_method meth, Import_Module.name(meth, mod)
|
40
|
+
protected(meth) if target.protecteds.include?(meth)
|
41
|
+
private(meth) if target.privates.include?(meth)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def recov_methods(c)
|
47
|
+
orig_methods = @target.orig_methods
|
48
|
+
d = @target.stack.current
|
49
|
+
c.__each__ do |meth, _mod|
|
50
|
+
@klass.module_eval do
|
51
|
+
if m = d[meth] || orig_methods[meth] && :orig
|
52
|
+
alias_method meth, Import_Module.name(meth, m)
|
53
|
+
else
|
54
|
+
undef_method meth
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Target
|
62
|
+
def initialize(klass)
|
63
|
+
@scopes = {}
|
64
|
+
@klass = klass
|
65
|
+
@publics = @klass.public_instance_methods(true) # .find_all{|m| @klass.public_method_defined? m}
|
66
|
+
@privates = @klass.private_instance_methods(true) # .find_all{|m| @klass.private_method_defined? m}
|
67
|
+
@protecteds = @klass.protected_instance_methods(true) # .find_all{|m| @klass.protected_method_defined? m}
|
68
|
+
@orig_methods = {}
|
69
|
+
@saved_methods = {}
|
70
|
+
resist_orig_methods
|
71
|
+
@stack = Stack.new([{}]) # diff
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class Stack
|
76
|
+
private
|
77
|
+
|
78
|
+
def export_current; end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class << Thread
|
83
|
+
alias new new_org
|
84
|
+
alias start new_org
|
85
|
+
alias fork new_org
|
86
|
+
end
|