algebra 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.travis.yml +7 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.lock +28 -0
  7. data/LICENSE.txt +21 -0
  8. data/README-ja.txt +60 -0
  9. data/README.md +61 -0
  10. data/Rakefile +43 -0
  11. data/algebra.gemspec +33 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/doc-ja/README-ja.html +69 -0
  15. data/doc-ja/README-ja.rd +60 -0
  16. data/doc-ja/README.html +0 -0
  17. data/doc-ja/README.rd +0 -0
  18. data/doc-ja/algebra-ja.html +66 -0
  19. data/doc-ja/algebra-ja.rd +60 -0
  20. data/doc-ja/algebraic-equation-ja.html +36 -0
  21. data/doc-ja/algebraic-equation-ja.rd +26 -0
  22. data/doc-ja/algebraic-extension-field-ja.html +122 -0
  23. data/doc-ja/algebraic-extension-field-ja.rd +118 -0
  24. data/doc-ja/algebraic-parser-ja.html +87 -0
  25. data/doc-ja/algebraic-parser-ja.rd +95 -0
  26. data/doc-ja/changes.html +161 -0
  27. data/doc-ja/changes.rd +119 -0
  28. data/doc-ja/elementary-divisor-ja.html +56 -0
  29. data/doc-ja/elementary-divisor-ja.rd +45 -0
  30. data/doc-ja/euclidian-ring-ja.html +78 -0
  31. data/doc-ja/euclidian-ring-ja.rd +69 -0
  32. data/doc-ja/finite-group-ja.html +285 -0
  33. data/doc-ja/finite-group-ja.rd +276 -0
  34. data/doc-ja/finite-map-ja.html +224 -0
  35. data/doc-ja/finite-map-ja.rd +227 -0
  36. data/doc-ja/finite-set-ja.html +393 -0
  37. data/doc-ja/finite-set-ja.rd +408 -0
  38. data/doc-ja/index-ja.html +113 -0
  39. data/doc-ja/index-ja.rd +112 -0
  40. data/doc-ja/jordan-form-ja.html +106 -0
  41. data/doc-ja/jordan-form-ja.rd +99 -0
  42. data/doc-ja/localized-ring-ja.html +121 -0
  43. data/doc-ja/localized-ring-ja.rd +131 -0
  44. data/doc-ja/m-polynomial-ja.html +542 -0
  45. data/doc-ja/m-polynomial-ja.rd +596 -0
  46. data/doc-ja/matrix-algebra-ja.html +686 -0
  47. data/doc-ja/matrix-algebra-ja.rd +727 -0
  48. data/doc-ja/matrix-algebra-triplet-ja.html +124 -0
  49. data/doc-ja/matrix-algebra-triplet-ja.rd +129 -0
  50. data/doc-ja/permutation-group-ja.html +159 -0
  51. data/doc-ja/permutation-group-ja.rd +151 -0
  52. data/doc-ja/polynomial-converter-ja.html +64 -0
  53. data/doc-ja/polynomial-converter-ja.rd +54 -0
  54. data/doc-ja/polynomial-ja.html +446 -0
  55. data/doc-ja/polynomial-ja.rd +473 -0
  56. data/doc-ja/residue-class-ring-ja.html +112 -0
  57. data/doc-ja/residue-class-ring-ja.rd +113 -0
  58. data/doc-ja/sample-algebraic-equation01.rb.v.rd +11 -0
  59. data/doc-ja/sample-algebraic-equation02.rb.v.rd +11 -0
  60. data/doc-ja/sample-algebraic-root01.rb.v.rd +20 -0
  61. data/doc-ja/sample-algebraicfield01.rb.v.rd +26 -0
  62. data/doc-ja/sample-algebraicfield02.rb.v.rd +15 -0
  63. data/doc-ja/sample-cayleyhamilton01.rb.v.rd +14 -0
  64. data/doc-ja/sample-diagonalization01.rb.v.rd +48 -0
  65. data/doc-ja/sample-divmod01.rb.v.rd +17 -0
  66. data/doc-ja/sample-elementary-divisor01.rb.v.rd +48 -0
  67. data/doc-ja/sample-factorize01.rb.v.rd +11 -0
  68. data/doc-ja/sample-factorize02.rb.v.rd +13 -0
  69. data/doc-ja/sample-factorize03.rb.v.rd +14 -0
  70. data/doc-ja/sample-factorize04.rb.v.rd +14 -0
  71. data/doc-ja/sample-factorize05.rb.v.rd +53 -0
  72. data/doc-ja/sample-galois-group01.rb.v.rd +27 -0
  73. data/doc-ja/sample-gaussian-elimination01.rb.v.rd +19 -0
  74. data/doc-ja/sample-geometry01.rb.v.rd +33 -0
  75. data/doc-ja/sample-geometry02.rb.v.rd +34 -0
  76. data/doc-ja/sample-geometry03.rb.v.rd +45 -0
  77. data/doc-ja/sample-geometry04.rb.v.rd +33 -0
  78. data/doc-ja/sample-geometry07.rb.v.rd +62 -0
  79. data/doc-ja/sample-groebner01.rb.v.rd +13 -0
  80. data/doc-ja/sample-groebner02.rb.v.rd +18 -0
  81. data/doc-ja/sample-groebner03.rb.v.rd +19 -0
  82. data/doc-ja/sample-group01.rb.v.rd +21 -0
  83. data/doc-ja/sample-jordan-form01.rb.v.rd +56 -0
  84. data/doc-ja/sample-jordanform01.rb.v.rd +55 -0
  85. data/doc-ja/sample-lagrange-multiplier01.rb.v.rd +35 -0
  86. data/doc-ja/sample-m-factorize01.rb.v.rd +15 -0
  87. data/doc-ja/sample-m-factorize02.rb.v.rd +12 -0
  88. data/doc-ja/sample-m-polynomial01.rb.v.rd +10 -0
  89. data/doc-ja/sample-map01.rb.v.rd +9 -0
  90. data/doc-ja/sample-polynomial01.rb.v.rd +9 -0
  91. data/doc-ja/sample-polynomial02.rb.v.rd +11 -0
  92. data/doc-ja/sample-primefield01.rb.v.rd +13 -0
  93. data/doc-ja/sample-quotientfield01.rb.v.rd +11 -0
  94. data/doc-ja/sample-quotientfield02.rb.v.rd +18 -0
  95. data/doc-ja/sample-quotientfield03.rb.v.rd +16 -0
  96. data/doc-ja/sample-quotientfield04.rb.v.rd +16 -0
  97. data/doc-ja/sample-set01.rb.v.rd +18 -0
  98. data/doc-ja/sample-splitting-field01.rb.v.rd +19 -0
  99. data/doc-ja/samples-ja.html +885 -0
  100. data/doc-ja/samples-ja.rd +221 -0
  101. data/doc-ja/style.css +85 -0
  102. data/doc-ja/todo.html +20 -0
  103. data/doc-ja/todo.rd +9 -0
  104. data/lib/algebra.rb +36 -0
  105. data/lib/algebra/algebraic-equation.rb +56 -0
  106. data/lib/algebra/algebraic-extension-field.rb +135 -0
  107. data/lib/algebra/algebraic-parser.rb +160 -0
  108. data/lib/algebra/algebraic-system.rb +224 -0
  109. data/lib/algebra/annihilate.rb +52 -0
  110. data/lib/algebra/array-supplement.rb +53 -0
  111. data/lib/algebra/auto-require.rb +84 -0
  112. data/lib/algebra/chinese-rem-th.rb +135 -0
  113. data/lib/algebra/combinatorial.rb +145 -0
  114. data/lib/algebra/elementary-divisor.rb +193 -0
  115. data/lib/algebra/euclidian-ring.rb +161 -0
  116. data/lib/algebra/factors.rb +305 -0
  117. data/lib/algebra/finite-group.rb +374 -0
  118. data/lib/algebra/finite-map.rb +201 -0
  119. data/lib/algebra/finite-set.rb +456 -0
  120. data/lib/algebra/galois-group.rb +129 -0
  121. data/lib/algebra/gaussian-elimination.rb +385 -0
  122. data/lib/algebra/groebner-basis-coeff.rb +228 -0
  123. data/lib/algebra/groebner-basis.rb +197 -0
  124. data/lib/algebra/import-module-single-thread.rb +86 -0
  125. data/lib/algebra/import-module.rb +491 -0
  126. data/lib/algebra/jordan-form.rb +114 -0
  127. data/lib/algebra/linear-algebra.rb +143 -0
  128. data/lib/algebra/localized-ring.rb +294 -0
  129. data/lib/algebra/m-index.rb +282 -0
  130. data/lib/algebra/m-polynomial-factor-int.rb +186 -0
  131. data/lib/algebra/m-polynomial-factor-zp.rb +114 -0
  132. data/lib/algebra/m-polynomial-factor.rb +315 -0
  133. data/lib/algebra/m-polynomial-gcd.rb +40 -0
  134. data/lib/algebra/m-polynomial.rb +875 -0
  135. data/lib/algebra/matrix-algebra-triplet.rb +292 -0
  136. data/lib/algebra/matrix-algebra.rb +929 -0
  137. data/lib/algebra/numeric-supplement.rb +123 -0
  138. data/lib/algebra/permutation-group.rb +257 -0
  139. data/lib/algebra/polynomial-converter.rb +193 -0
  140. data/lib/algebra/polynomial-factor-alg.rb +148 -0
  141. data/lib/algebra/polynomial-factor-int.rb +252 -0
  142. data/lib/algebra/polynomial-factor-zp.rb +165 -0
  143. data/lib/algebra/polynomial-factor.rb +140 -0
  144. data/lib/algebra/polynomial.rb +592 -0
  145. data/lib/algebra/powers.rb +31 -0
  146. data/lib/algebra/prime-gen.rb +32 -0
  147. data/lib/algebra/rational.rb +81 -0
  148. data/lib/algebra/residue-class-ring.rb +219 -0
  149. data/lib/algebra/sets-system.rb +43 -0
  150. data/lib/algebra/splitting-field.rb +103 -0
  151. data/lib/algebra/version.rb +3 -0
  152. data/sample/Makefile +10 -0
  153. data/sample/do-testscripts.rb +100 -0
  154. data/sample/sample-algebraic-equation01.rb +6 -0
  155. data/sample/sample-algebraic-equation02.rb +6 -0
  156. data/sample/sample-algebraic-root01.rb +15 -0
  157. data/sample/sample-algebraicfield01.rb +21 -0
  158. data/sample/sample-algebraicfield02.rb +10 -0
  159. data/sample/sample-cayleyhamilton01.rb +9 -0
  160. data/sample/sample-diagonalization01.rb +43 -0
  161. data/sample/sample-divmod01.rb +12 -0
  162. data/sample/sample-elementary-divisor01.rb +43 -0
  163. data/sample/sample-factorize01.rb +6 -0
  164. data/sample/sample-factorize02.rb +8 -0
  165. data/sample/sample-factorize03.rb +9 -0
  166. data/sample/sample-factorize04.rb +9 -0
  167. data/sample/sample-factorize05.rb +48 -0
  168. data/sample/sample-galois-group01.rb +22 -0
  169. data/sample/sample-gaussian-elimination01.rb +14 -0
  170. data/sample/sample-geometry01.rb +28 -0
  171. data/sample/sample-geometry02.rb +29 -0
  172. data/sample/sample-geometry03.rb +40 -0
  173. data/sample/sample-geometry04.rb +28 -0
  174. data/sample/sample-geometry07.rb +58 -0
  175. data/sample/sample-groebner01.rb +8 -0
  176. data/sample/sample-groebner02.rb +13 -0
  177. data/sample/sample-groebner03.rb +14 -0
  178. data/sample/sample-group01.rb +16 -0
  179. data/sample/sample-jordan-form01.rb +51 -0
  180. data/sample/sample-lagrange-multiplier01.rb +30 -0
  181. data/sample/sample-m-factorize01.rb +10 -0
  182. data/sample/sample-m-factorize02.rb +7 -0
  183. data/sample/sample-m-polynomial01.rb +5 -0
  184. data/sample/sample-map01.rb +4 -0
  185. data/sample/sample-polynomial01.rb +4 -0
  186. data/sample/sample-polynomial02.rb +6 -0
  187. data/sample/sample-primefield01.rb +8 -0
  188. data/sample/sample-quotientfield01.rb +6 -0
  189. data/sample/sample-quotientfield02.rb +13 -0
  190. data/sample/sample-quotientfield03.rb +11 -0
  191. data/sample/sample-quotientfield04.rb +11 -0
  192. data/sample/sample-set01.rb +13 -0
  193. data/sample/sample-splitting-field01.rb +14 -0
  194. data/sample/test-00-cayley-hamilton.rb +76 -0
  195. data/sample/test-00-groebner-basis.rb +274 -0
  196. data/sample/test-00-polynomial-factor-alg.rb +89 -0
  197. data/sample/test-00.list +4 -0
  198. data/sample/time-trial.rb +65 -0
  199. metadata +373 -0
