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.
- 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,374 @@
|
|
|
1
|
+
# Finite Group
|
|
2
|
+
#
|
|
3
|
+
# by Shin-ichiro Hara
|
|
4
|
+
#
|
|
5
|
+
# Version 0.9 (2002.03.12)
|
|
6
|
+
|
|
7
|
+
require 'algebra/finite-set'
|
|
8
|
+
require 'algebra/prime-gen'
|
|
9
|
+
|
|
10
|
+
module Algebra
|
|
11
|
+
module OperatorDomain
|
|
12
|
+
def right_act(other)
|
|
13
|
+
cast.product(other.cast) { |x, y| x * y }
|
|
14
|
+
# product(other, self.class[unity]) {|x, y| x * y}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
alias act right_act
|
|
18
|
+
|
|
19
|
+
def left_act(other)
|
|
20
|
+
other.right_act(self)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def right_quotient(other)
|
|
24
|
+
s = Set.phi
|
|
25
|
+
remain = cast.dup
|
|
26
|
+
until remain.empty?
|
|
27
|
+
x = remain.shift
|
|
28
|
+
t = Set[x].right_act(other)
|
|
29
|
+
s.push t
|
|
30
|
+
remain -= t
|
|
31
|
+
end
|
|
32
|
+
s
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias quotient right_quotient
|
|
36
|
+
alias right_coset right_quotient
|
|
37
|
+
alias coset right_quotient
|
|
38
|
+
|
|
39
|
+
def left_quotient(other)
|
|
40
|
+
s = Set.phi
|
|
41
|
+
remain = cast.dup
|
|
42
|
+
until remain.empty?
|
|
43
|
+
x = remain.shift
|
|
44
|
+
t = Set[x].left_act(other)
|
|
45
|
+
s.push t
|
|
46
|
+
remain -= t
|
|
47
|
+
end
|
|
48
|
+
s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
alias left_coset left_quotient
|
|
52
|
+
|
|
53
|
+
def right_representatives(other)
|
|
54
|
+
s = Set.phi
|
|
55
|
+
remain = cast.dup
|
|
56
|
+
until remain.empty?
|
|
57
|
+
x = remain.shift
|
|
58
|
+
t = self.class[x].act(other)
|
|
59
|
+
s.push x
|
|
60
|
+
remain -= t
|
|
61
|
+
end
|
|
62
|
+
s
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias representatives right_representatives
|
|
66
|
+
|
|
67
|
+
def left_representatives(other)
|
|
68
|
+
s = Set.phi
|
|
69
|
+
remain = cast.dup
|
|
70
|
+
until remain.empty?
|
|
71
|
+
x = remain.shift
|
|
72
|
+
t = self.class[x].left_act(other)
|
|
73
|
+
s.push x
|
|
74
|
+
remain -= t
|
|
75
|
+
end
|
|
76
|
+
s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def right_orbit!(other)
|
|
80
|
+
news = Set.phi
|
|
81
|
+
loop do
|
|
82
|
+
each_product(other) do |x, y|
|
|
83
|
+
z = x * y
|
|
84
|
+
news.push z unless include?(z) || news.include?(z)
|
|
85
|
+
end
|
|
86
|
+
if news.empty?
|
|
87
|
+
break
|
|
88
|
+
else
|
|
89
|
+
concat news
|
|
90
|
+
news = Set.phi
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
self
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
alias orbit! right_orbit!
|
|
97
|
+
|
|
98
|
+
def left_orbit!(other)
|
|
99
|
+
other.right_orbit!(self)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class Set
|
|
104
|
+
include OperatorDomain
|
|
105
|
+
alias * act
|
|
106
|
+
alias / quotient
|
|
107
|
+
alias % representatives
|
|
108
|
+
|
|
109
|
+
def increasing_series(x = unit_group)
|
|
110
|
+
a = []
|
|
111
|
+
loop do
|
|
112
|
+
a.push x
|
|
113
|
+
if x >= (y = yield x)
|
|
114
|
+
break
|
|
115
|
+
end
|
|
116
|
+
x = y
|
|
117
|
+
end
|
|
118
|
+
a
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def decreasing_series(x = self)
|
|
122
|
+
a = []
|
|
123
|
+
loop do
|
|
124
|
+
a.push x
|
|
125
|
+
if x <= (y = yield x)
|
|
126
|
+
break
|
|
127
|
+
end
|
|
128
|
+
x = y
|
|
129
|
+
end
|
|
130
|
+
a
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
class Group < Set
|
|
135
|
+
# include OperatorDomain
|
|
136
|
+
attr_reader :unity
|
|
137
|
+
|
|
138
|
+
def quotient_group(u)
|
|
139
|
+
# raise "devided by non normal sub group" unless normal?(u)
|
|
140
|
+
QuotientGroup.new(self, u)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def separate(&b)
|
|
144
|
+
self.class.new(unity, *find_all(&b))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def initialize(u, *a)
|
|
148
|
+
super(u, *a)
|
|
149
|
+
@unity = u
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
attr_reader :unity
|
|
153
|
+
|
|
154
|
+
def unit_group
|
|
155
|
+
self.class.new(@unity)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def semi_complete!
|
|
159
|
+
orbit!(self)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def semi_complete
|
|
163
|
+
dup.semi_complete!
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def complete!
|
|
167
|
+
concat collect(&:inverse)
|
|
168
|
+
orbit!(self)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def complete
|
|
172
|
+
dup.complete!
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def self.generate_strong(u, *ary_of_gens)
|
|
176
|
+
unless a = ary_of_gens.shift
|
|
177
|
+
return new(u)
|
|
178
|
+
end
|
|
179
|
+
a.first != u && (a = [u] + a)
|
|
180
|
+
while b = ary_of_gens.shift
|
|
181
|
+
b.first != u && (b = [u] + b)
|
|
182
|
+
c = []
|
|
183
|
+
a.each do |x|
|
|
184
|
+
b.each do |y|
|
|
185
|
+
c.push x * y
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
a = c
|
|
189
|
+
end
|
|
190
|
+
new(*a)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def closed?
|
|
194
|
+
each do |x|
|
|
195
|
+
return false unless include? x.inverse
|
|
196
|
+
each do |y|
|
|
197
|
+
return false unless include?(x * y)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
true
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def subgroups(&b)
|
|
204
|
+
e = unit_group
|
|
205
|
+
yield e if block_given?
|
|
206
|
+
subgrs = Set[e, self]
|
|
207
|
+
_subgroups(e, subgrs, &b)
|
|
208
|
+
yield self if block_given?
|
|
209
|
+
subgrs
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def _subgroups(h, subgrs, &b)
|
|
213
|
+
loop do
|
|
214
|
+
new_elem = false
|
|
215
|
+
(cast - h).representatives(h).each do |a|
|
|
216
|
+
i = h.append(a).complete!
|
|
217
|
+
next if i.size == size
|
|
218
|
+
next if subgrs.include? i
|
|
219
|
+
new_elem = true
|
|
220
|
+
subgrs.push i
|
|
221
|
+
yield i if block_given?
|
|
222
|
+
if defined?(Primes) && Primes.include?(size / i.size)
|
|
223
|
+
else
|
|
224
|
+
_subgroups(i, subgrs, &b)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
break unless new_elem
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
private :_subgroups
|
|
231
|
+
|
|
232
|
+
def centralizer(s) # C_{self}(s) not C_{s}(self) !!!!
|
|
233
|
+
separate { |x| s.all? { |y| x * y == y * x } }
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def center # C_{self}(self)
|
|
237
|
+
centralizer(self)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def center?(x) # self == C_{self}(x)
|
|
241
|
+
all? { |y| x * y == y * x }
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def normalizer(s)
|
|
245
|
+
separate { |x| s.right_act(Set[x]) == s.left_act(Set[x]) }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def normal?(s)
|
|
249
|
+
all? { |x| s.right_act(Set[x]) == s.left_act(Set[x]) }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def normal_subgroups
|
|
253
|
+
s = Set.phi
|
|
254
|
+
subgroups.each do |x|
|
|
255
|
+
if x.size == 1 ||
|
|
256
|
+
x.size == size ||
|
|
257
|
+
normal?(x)
|
|
258
|
+
yield x if block_given?
|
|
259
|
+
s.push x
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
s
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def conjugacy_class(x)
|
|
266
|
+
(self % centralizer(Set[x])).map_s { |y| x.conjugate(y) }
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def conjugacy_classes
|
|
270
|
+
s = Set.phi
|
|
271
|
+
t = cast
|
|
272
|
+
until t.empty?
|
|
273
|
+
x = conjugacy_class(t.pick)
|
|
274
|
+
yield x if block_given?
|
|
275
|
+
s.push x
|
|
276
|
+
t -= x
|
|
277
|
+
end
|
|
278
|
+
s
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def simple?
|
|
282
|
+
subgroups.all? do |x|
|
|
283
|
+
x.size == 1 || x.size == size ||
|
|
284
|
+
!normal?(x)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def commutator(h = self)
|
|
289
|
+
gr = unit_group
|
|
290
|
+
each do |x|
|
|
291
|
+
h.each do |y|
|
|
292
|
+
gr.push x.inverse * y.inverse * x * y
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
self == h ? gr.semi_complete! : gr.complete!
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def D(n = 1)
|
|
299
|
+
if n == 0
|
|
300
|
+
self
|
|
301
|
+
else
|
|
302
|
+
D(n - 1).commutator D(n - 1)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def commutator_series
|
|
307
|
+
decreasing_series(&:D)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def solvable?
|
|
311
|
+
commutator_series.last.size == 1
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def K(n = 1)
|
|
315
|
+
if n == 0
|
|
316
|
+
self
|
|
317
|
+
else
|
|
318
|
+
commutator K(n - 1)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def descending_central_series
|
|
323
|
+
decreasing_series do |s|
|
|
324
|
+
commutator s
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def Z(n = 1)
|
|
329
|
+
if n == 0
|
|
330
|
+
unit_group
|
|
331
|
+
else
|
|
332
|
+
separate do |x|
|
|
333
|
+
commutator(Set[x]) <= Z(n - 1)
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def ascending_central_series
|
|
339
|
+
increasing_series(&:Z)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def nilpotent?
|
|
343
|
+
descending_central_series.last.size == 1
|
|
344
|
+
# ascending_central_series.last.size == size
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def nilpotency_class
|
|
348
|
+
a = descending_central_series
|
|
349
|
+
a.size - 1 if a.last.size == 1
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def to_a
|
|
353
|
+
[unity, *(super - [unity])]
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# will be optimized
|
|
358
|
+
class QuotientGroup < Group
|
|
359
|
+
def initialize(univ, u)
|
|
360
|
+
@univ = univ
|
|
361
|
+
super(u, *univ.quotient(u))
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def inverse
|
|
365
|
+
map_s(&:inverse)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
alias inv inverse
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
if __FILE__ == $PROGRAM_NAME
|
|
373
|
+
|
|
374
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Map of Finite Sets
|
|
2
|
+
#
|
|
3
|
+
# by Shin-ichiro Hara
|
|
4
|
+
#
|
|
5
|
+
# Version 0.96 (2003.11.06)
|
|
6
|
+
|
|
7
|
+
require 'algebra/finite-set'
|
|
8
|
+
require 'algebra/powers'
|
|
9
|
+
|
|
10
|
+
module Algebra
|
|
11
|
+
class Map < Set
|
|
12
|
+
include Powers
|
|
13
|
+
|
|
14
|
+
def self.[](a = {})
|
|
15
|
+
new.instance_eval do
|
|
16
|
+
@body = Hash[a]
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.new_a(a)
|
|
22
|
+
self[Hash[*a]]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def initialize(h = {})
|
|
26
|
+
@body = h
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.empty_set(t = nil)
|
|
30
|
+
m = new
|
|
31
|
+
m.target = t if t
|
|
32
|
+
m
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class << self
|
|
36
|
+
alias phi empty_set
|
|
37
|
+
alias null empty_set
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.singleton(x, y)
|
|
41
|
+
new(x => y)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def base_class
|
|
45
|
+
self.class.superclass
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def each(&b)
|
|
49
|
+
@body.each(&b)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def empty_set(s = nil)
|
|
53
|
+
self.class.empty_set(s)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
alias phi empty_set
|
|
57
|
+
alias null empty_set
|
|
58
|
+
|
|
59
|
+
def dup
|
|
60
|
+
m = self.class.new(@body.dup)
|
|
61
|
+
m.target = target if target
|
|
62
|
+
m
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def call(x)
|
|
66
|
+
@body.fetch(x)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
alias act call
|
|
70
|
+
alias [] call
|
|
71
|
+
|
|
72
|
+
def append!(x, y)
|
|
73
|
+
@body.store(x, y)
|
|
74
|
+
self
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
alias []= append!
|
|
78
|
+
|
|
79
|
+
def append(x, y)
|
|
80
|
+
dup.append!(x, y)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def hash
|
|
84
|
+
s = 0
|
|
85
|
+
@body.each_key do |k, v|
|
|
86
|
+
s ^= k.hash ^ ~v.hash
|
|
87
|
+
end
|
|
88
|
+
s
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def member?(a)
|
|
92
|
+
return nil unless a.is_a? Array
|
|
93
|
+
@body[a.first] == a.last
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
alias has? member?
|
|
97
|
+
|
|
98
|
+
def domain
|
|
99
|
+
base_class.new(*@body.keys)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def image(set = nil)
|
|
103
|
+
if set
|
|
104
|
+
set.map_s { |k| call(k) }
|
|
105
|
+
else
|
|
106
|
+
base_class.new(*@body.values)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def map_s
|
|
111
|
+
s = base_class.phi
|
|
112
|
+
each do |x, y|
|
|
113
|
+
s.append!(yield(x, y))
|
|
114
|
+
end
|
|
115
|
+
s
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def map_m
|
|
119
|
+
s = phi
|
|
120
|
+
each do |x, y|
|
|
121
|
+
s.append!(* yield(x, y))
|
|
122
|
+
end
|
|
123
|
+
s
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def inverse
|
|
127
|
+
self.class.new(@body.invert)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def compose(other) # LEFT ACTION!!!
|
|
131
|
+
m = other.map_m { |x, y| [x, call(y)] }
|
|
132
|
+
m.target = target
|
|
133
|
+
m
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
alias * compose
|
|
137
|
+
|
|
138
|
+
# module Map_common
|
|
139
|
+
|
|
140
|
+
attr_accessor :target
|
|
141
|
+
alias source domain
|
|
142
|
+
alias codomain target
|
|
143
|
+
alias codomain= target=
|
|
144
|
+
|
|
145
|
+
def identity?
|
|
146
|
+
all? { |x, y| x == y }
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def surjective?
|
|
150
|
+
raise 'target is not defined.' unless @target
|
|
151
|
+
image.size == target.size
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def injective?
|
|
155
|
+
image.size == source.size
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def bijective?
|
|
159
|
+
surjective? && injective?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def inv_image(s)
|
|
163
|
+
source.separate { |x| s.member? act(x) }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def inv_coset
|
|
167
|
+
s = phi
|
|
168
|
+
if target
|
|
169
|
+
target.each do |y|
|
|
170
|
+
s.append!(y, base_class.phi)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
each do |x, y|
|
|
174
|
+
if s.include? y
|
|
175
|
+
s.call(y) << x
|
|
176
|
+
else
|
|
177
|
+
s.append!(y, base_class.singleton(x))
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
s
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def inspect
|
|
184
|
+
@body.inspect
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def to_s
|
|
188
|
+
@body.inspect
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
if $PROGRAM_NAME == __FILE__
|
|
194
|
+
require 'algebra/permutation-group'
|
|
195
|
+
|
|
196
|
+
a = Algebra::Set[0, 1, 2]
|
|
197
|
+
b = Algebra::Set[0, 1, 2]
|
|
198
|
+
(a**b).each do |x|
|
|
199
|
+
p x
|
|
200
|
+
end
|
|
201
|
+
end
|