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,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
|