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,160 @@
|
|
1
|
+
# Algebraic Parser
|
2
|
+
#
|
3
|
+
# by Shin-ichiro Hara
|
4
|
+
#
|
5
|
+
# Version 1.1 (2001.04.08)
|
6
|
+
|
7
|
+
require 'algebra/numeric-supplement'
|
8
|
+
|
9
|
+
module Algebra
|
10
|
+
class AlgebraicParser
|
11
|
+
def self.eval(str, klass) # , coeff = Numeric)
|
12
|
+
new(str, klass).compile
|
13
|
+
end
|
14
|
+
|
15
|
+
Var = '[a-zA-Z]\d*'.freeze
|
16
|
+
Num = '\d+(?:\.\d*)?'.freeze
|
17
|
+
Op = '(?:\*\*|[+\-*\/^])'.freeze
|
18
|
+
Gr = '[\(\)]'.freeze
|
19
|
+
Dlm = ';'.freeze
|
20
|
+
|
21
|
+
def initialize(str, klass)
|
22
|
+
@klass = klass
|
23
|
+
@coeff = klass.ground
|
24
|
+
@s = str.gsub(/\s+/, '').scan(/#{Dlm}|#{Num}|#{Op}|#{Gr}|#{Var}|.+/o)
|
25
|
+
@basis = [] # stack for the basis of the power
|
26
|
+
end
|
27
|
+
|
28
|
+
def compile
|
29
|
+
sentence
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def head
|
35
|
+
@s[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def succ(x = nil)
|
39
|
+
raise "Error: receive #{x} expect #{head}" if x && x != head
|
40
|
+
@s.shift
|
41
|
+
end
|
42
|
+
|
43
|
+
def sentence
|
44
|
+
e = expr
|
45
|
+
while /^#{Dlm}$/ =~ head
|
46
|
+
succ(';')
|
47
|
+
e = expr
|
48
|
+
end
|
49
|
+
e
|
50
|
+
end
|
51
|
+
|
52
|
+
def expr
|
53
|
+
e = expr1
|
54
|
+
while /^[+-]$/ =~ head
|
55
|
+
case succ
|
56
|
+
when '+'
|
57
|
+
e += expr1
|
58
|
+
when '-'
|
59
|
+
e -= expr1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
e
|
63
|
+
end
|
64
|
+
|
65
|
+
def expr1
|
66
|
+
case head
|
67
|
+
when '+' then succ; term
|
68
|
+
when '-' then succ; - term
|
69
|
+
else term
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def term
|
74
|
+
e = sequence
|
75
|
+
while /^[*\/]$/ =~ head # /
|
76
|
+
case succ
|
77
|
+
when '*'
|
78
|
+
e *= sequence
|
79
|
+
when '/'
|
80
|
+
e /= sequence
|
81
|
+
end
|
82
|
+
end
|
83
|
+
e
|
84
|
+
end
|
85
|
+
|
86
|
+
def sequence
|
87
|
+
e = power
|
88
|
+
e *= power while head && head !~ /^#{Dlm}$|^#{Op}$|^#{Gr}$/o
|
89
|
+
e
|
90
|
+
end
|
91
|
+
|
92
|
+
def power
|
93
|
+
@basis.push(k = factor)
|
94
|
+
n = 0
|
95
|
+
while /^(?:\*\*)$|^\^$/ =~ head
|
96
|
+
succ
|
97
|
+
@basis.push(factor)
|
98
|
+
n += 1
|
99
|
+
end
|
100
|
+
f = @basis.pop
|
101
|
+
while n > 0
|
102
|
+
f = @basis.pop**f
|
103
|
+
n -= 1
|
104
|
+
end
|
105
|
+
f
|
106
|
+
end
|
107
|
+
|
108
|
+
def factor
|
109
|
+
case head
|
110
|
+
when '(' then succ; e = sentence; succ(')'); e
|
111
|
+
when /^#{Num}$/o
|
112
|
+
@basis.empty? ? @coeff.indeterminate(succ) : eval(succ)
|
113
|
+
when /^#{Var}$/o then @klass.indeterminate(succ)
|
114
|
+
else
|
115
|
+
raise "unknown token '#{head}'"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if $PROGRAM_NAME == __FILE__
|
122
|
+
class A
|
123
|
+
def self.indeterminate(str)
|
124
|
+
case str
|
125
|
+
when 'x' then 7
|
126
|
+
when 'y' then 11
|
127
|
+
when /\d+/ then eval($&)
|
128
|
+
else
|
129
|
+
raise
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.ground
|
134
|
+
Fixnum
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
p AlgebraicParser.eval('x * y - x^2 + x/8', A) #=> 7*11 - 7**2 + 7/8 = 28
|
139
|
+
|
140
|
+
require 'algebra/rational'
|
141
|
+
|
142
|
+
class B < A
|
143
|
+
def self.indeterminate(str)
|
144
|
+
case str
|
145
|
+
when /\d+/ then Rational(eval($&))
|
146
|
+
else
|
147
|
+
super
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
puts AlgebraicParser.eval('x * y - x^2 + x/8', B)
|
152
|
+
#=> 7*11 - 7**2 + 7/8 = 231/8
|
153
|
+
p AlgebraicParser.eval('2^(-8+4-2+(3-1)^3)^2', Integer) #=> 16
|
154
|
+
|
155
|
+
require 'algebra/m-polynomial'
|
156
|
+
F = MPolynomial(Rational)
|
157
|
+
p AlgebraicParser.eval('- (2*y)**3 + x', F) #=> -8y^3 + x
|
158
|
+
F.variables.clear
|
159
|
+
p AlgebraicParser.eval('x; y; - (2*y)**3 + x', F) #=> x - 8y^3
|
160
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# Algebraic System Library
|
2
|
+
#
|
3
|
+
# by Shin-ichiro Hara
|
4
|
+
#
|
5
|
+
# Version 1.1 (2001.04.20)
|
6
|
+
|
7
|
+
require 'algebra/numeric-supplement'
|
8
|
+
require 'algebra/auto-require'
|
9
|
+
|
10
|
+
module Algebra
|
11
|
+
module AlgebraCreator
|
12
|
+
def create(ground)
|
13
|
+
klass = Class.new(self)
|
14
|
+
klass.sysvar :ground, ground
|
15
|
+
def klass.inspect
|
16
|
+
to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def klass.to_s
|
20
|
+
s = super
|
21
|
+
s = "(#{superclass.inspect}/#{ground.inspect})" if s =~ /^#/ # /
|
22
|
+
s.gsub(/Algebra::/, '')
|
23
|
+
end
|
24
|
+
klass
|
25
|
+
end
|
26
|
+
|
27
|
+
# Needed in the type conversion of MatrixAlgebra
|
28
|
+
def wedge(otype) # =:= tensor
|
29
|
+
if superior?(otype)
|
30
|
+
self
|
31
|
+
elsif otype.respond_to?(:superior?) && otype.superior?(self)
|
32
|
+
otype
|
33
|
+
else
|
34
|
+
raise "wedge: unknown pair (#{self}) .wedge (#{otype})"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def superior?(otype)
|
39
|
+
if otype <= Numeric || self <= otype
|
40
|
+
true
|
41
|
+
elsif respond_to?(:ground) && ground.respond_to?(:superior?)
|
42
|
+
ground.superior?(otype)
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def sysvar(var_name, value = nil, sw = false)
|
49
|
+
var_name = var_name.id2name if var_name.is_a?(Symbol)
|
50
|
+
|
51
|
+
class_eval <<__END_OF_CLASS_DEFINITION__
|
52
|
+
@@#{var_name} = nil
|
53
|
+
def self.#{var_name}; @@#{var_name}; end
|
54
|
+
def self.#{var_name}=(value); @@#{var_name} = value; end
|
55
|
+
__END_OF_CLASS_DEFINITION__
|
56
|
+
|
57
|
+
send(var_name + '=', value) if value
|
58
|
+
|
59
|
+
if sw
|
60
|
+
class_eval <<__END_OF_CLASS_DEFINITION__
|
61
|
+
def #{var_name}; @@#{var_name}; end
|
62
|
+
def #{var_name}=(value); @@#{var_name} = value; end
|
63
|
+
__END_OF_CLASS_DEFINITION__
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module AlgebraBase
|
69
|
+
def zero
|
70
|
+
self.class.zero
|
71
|
+
end
|
72
|
+
|
73
|
+
def unity
|
74
|
+
self.class.unity
|
75
|
+
end
|
76
|
+
|
77
|
+
def zero?
|
78
|
+
zero == self
|
79
|
+
end
|
80
|
+
|
81
|
+
def unit?
|
82
|
+
unity == self || -unity == self
|
83
|
+
end
|
84
|
+
|
85
|
+
def unity?
|
86
|
+
unity == self
|
87
|
+
end
|
88
|
+
|
89
|
+
def ground
|
90
|
+
self.class.ground
|
91
|
+
end
|
92
|
+
|
93
|
+
def ground=(bf)
|
94
|
+
self.class.ground = bf
|
95
|
+
end
|
96
|
+
|
97
|
+
def devide?(other)
|
98
|
+
if self.class.field?
|
99
|
+
true
|
100
|
+
elsif self.class.euclidian?
|
101
|
+
_q, r = other.divmod(self)
|
102
|
+
r.zero?
|
103
|
+
else
|
104
|
+
raise "don't konw #{self} divides #{other}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def regulate(x)
|
109
|
+
self.class.regulate(x)
|
110
|
+
end
|
111
|
+
# private :regulate
|
112
|
+
|
113
|
+
def self.append_features(klass)
|
114
|
+
def klass.field?
|
115
|
+
!method_defined?(:divmod) # may be overwrited
|
116
|
+
end
|
117
|
+
|
118
|
+
def klass.euclidian?
|
119
|
+
method_defined?(:divmod) # may be overwrited
|
120
|
+
end
|
121
|
+
|
122
|
+
def klass.ufd?
|
123
|
+
euclidian? # may be overwrited
|
124
|
+
end
|
125
|
+
|
126
|
+
def klass.zero
|
127
|
+
new(ground.zero)
|
128
|
+
end
|
129
|
+
|
130
|
+
def klass.unity
|
131
|
+
new(ground.unity)
|
132
|
+
end
|
133
|
+
|
134
|
+
def klass.regulate(x)
|
135
|
+
if x.is_a? self
|
136
|
+
x
|
137
|
+
elsif y = ground.regulate(x)
|
138
|
+
new(y)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
super
|
142
|
+
end
|
143
|
+
|
144
|
+
# Operations
|
145
|
+
def +@
|
146
|
+
self
|
147
|
+
end
|
148
|
+
|
149
|
+
def -@
|
150
|
+
zero - self
|
151
|
+
end
|
152
|
+
|
153
|
+
def ==(other)
|
154
|
+
if o = regulate(other)
|
155
|
+
yield o
|
156
|
+
else
|
157
|
+
x, y = other.coerce(self)
|
158
|
+
x == y
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def +(other)
|
163
|
+
if o = regulate(other)
|
164
|
+
yield o
|
165
|
+
else
|
166
|
+
x, y = other.coerce(self)
|
167
|
+
x + y
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def -(other)
|
172
|
+
if o = regulate(other)
|
173
|
+
yield o
|
174
|
+
else
|
175
|
+
x, y = other.coerce(self)
|
176
|
+
x - y
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def *(other)
|
181
|
+
if o = regulate(other)
|
182
|
+
yield o
|
183
|
+
else
|
184
|
+
x, y = other.coerce(self)
|
185
|
+
x * y
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def /(other)
|
190
|
+
if o = regulate(other)
|
191
|
+
yield o
|
192
|
+
else
|
193
|
+
x, y = other.coerce(self)
|
194
|
+
x / y
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def **(n)
|
199
|
+
if !n.is_a?(Integer) || n < 0
|
200
|
+
raise 'index must be non negative integer'
|
201
|
+
elsif n == 0
|
202
|
+
return unity
|
203
|
+
elsif n == 1
|
204
|
+
self
|
205
|
+
else
|
206
|
+
q, r = n.divmod 2
|
207
|
+
x = self**q
|
208
|
+
x *= x
|
209
|
+
x *= self if r > 0
|
210
|
+
x
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
alias ^ **
|
215
|
+
|
216
|
+
def coerce(other)
|
217
|
+
if x = regulate(other)
|
218
|
+
[x, self]
|
219
|
+
else
|
220
|
+
raise "(ALG.SYS) can't coerce: (#{self.class}).coerce(#{other.class}) : (#{self}).coerce(#{other})"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'algebra/m-polynomial'
|
2
|
+
require 'algebra/groebner-basis'
|
3
|
+
|
4
|
+
module Algebra
|
5
|
+
class MPolynomial
|
6
|
+
def lcm(other)
|
7
|
+
vars0 = vars
|
8
|
+
mp = MPolynomial.create(ground)
|
9
|
+
mp.vars('t', *vars)
|
10
|
+
t = mp.vars.first
|
11
|
+
mpvars = mp.vars
|
12
|
+
f = project0(mp) do |c, ind|
|
13
|
+
c * index_eval(mp, mpvars, [0] + ind.to_a)
|
14
|
+
end
|
15
|
+
g = other.project0(mp) do |c, ind|
|
16
|
+
c * index_eval(mp, mpvars, [0] + ind.to_a)
|
17
|
+
end
|
18
|
+
gb = Groebner.basis([t * f, (1 - t) * g])
|
19
|
+
lcm0 = gb.last
|
20
|
+
lcm0.project0(self.class) do |c, ind|
|
21
|
+
c * index_eval(self.class, vars0, ind.empty? ? [] : ind[1..-1])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def gcd(other)
|
26
|
+
(self * other).divmod(lcm(other)).first.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def gcd_all(*a)
|
30
|
+
t = self
|
31
|
+
a.each do |x|
|
32
|
+
break if t.constant?
|
33
|
+
t = t.gcd(x)
|
34
|
+
end
|
35
|
+
t
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if $PROGRAM_NAME == __FILE__
|
41
|
+
require 'algebra/residue-class-ring'
|
42
|
+
include Algebra
|
43
|
+
Z7 = ResidueClassRing(Integer, 7)
|
44
|
+
P = MPolynomial(Z7)
|
45
|
+
x, y, z = P.vars('xyz')
|
46
|
+
|
47
|
+
f = (x + y) * (x + 2 * y)
|
48
|
+
g = (x + 2 * y) * (x + 3 * y)
|
49
|
+
# f, g = x**2*y, x*y**2
|
50
|
+
p f.lcm(g)
|
51
|
+
p f.gcd(g)
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Array Supplements
|
2
|
+
#
|
3
|
+
# by Shin-ichiro Hara
|
4
|
+
#
|
5
|
+
# Version 1.2 (2001.07.23)
|
6
|
+
|
7
|
+
class Array
|
8
|
+
def each_pair
|
9
|
+
each_with_index do |x, i|
|
10
|
+
(i + 1).upto(size - 1) do |j|
|
11
|
+
y = self[j]
|
12
|
+
yield(x, y)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def each_pair_with_index
|
18
|
+
each_with_index do |x, i|
|
19
|
+
(i + 1).upto(size - 1) do |j|
|
20
|
+
y = self[j]
|
21
|
+
yield(x, y, i, j)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def rsort!
|
27
|
+
sort!
|
28
|
+
reverse!
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def rsort
|
33
|
+
s = sort
|
34
|
+
s.reverse!
|
35
|
+
s
|
36
|
+
end
|
37
|
+
|
38
|
+
def inner_product(other)
|
39
|
+
sum = 0
|
40
|
+
each_with_index do |x, i|
|
41
|
+
sum += x * other[i]
|
42
|
+
end
|
43
|
+
sum
|
44
|
+
end
|
45
|
+
|
46
|
+
def sumation
|
47
|
+
sum = 0
|
48
|
+
each do |x|
|
49
|
+
sum += x
|
50
|
+
end
|
51
|
+
sum
|
52
|
+
end
|
53
|
+
end
|