@@ -0,0 +1,114 @@
1
+ # Jordan Canonical Forms
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.00 (2001.11.01)
6
+ require 'algebra/matrix-algebra'
7
+
8
+ module Algebra
9
+ class MatrixAlgebra
10
+ def jordan_form
11
+ Algebra::JordanForm.decompose(self).first
12
+ end
13
+
14
+ def jordan_form_info
15
+ Algebra::JordanForm.decompose(self)
16
+ end
17
+ end
18
+
19
+ class JordanForm
20
+ def initialize(body)
21
+ @body = body
22
+ end
23
+
24
+ def to_matrix(ring = Integer)
25
+ mat = nil
26
+ @body.each do |x, n|
27
+ mat = if mat
28
+ mat.dsum(jordan_block_u(ring, x, n))
29
+ else
30
+ jordan_block_u(ring, x, n)
31
+ end
32
+ end
33
+ mat
34
+ end
35
+
36
+ alias to_matrix_u to_matrix
37
+
38
+ def to_matrix_l
39
+ to_matrix_u.transpose
40
+ end
41
+
42
+ def jordan_block_u(ring, x, n)
43
+ a = Algebra.SquareMatrix(ring, n)
44
+ a.matrix do |i, j|
45
+ if i == j
46
+ x
47
+ elsif i == j - 1
48
+ ring.unity
49
+ else
50
+ ring.zero
51
+ end
52
+ end
53
+ end
54
+
55
+ def jordan_block_l(ring, x, n)
56
+ jordan_block_u(ring, x, n).transpose
57
+ end
58
+
59
+ def self.construct(elem_divs, facts, field, pfield)
60
+ a = []
61
+ elem_divs.each do |e|
62
+ facts.each do |f, n|
63
+ next if f.deg.zero? || n.zero?
64
+ f = f.convert_to(pfield)
65
+ g = e.convert_to(pfield)
66
+
67
+ raise 'insufficient decomposition' unless f.deg <= 1
68
+ k = 0
69
+ loop do
70
+ q, r = g.divmod f
71
+ break unless r.zero?
72
+ g = q
73
+ k += 1
74
+ end
75
+ a.push [-f[0], k] if k > 0
76
+ end
77
+ end
78
+ Algebra::JordanForm.new(a).to_matrix(field)
79
+ end
80
+
81
+ def self.decompose(m)
82
+ base_ring = m.ground
83
+ base_pring = Algebra.Polynomial(base_ring, 'x')
84
+ base_alg = Algebra.SquareMatrix(base_pring, m.size)
85
+
86
+ me = m._char_matrix(base_alg).to_quint.e_diagonalize
87
+ elem_divs = me.body.diag
88
+
89
+ facts = Algebra::ElementaryDivisor.factorize(elem_divs)
90
+ dl = facts.last
91
+ field, modulus, facts, roots, elms = dl.pi.decompose(dl)
92
+
93
+ pfield = Algebra.Polynomial(field, 'x')
94
+ pfm_alg = Algebra.SquareMatrix(pfield, m.size)
95
+
96
+ jm = Algebra::JordanForm.construct(elem_divs, facts, field, pfield)
97
+ jme = jm._char_matrix(pfm_alg).to_quint.e_diagonalize
98
+
99
+ mebody = pfm_alg.convert_from(me.body)
100
+ meright = pfm_alg.convert_from(me.right)
101
+ meleft = pfm_alg.convert_from(me.left)
102
+
103
+ sR = (meright * jme.righti).i2o.evaluateR(jm)
104
+ tL = (jme.lefti * meleft).i2o.evaluateL(jm)
105
+
106
+ [jm, tL, sR, field, modulus]
107
+ end
108
+ end
109
+ end
110
+
111
+ if $PROGRAM_NAME == __FILE__
112
+ j = Algebra::JordanForm.new([[2, 3], [-1, 2]])
113
+ j.to_matrix.display
114
+ end
@@ -0,0 +1,143 @@
1
+ # Linear Algebra
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.00 (2001.11.01)
6
+
7
+ require 'algebra/matrix-algebra'
8
+ require 'algebra/gaussian-elimination'
9
+ require 'algebra/polynomial'
10
+ require 'algebra/polynomial-factor'
11
+ require 'algebra/algebraic-equation'
12
+ require 'algebra/jordan-form'
13
+
14
+ module Algebra
15
+ module Orthogonalization
16
+ def orthogonalize
17
+ orth_basis = []
18
+ vectors.each_with_index do |b, i|
19
+ orth_basis.push b
20
+ next unless i > 0
21
+ orth_basis[0...i].each do |f|
22
+ orth_basis[i] -= b.inner_product(f) / f.norm2 * f
23
+ # orth_basis[i] = f.norm2*orth_basis[i] - b.inner_product(f)*f #also
24
+ end
25
+ end
26
+ self.class.collect_column { |j| orth_basis[j] }
27
+ end
28
+
29
+ def normalize
30
+ k = ground
31
+ orth_basis = []
32
+ vectors.each do |b|
33
+ k, n = Sqrt(k, b.norm2)
34
+ orth_basis.push Vector(k, size)**b / n
35
+ end
36
+ Algebra.SquareMatrix(k, size).collect_column { |j| orth_basis[j] }
37
+ end
38
+ end
39
+
40
+ class MatrixAlgebra
41
+ include Orthogonalization
42
+ # auto_req_init
43
+ # auto_req :e_diagonalize, "algebra/elementary-divisor"
44
+ # auto_req :elementary_divisor, "algebra/elementary-divisor"
45
+ require 'algebra/elementary-divisor'
46
+ end
47
+
48
+ class SquareMatrix < MatrixAlgebra
49
+ def self.symmetric(*a)
50
+ k = size * (size + 1) / 2
51
+ raise "the size of #{a.inspect} must be <= #{k}" if a.size > k
52
+ matrix do |i, j|
53
+ d = (i - j).abs
54
+ a[(i < j ? i : j) + (2 * size + 1 - d) * d / 2] || ground.zero
55
+ end
56
+ end
57
+
58
+ EigenSystem = Struct.new('EigenSystem',
59
+ :extfield,
60
+ :roots,
61
+ :tmatrix,
62
+ :evalues,
63
+ :addelms,
64
+ :evectors,
65
+ :espaces,
66
+ :chpoly,
67
+ :facts)
68
+
69
+ def diagonalize
70
+ chp = char_polynomial(Algebra.Polynomial(ground, 't'))
71
+
72
+ facts = chp.factorize
73
+ mdf, mods, fas, roots, proots = chp.decompose(facts)
74
+ nu = Algebra.SquareMatrix(mdf, size)
75
+
76
+ espaces = {}
77
+ evalues = []
78
+ evectors = []
79
+ roots0 = []
80
+ k = 0
81
+ facts.each do |f, _n|
82
+ dim = f.deg
83
+ if dim <= 0 # 0 might be occurred
84
+ next
85
+ elsif dim == 1
86
+ evs = [-f[0] / f[1]]
87
+ else
88
+ evs = roots[k, dim] # .reverse
89
+ roots0.push [f, evs]
90
+ end
91
+ k += dim
92
+
93
+ evs.each do |evalue|
94
+ ks = nu.const(evalue) - self
95
+ kb = ks.kernel_basis
96
+ espaces[evalue] = kb
97
+
98
+ kb.each do |v|
99
+ evalues.push evalue
100
+ evectors.push v
101
+ end
102
+ end
103
+ end
104
+
105
+ raise "can't Diagonalize" if evalues.size < size
106
+ ttype = Algebra.SquareMatrix(mdf, size)
107
+ r = ttype.collect_column { |i| evectors[i] }
108
+ # :extfield, :roots, :tmatrix, :evalues, :addelms, :evectors,
109
+ # :espaces, :chpoly, :facts
110
+ e = EigenSystem.new(mdf, roots0, r, evalues, proots, evectors,
111
+ espaces, chp, facts)
112
+ def e.to_ary
113
+ to_a
114
+ end
115
+ e
116
+ end
117
+
118
+ def solve_eigen_value_problem
119
+ puts 'A = '; display; puts
120
+
121
+ e = diagonalize
122
+ puts "Charactoristic Poly.: #{e.chpoly} => #{e.facts}"; puts
123
+ puts 'Algebraic Numbers:'
124
+ e.roots.each do |po, rs|
125
+ puts "#{rs.join(', ')} : roots of #{po} == 0"
126
+ end; puts
127
+
128
+ puts 'EigenSpaces: '
129
+ e.evalues.uniq.each do |ev|
130
+ puts "W_{#{ev}} = <#{e.espaces[ev].join(', ')}>"
131
+ end; puts
132
+
133
+ puts 'Trans. Matrix:'
134
+ puts 'P ='
135
+ e.tmatrix.display; puts
136
+
137
+ puts 'P^-1 * A * P = '; (e.tmatrix.inverse * self * e.tmatrix).display; puts
138
+ end
139
+ end
140
+ end
141
+
142
+ if __FILE__ == $PROGRAM_NAME
143
+ end
@@ -0,0 +1,294 @@
1
+ # Localization of Ring
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 1.1 (2001.04.10)
6
+
7
+ require 'algebra/euclidian-ring'
8
+ require 'algebra/algebraic-system'
9
+
10
+ module Algebra
11
+ def LocalizedRing(ring)
12
+ LocalizedRing.create(ring)
13
+ end
14
+
15
+ def RationalFunctionField(field, obj)
16
+ require 'algebra/polynomial'
17
+ k = LocalizedRing(Polynomial(field, obj))
18
+ def k.var
19
+ self[ground.var]
20
+ end
21
+
22
+ def k.to_ary
23
+ [self, var]
24
+ end
25
+ k
26
+ end
27
+
28
+ def MRationalFunctionField(field, *objs)
29
+ require 'algebra/m-polynomial'
30
+ k = LocalizedRing(MPolynomial(field, *objs))
31
+ def k.vars(*vs)
32
+ ground.vars(*vs).map { |v| self[v] }
33
+ end
34
+
35
+ def k.to_ary
36
+ [self, *vars]
37
+ end
38
+ k.reducible = false
39
+ k
40
+ end
41
+
42
+ module_function :LocalizedRing, :RationalFunctionField, :MRationalFunctionField
43
+
44
+ class LocalizedRing
45
+ extend AlgebraCreator
46
+ include AlgebraBase
47
+
48
+ def self.create(ground)
49
+ klass = super(ground)
50
+ klass.sysvar(:reducible, true)
51
+ klass
52
+ end
53
+
54
+ def self.reducible
55
+ @@reducible
56
+ end
57
+
58
+ def self.reducible=(sw)
59
+ @@reducible = sw
60
+ end
61
+
62
+ attr_reader :numerator
63
+ attr_reader :denominator
64
+
65
+ def monomial?
66
+ true
67
+ end
68
+
69
+ def self.[](num, den = nil)
70
+ den ? reduce(num, den) : unity * num
71
+ end
72
+
73
+ def self.reduce(num, den)
74
+ reducible ? simplify(num, den) : new(num, den)
75
+ end
76
+
77
+ def self.simplify(num, den)
78
+ raise ZeroDivisionError, 'denometor is 0' if den.zero?
79
+ return zero if num.zero?
80
+
81
+ if ground.field?
82
+ num /= den
83
+ den = ground.unit
84
+ elsif ground.ufd? # ground.euclidian?
85
+ gcd = num.gcd(den)
86
+ num /= gcd
87
+ den /= gcd
88
+ # num = num.div(gcd)
89
+ # den = den.div(gcd)
90
+ end
91
+
92
+ # regulate the leading coefficient of polynomil
93
+ if defined?(Polynomial) && ground <= Polynomial
94
+ if ground.ground.field?
95
+ m = den.lc
96
+ num /= m
97
+ den /= m
98
+ elsif ground.ground.euclidian? # high cost!
99
+ m = num.cont.gcd(den.cont)
100
+ num /= m
101
+ den /= m
102
+ end
103
+ # elsif defined?(MPolynomial) && ground <= MPolynomial
104
+ end
105
+
106
+ # if den.respond_to?(:<) and den < 0
107
+ # num = -num
108
+ # den = -den
109
+ # end
110
+ new(num, den)
111
+ end
112
+
113
+ def initialize(num, den = ground.unity)
114
+ if den.respond_to?(:<=>) && den < ground.zero
115
+ num = -num
116
+ den = -den
117
+ end
118
+ @numerator = num
119
+ @denominator = den
120
+ end
121
+
122
+ def simplify
123
+ self.class.simplify(@numerator, @denominator)
124
+ end
125
+
126
+ def ==(o)
127
+ super do |o|
128
+ @numerator * o.denominator == o.numerator * @denominator
129
+ end
130
+ end
131
+
132
+ def +(o)
133
+ super do |o|
134
+ num = @numerator * o.denominator
135
+ num_o = o.numerator * @denominator
136
+ self.class.reduce(num + num_o, @denominator * o.denominator)
137
+ end
138
+ end
139
+
140
+ def -(o)
141
+ super do |o|
142
+ num = @numerator * o.denominator
143
+ num_o = o.numerator * @denominator
144
+ self.class.reduce(num - num_o, @denominator * o.denominator)
145
+ end
146
+ end
147
+
148
+ def *(o)
149
+ super do |o|
150
+ num = @numerator * o.numerator
151
+ den = @denominator * o.denominator
152
+ self.class.reduce(num, den)
153
+ end
154
+ end
155
+
156
+ def /(o)
157
+ raise ZeroDivisionError, 'devided by 0' if o.zero?
158
+ super do |o|
159
+ num = @numerator * o.denominator
160
+ den = @denominator * o.numerator
161
+ self.class.reduce(num, den)
162
+ end
163
+ end
164
+
165
+ def unit?
166
+ !zero? # some about
167
+ end
168
+
169
+ def pdivmod(other)
170
+ [self / other, zero]
171
+ end
172
+
173
+ # def % (o)
174
+ # raise ZeroDivisionError, "devided by 0" if o.zero?
175
+ # den, a, = @denominator.gcd_coeff(o)
176
+ # num = (@numerator * a) % o
177
+ # q, r = num.divmod den
178
+ # raise "#@denominator can not divide #@numerator mod #{o}" unless r.zero?
179
+ # q
180
+ # end
181
+
182
+ def **(other)
183
+ case other
184
+ when Integer
185
+ if other > 0
186
+ num = @numerator**other
187
+ den = @denominator**other
188
+ self.class.new(num, den)
189
+ elsif other < 0
190
+ num = @denominator**-other
191
+ den = @numerator**-other
192
+ self.class.new(num, den)
193
+ elsif other.zero?
194
+ unity
195
+ end
196
+ else
197
+ x, y = other.coerce(self)
198
+ x**y
199
+ end
200
+ end
201
+
202
+ def need_paren_in_coeff?
203
+ if @denominator.unity?
204
+ if @numerator.respond_to?(:need_paren_in_coeff?)
205
+ @numerator.need_paren_in_coeff?
206
+ elsif @numerator.is_a?(Numeric)
207
+ false
208
+ else
209
+ true
210
+ end
211
+ else
212
+ false
213
+ end
214
+ end
215
+
216
+ def to_s
217
+ n = if @numerator.respond_to?(:need_paren_in_coeff?) &&
218
+ @numerator.need_paren_in_coeff? &&
219
+ !@denominator.unity?
220
+ "(#{@numerator})"
221
+ else
222
+ @numerator.to_s
223
+ end
224
+ d = if @denominator.respond_to?(:need_paren_in_coeff?) &&
225
+ @denominator.need_paren_in_coeff? &&
226
+ !@denominator.is_a?(Integer)
227
+ "(#{@denominator})"
228
+ else
229
+ @denominator.to_s
230
+ end
231
+ if @denominator.unity?
232
+ n.to_s
233
+ else
234
+ n + '/' + d
235
+ end
236
+ end
237
+
238
+ def inspect
239
+ to_s
240
+ # sprintf("%s(%s/%s)", self.class, @numerator.inspect, @denominator.inspect)
241
+ end
242
+
243
+ def hash
244
+ raise 'hash is undefined'
245
+ end
246
+ end
247
+ end
248
+
249
+ if __FILE__ == $PROGRAM_NAME
250
+ require 'algebra/polynomial'
251
+ require 'algebra/rational'
252
+ require 'algebra/residue-class-ring'
253
+ include Algebra
254
+
255
+ Q = LocalizedRing(Integer)
256
+ a = Q.new(3, 5)
257
+ b = Q.new(5, 3)
258
+ p [a + b, a - b, a * b, a / b, a + 3, 1 + a]
259
+
260
+ Z13 = ResidueClassRing(Integer, 13)
261
+
262
+ Z13x = Polynomial(Z13, 'x')
263
+ x = Z13x.var
264
+ QZ13x = LocalizedRing(Z13x)
265
+ a = QZ13x[x**2 + x + 1, x**2 - 1]
266
+ b = QZ13x[x + 1, x**2 + 3 * x + 2]
267
+ p a + b
268
+ p((a + b)**4)
269
+ puts
270
+
271
+ Rx = Polynomial(Rational, 'x')
272
+ # Rx = Polynomial(Z13, "x")
273
+ x = Rx.var
274
+ QRx = LocalizedRing(Rx)
275
+ x = QRx[x]
276
+ a = (x**2 + 1) / (x**3 + x + 1)
277
+ QRxy = Polynomial(QRx, 'y')
278
+ y = QRxy.var
279
+ AFF = ResidueClassRing(QRxy, y**3 + a * y + 1)
280
+ y = AFF[y]
281
+ p((y + x)**3)
282
+
283
+ F = RationalFunctionField(Rational, 'x')
284
+ x = F.var
285
+ p ( 1 / (x**2 - 1) - 1 / (x**3 - 1))
286
+
287
+ require 'algebra/mathn'
288
+ require 'algebra/algebraic-extension-field'
289
+ S = AlgebraicExtensionField(Rational, 'a') { |a| a**2 - 2 }
290
+ QSx = RationalFunctionField(S, 'x')
291
+ x = QSx.var
292
+ a = S.var
293
+ p((a / 4 * x + 1 / 2) / (x**2 + a * x + 1) + (-a / 4 * x + 1 / 2) / (x**2 - a * x + 1))
294
+ end