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,84 @@
1
+ ## AUTO Require LIBRARY
2
+ ## by Shin-ichiro HARA
3
+ ##
4
+ ## version 1.21 (2002.04.22)
5
+ ##
6
+
7
+ class Module
8
+ def _auto_req_init(sw)
9
+
10
+ if sw
11
+ code = "AUTO_LOAD = {} unless self.class.const_defined? 'AUTO_LOAD'\n"
12
+ else
13
+ code = "AUTO_LOAD = {} unless const_defined? 'AUTO_LOAD'\n"
14
+ end
15
+
16
+ code.concat <<-__CODE__
17
+ def method_missing(sym, *param, &block)
18
+ begin
19
+ file, work = AUTO_LOAD[sym]
20
+ unless file
21
+ raise NameError,
22
+ "undefined method `\#{sym.id2name}' for \#{inspect}"
23
+ end
24
+ require file
25
+ work.call if work
26
+
27
+ unless respond_to?(sym, true)
28
+ raise "(auto_req) `\#{sym.id2name}' is not defined for `\#{self}' in file:`\#{file}' \#{self.class.superclass.superclass}"
29
+ end
30
+ send(sym, *param, &block)
31
+ rescue Exception
32
+ $@.delete_if do |trace|
33
+ trace =~ /^\\(eval\\):/
34
+ end
35
+ raise
36
+ end
37
+ end
38
+ __CODE__
39
+
40
+ sw ? instance_eval(code) : module_eval(code)
41
+ end
42
+
43
+ private :_auto_req_init
44
+ def auto_req_init; _auto_req_init(false); end
45
+ def auto_req_s_init; _auto_req_init(true); end
46
+
47
+ def _auto_req(meths, file, sw = nil, &b)
48
+ meths = [meths] unless meths.is_a? Array
49
+ meths.each_index do |x, i|
50
+ meth[i] = x.intern if x.is_a? String
51
+ end
52
+
53
+ meths.each do |symb|
54
+ code = <<-__CODE__
55
+ AUTO_LOAD[symb.is_a?(String) ? symb.intern : symb] = [file, b]
56
+ __CODE__
57
+
58
+ sw ? instance_eval(code) : module_eval(code)
59
+ end
60
+ end
61
+
62
+ private :_auto_req
63
+ def auto_req(*a, &b); _auto_req(a[0...-1], a[-1], false, &b); end
64
+ def auto_req_s(*a, &b); _auto_req(a[0...-1], a[-1], true, &b); end
65
+ end
66
+
67
+ def auto_req_init
68
+ Object.auto_req_init
69
+ end
70
+
71
+ def auto_req(*a, &b)
72
+ Object.auto_req(*a, &b)
73
+ end
74
+
75
+ if $0 == __FILE__
76
+ class Foo
77
+ auto_req_init
78
+ auto_req(:hello, "hello.rb") {include Hello; extend Hello}
79
+ end
80
+ class Bar < Foo
81
+ end
82
+ Bar.new.hello
83
+ Bar.hello
84
+ end
@@ -0,0 +1,135 @@
1
+ # require "algebra/euclidian-ring"
2
+ require 'algebra/array-supplement'
3
+
4
+ module Algebra
5
+ module ChineseRemainderTheorem
6
+ # return coeffs s.t. coeffs.inner_product(ary) == c
7
+ # entries of c and ary must be euclidian ring
8
+ def decompose_on_factors(c, ary)
9
+ f1, *fs = ary
10
+ k, *coeffs = f1.gcd_ext_all(*fs)
11
+ q, r = c.divmod(k)
12
+ unless r.zero?
13
+ print 'c = '
14
+ p c
15
+ print 'k = '
16
+ p k
17
+ print 'ary = '
18
+ p ary
19
+ raise "#{c} is not expressed by parameters"
20
+ end
21
+ d1, *ds = coeffs.collect { |x| x * q }
22
+ [d1] + ds # this is ok
23
+ end
24
+
25
+ def decompose_on_cofactors_modp(c, ary, cofacts)
26
+ # c: Polynomial/Zp
27
+ # ary: Array of Polynomial/Zp
28
+ # cofacts: cofacts of ary
29
+ # OutPut: coeff.inner_product(cofacts of ary) == c
30
+
31
+ pf = c.ground
32
+ prime = c.ground.char
33
+ coeffs = ary.collect(&:zero)
34
+ d1, *ds = decompose_on_factors(c, cofacts)
35
+ # normalize
36
+ ds_new = []
37
+ ds.each_with_index do |d, i|
38
+ fq, fr = d.divmod(ary[i + 1])
39
+ d1 += fq * ary[0]
40
+ ds_new << fr
41
+ end
42
+ coeffs = [d1] + ds_new
43
+
44
+ # p c == coeffs.inner_product(cofacts)
45
+ coeffs
46
+ end
47
+
48
+ def decomp_on_cofactors_over_p_adic_int_first(c, ary, prime, cofacts)
49
+ pf = Polynomial.reduction(Integer, prime, 'x')
50
+ ary_Zp = ary.collect { |f| pf.reduce(f) }
51
+ cofacts_Zp = cofacts.collect { |f| pf.reduce(f) }
52
+ c_zp = pf.reduce(c)
53
+
54
+ d1, *ds = decompose_on_factors(c_zp, cofacts_Zp)
55
+
56
+ # normalize
57
+ ds_new = []
58
+ ds.each_with_index do |d, i|
59
+ fq, fr = d.divmod(ary_Zp[i + 1])
60
+ d1 += fq * ary_Zp[0]
61
+ ds_new << fr
62
+ end
63
+ coeffs = [d1] + ds_new
64
+ ring = c.class
65
+ coeffs.collect { |f| lifting(f, ring) }
66
+ end
67
+
68
+ def lifting(f, ring)
69
+ f.project(ring) { |c, _i| c.lift }
70
+ end
71
+
72
+ private :decomp_on_cofactors_over_p_adic_int_first, :lifting
73
+
74
+ def mk_cofacts(ary)
75
+ tot = ary.first.unity
76
+ ary.each { |f|; tot *= f; }
77
+ cofacts = []
78
+ ary.each { |f|; cofacts.push tot / f; }
79
+ cofacts
80
+ end
81
+
82
+ def decompose_on_cofactors_p_adic(c, ary, cofacts, prime, k)
83
+ # c: Polynomial/Intger
84
+ # ary: Array of Polynomial/Integer
85
+ # OutPut: coeff.inner_product(cofacts of ary) === c mod prime**k
86
+
87
+ raise if ary.find { |f| (f.lc % prime).zero? }
88
+ # cofacts = mk_cofacts(ary)
89
+ coeffs = ary.collect(&:zero)
90
+ 0.upto k - 1 do |j|
91
+ e = prime**j
92
+ c1 = (c - coeffs.inner_product(cofacts)) / e
93
+ coeffs1 = decomp_on_cofactors_over_p_adic_int_first(c1,
94
+ ary, prime, cofacts)
95
+ coeffs.each_index do |i|
96
+ coeffs[i] += coeffs1[i] * e
97
+ end
98
+ end
99
+ # p c - coeffs.inner_product(cofacts)
100
+ coeffs
101
+ end
102
+ end
103
+ end
104
+
105
+ if $PROGRAM_NAME == __FILE__
106
+ CRT = ChineseRemainderTheorem
107
+ include CRT
108
+ require 'algebra/polynomial'
109
+ require 'algebra/residue-class-ring'
110
+ require 'algebra/polynomial-factor'
111
+ Zp = ResidueClassRing(Integer, 5)
112
+ P = Polynomial(Zp, 'x')
113
+ x = P.var
114
+ a = x + 1
115
+ b = x + 2
116
+ c = x + 3
117
+ # ary = [b*c, c*a, a*b]
118
+ ary = [a, b, c]
119
+ f = a * b * c
120
+ # coeffs = decompose_on_factors(P.unity, ary)
121
+ coeffs = decompose_on_cofactors_modp(P.unity, ary, mk_cofacts(ary))
122
+ p cofacts = mk_cofacts(ary)
123
+ p coeffs
124
+ p coeffs.inner_product(cofacts)
125
+
126
+ exit
127
+ PZ = Polynomial(Integer, 'x')
128
+ x = PZ.var
129
+ a = (x + 1)**2
130
+ b = (x + 2)**3
131
+ c = (x + 3)**1
132
+ ary = [a, b, c]
133
+ p decompose_on_cofactors_over_p_adic_int(PZ.unity, ary, mk_cofacts(ary),
134
+ 11, 2)
135
+ end
@@ -0,0 +1,145 @@
1
+ # Combinatorial Calculation Library
2
+ #
3
+ # by Shin-ichiro Hara
4
+ #
5
+ # Version 2.0 (2001.09.14)
6
+
7
+ module Combinatorial
8
+ def power(n, m = n)
9
+ if m == 0
10
+ yield([])
11
+ else
12
+ power(n, m - 1) do |x|
13
+ (0...n).each do |i|
14
+ yield([i] + x)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def perm(n, m = n)
21
+ if m == 0
22
+ yield([])
23
+ else
24
+ perm(n - 1, m - 1) do |x|
25
+ (0...n).each do |i|
26
+ yield([i] + x.collect{|j| j < i ? j : j + 1})
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def comb(n, m = n)
33
+ if m == 0
34
+ yield([])
35
+ else
36
+ comb(n, m - 1) do |x|
37
+ (((x[0] || -1) + 1)...n).each do |i|
38
+ yield([i] + x)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def rep_comb(n, m)
45
+ if m == 0
46
+ yield([])
47
+ else
48
+ rep_comb(n, m - 1) do |x|
49
+ ((x.empty? ? 0 : x.last)...n).each do |i|
50
+ yield(x+[i])
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def power0(n, m = n)
57
+ 0.upto n**m-1 do |i|
58
+ yield( (0...m).collect{ (i, = i.divmod n).last } )
59
+ end
60
+ end
61
+
62
+ def perm0(n, stack = [])
63
+ (0...n).each do |x|
64
+ unless stack.include? x
65
+ stack.push x
66
+ if stack.size < n
67
+ perm0(n, stack) do |y|; yield y; end
68
+ else
69
+ yield stack.self
70
+ end
71
+ stack.pop
72
+ end
73
+ end
74
+ end
75
+
76
+ module_function :power, :perm, :comb, :rep_comb, :power0, :perm0
77
+
78
+ module Diagonal
79
+ def diagonal_cone(n, m)
80
+ 0.upto n do |i|
81
+ co_diagonal(i, m) do |a|
82
+ yield a
83
+ end
84
+ end
85
+ end
86
+
87
+ def co_diagonal(n, m)
88
+ rep_comb(n+1, m-1) do |a|
89
+ yield difference_seq(0, a, n)
90
+ end
91
+ end
92
+
93
+ def difference_seq(n0, ary, n1)
94
+ x = n0
95
+ a = []
96
+ ary.each do |y|
97
+ a.push y - x
98
+ x = y
99
+ end
100
+ a.push n1 - x
101
+ a
102
+ end
103
+ private :difference_seq
104
+ end
105
+ include Diagonal
106
+ extend Diagonal
107
+
108
+ module Cubic
109
+ # power in order of (point, eadges, surfaces, bodies, ..)
110
+ def power_cubic(n, m)
111
+ if n < 1
112
+ raise "cubic(< 1, m) called"
113
+ elsif n == 1
114
+ yield( (0...m).collect{0} )# point of origin
115
+ else
116
+ 0.upto m do |dim|
117
+ Combinatorial.comb(m, dim) do |s|
118
+ power_cubic(n-1, dim) do |a|
119
+ yield inject(a, s.sort, m)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ def inject(ary, inds, n = inds.size+1)
127
+ (0...n).collect{|i| (k = inds.index(i)) ? 1 + ary[k] : 0}
128
+ end
129
+ private :inject
130
+ end
131
+ include Cubic
132
+ extend Cubic
133
+ end
134
+
135
+ if __FILE__ == $0
136
+ # include Combinatorial
137
+ n, dim = ARGV.collect{|x|x.to_i}
138
+ # n, dim = 2, 3
139
+ # diagonal_cone(n, m) do |a|; p a; end
140
+ Combinatorial::power_cubic(n, dim) do |a|
141
+ # Combinatorial::power_cubic_nested(n, dim) do |a|
142
+ p a
143
+ end
144
+ # $stderr.puts( (2*n+1)**dim )
145
+ end
@@ -0,0 +1,193 @@
1
+ ##########################################
2
+ # Elementary Divisor
3
+ # by Shin-ichiro HARA
4
+ #
5
+ # Ver. 1.0 (2001.11.03)
6
+ #
7
+ ##########################################
8
+
9
+ module Algebra
10
+ class MatrixAlgebra
11
+ def i2o
12
+ mground = self.class.ground.ground
13
+ r = if self.class <= Algebra::SquareMatrix
14
+ Algebra.SquareMatrix(mground, size)
15
+ else
16
+ Algebra.MatrixAlgebra(mground, rsize, csize)
17
+ end
18
+
19
+ rx = Algebra.Polynomial(r, 'x')
20
+ x = rx.var
21
+ s = 0
22
+ (0..e_deg).each do |n|
23
+ s += x**n * r.matrix { |i, j| self[i, j][n] }
24
+ end
25
+ s
26
+ end
27
+
28
+ def e_deg
29
+ max = -1
30
+ each_ij do |i, j|
31
+ if !self[i, j].zero? && (d = self[i, j].deg) > max
32
+ max = d
33
+ end
34
+ end
35
+ max
36
+ end
37
+ end
38
+
39
+ module ElementaryDivisor
40
+ def e_inverse
41
+ raise 'not square matrix' unless rsize == csize
42
+ size = rsize
43
+ edm = to_triplet.e_diagonalize
44
+ if edm.body[size - 1, size - 1].unity?
45
+ edm.right * edm.left
46
+ else
47
+ puts 'elementary divisor matrix:'; edm.body.display
48
+ raise 'not invertible'
49
+ end
50
+ end
51
+
52
+ def elementary_divisor
53
+ e_diagonalize.diag
54
+ end
55
+
56
+ def e_diagonalize
57
+ dup.e_diagonalize!
58
+ end
59
+
60
+ def e_diagonalize!
61
+ size = rsize < csize ? rsize : csize
62
+ 0.upto size - 1 do |d|
63
+ el_sweep!(d)
64
+ end
65
+ self
66
+ end
67
+
68
+ def el_sweep!(d)
69
+ loop do
70
+ 1 while horizontal_sweep!(d) || vertical_sweep!(d)
71
+ if idx = sq_find_nondiv(d + 1, self[d, d])
72
+ i, _j = idx
73
+ mix_r!(d, i)
74
+ else
75
+ break
76
+ end
77
+ end
78
+ unless self[d, d].zero?
79
+ # row!(d)[d] = self[d, d].monic
80
+ divide_r!(d, _coeff(self[d, d]))
81
+ end
82
+ self
83
+ end
84
+
85
+ def el_sweep_old!(d)
86
+ loop do
87
+ sr = vertical_sweep!(d)
88
+ sc = horizontal_sweep!(d)
89
+ break unless sr || sc
90
+ next unless idx = sq_find_nondiv(d + 1, self[d, d])
91
+ i, _j = idx
92
+ mix_r!(d, i)
93
+ redo
94
+ end
95
+ unless self[d, d].zero?
96
+ # row!(d)[d] = self[d, d].monic
97
+ divide_r!(d, _coeff(self[d, d]))
98
+ end
99
+ self
100
+ end
101
+
102
+ def _coeff(sdd)
103
+ if ground <= Algebra::Polynomial
104
+ sdd.lc
105
+ elsif ground.field?
106
+ sdd
107
+ elsif ground.euclidian?
108
+ if ground <= Integer && sdd < 0
109
+ - ground.unity
110
+ elsif sdd.unit?
111
+ sdd
112
+ else
113
+ ground.unity
114
+ end
115
+ else
116
+ ground.unity
117
+ end
118
+ end
119
+
120
+ def sq_find_nondiv(d, x)
121
+ (d...rsize).each do |i|
122
+ (d...csize).each do |j|
123
+ return [i, j] unless (self[i, j] % x).zero?
124
+ end
125
+ end
126
+ nil
127
+ end
128
+
129
+ def vertical_sweep!(d)
130
+ sw = false
131
+ if self[d, d].zero? && (i = ((d + 1)...rsize).find { |i1| !self[i1, d].zero? })
132
+ sswap_r!(d, i)
133
+ sw = true
134
+ end
135
+ unless self[d, d].zero?
136
+ (d + 1...rsize).each do |i0|
137
+ next if self[i0, d].zero?
138
+ q = self[i0, d] / self[d, d]
139
+ sw = true
140
+ mix_r!(i0, d, -q)
141
+ # high speed but lost genericity (wo'nt work on triplet)
142
+ # r = row!(i0)
143
+ # (d...csize).each do |j0|; r[j0] -= q * self[d, j0]; end
144
+ unless self[i0, d].zero?
145
+ sswap_r!(d, i0)
146
+ redo
147
+ end
148
+ end
149
+ end
150
+ sw
151
+ end
152
+
153
+ def horizontal_sweep!(d)
154
+ m = transpose
155
+ if m.vertical_sweep!(d)
156
+ replace m.transpose
157
+ true
158
+ else
159
+ false
160
+ end
161
+ end
162
+
163
+ def self.factorize(eds)
164
+ prev = nil
165
+ qeds = []
166
+ eds.each do |f|
167
+ qeds << if prev
168
+ f / prev
169
+ else
170
+ f
171
+ end
172
+ prev = f
173
+ end
174
+
175
+ qeds_facts = qeds.collect(&:factorize)
176
+ result = []
177
+ prev = nil
178
+ qeds_facts.each do |fac|
179
+ prev = if prev
180
+ prev * fac
181
+ else
182
+ fac
183
+ end
184
+ result << prev
185
+ end
186
+ result
187
+ end
188
+ end
189
+
190
+ class MatrixAlgebra
191
+ include ElementaryDivisor
192
+ end
193
+ end