abst 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,155 @@
1
+ class Rational
2
+ def self.one
3
+ return Rational(1, 1)
4
+ end
5
+
6
+ def self.zero
7
+ return Rational(0, 1)
8
+ end
9
+
10
+ def inverse
11
+ return 1 / self
12
+ end
13
+
14
+ # to repeating decimal string
15
+ def to_rds(base = 10)
16
+ raise ArgumentError, "invalid radix #{base}" if base < 2 or 36 < base
17
+
18
+ # initialize
19
+ quotient = []
20
+
21
+ n = numerator.to_s(base).split('').map(&:to_i)
22
+ exp = 0
23
+ while 0 == n.last
24
+ n.pop
25
+ exp += 1
26
+ end
27
+ d = denominator
28
+ loop do
29
+ q, r = d.divmod(base)
30
+ break unless 0 == r
31
+ d = q
32
+ exp -= 1
33
+ end
34
+ t = n[0]
35
+
36
+ # division loop
37
+ i = 1
38
+ loop do
39
+ q, r = t.divmod(d)
40
+ t = r * base + n[i].to_i
41
+
42
+ quotient.push([q, nil])
43
+
44
+ unless n[i]
45
+ if 0 == t
46
+ quotient.last[1] = 0
47
+ break
48
+ end
49
+ break if quotient.map(&:last).include?(t)
50
+ quotient.last[1] = t
51
+ end
52
+
53
+ i += 1
54
+ end
55
+
56
+ # format
57
+ rslt = "0."
58
+
59
+ zero_count = 0
60
+ while 0 == quotient[0][0]
61
+ zero_count += 1
62
+ if t == quotient.shift[1]
63
+ rslt += '('
64
+
65
+ # rotate 0
66
+ while 0 == quotient[0][0]
67
+ quotient.push(quotient.shift)
68
+ zero_count += 1
69
+ end
70
+ break
71
+ end
72
+ end
73
+ exp += n.size - zero_count
74
+
75
+ convert = "0123456789abcdefghijklmnopqrstuvwxyz"
76
+ if 0 == quotient.last[1]
77
+ rslt += quotient.map{|q| convert[q[0]]}.inject(&:+)
78
+ else
79
+ quotient.each do |q|
80
+ rslt += convert[q[0]]
81
+ rslt += '(' if t == q[1]
82
+ end
83
+ rslt += ")"
84
+ end
85
+ rslt += "e" + exp.to_s unless 0 == exp
86
+
87
+ return rslt
88
+ end
89
+
90
+ # to decimal string
91
+ def to_ds(length = 64, base = 10)
92
+ raise ArgumentError, "invalid radix #{base}" if base < 2 or 36 < base
93
+
94
+ # initialize
95
+ quotient = []
96
+
97
+ n = numerator.to_s(base).split('').map(&:to_i)
98
+ exp = 0
99
+ while 0 == n.last
100
+ n.pop
101
+ exp += 1
102
+ end
103
+ d = denominator
104
+ loop do
105
+ q, r = d.divmod(base)
106
+ break unless 0 == r
107
+ d = q
108
+ exp -= 1
109
+ end
110
+ t = n[0]
111
+
112
+ # division loop
113
+ i = 1
114
+ s = nil
115
+ loop do
116
+ q, r = t.divmod(d)
117
+ t = r * base + n[i].to_i
118
+
119
+ s = i - 1 if nil == s and q != 0
120
+ quotient.push([q, nil])
121
+
122
+ unless n[i]
123
+ if 0 == t
124
+ quotient.last[1] = 0
125
+ break
126
+ end
127
+ break if s and i - s == length
128
+ quotient.last[1] = t
129
+ end
130
+
131
+ i += 1
132
+ end
133
+
134
+ # format
135
+ zero_count = 0
136
+ while 0 == quotient[0][0]
137
+ zero_count += 1
138
+ if t == quotient.shift[1]
139
+ # rotate 0
140
+ while 0 == quotient[0][0]
141
+ quotient.push(quotient.shift)
142
+ zero_count += 1
143
+ end
144
+ break
145
+ end
146
+ end
147
+ exp += n.size - zero_count
148
+
149
+ convert = "0123456789abcdefghijklmnopqrstuvwxyz"
150
+ rslt = "0." + quotient.map{|q| convert[q[0]]}.inject(&:+)
151
+ rslt += "e" + exp.to_s unless 0 == exp
152
+
153
+ return rslt
154
+ end
155
+ end
@@ -0,0 +1,27 @@
1
+ module Abst
2
+ module_function
3
+
4
+ def residue_class(ideal)
5
+ if prime?(ideal.n)
6
+ return residue_class_field(ideal)
7
+ else
8
+ return residue_class_ring(ideal)
9
+ end
10
+ end
11
+
12
+ def residue_class_ring(ideal)
13
+ residue_class = Class.new(IntegerResidueRing) do
14
+ @mod = ideal.n
15
+ end
16
+
17
+ return residue_class
18
+ end
19
+
20
+ def residue_class_field(maximal_ideal)
21
+ residue_class = Class.new(IntegerResidueField) do
22
+ @mod = maximal_ideal.n
23
+ end
24
+
25
+ return residue_class
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module Abst
2
+ module Ring
3
+ def self.included(base)
4
+ base.class_eval do
5
+ include Abst::Group
6
+ end
7
+ end
8
+
9
+ def /(other)
10
+ return self.divmod(other)[0]
11
+ end
12
+
13
+ def %(other)
14
+ return self.divmod(other)[1]
15
+ end
16
+
17
+ def **(e)
18
+ return Abst.power(self, e)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ module Abst
2
+ module_function
3
+
4
+ $fibonacci = {0 => 0, 1 => 1}
5
+
6
+ # Param:: non-negative integer n
7
+ # Return:: the n-th Fibonacci number
8
+ # effect $fibonacci[n] = fibonacci(n)
9
+ def fibonacci(n)
10
+ return $fibonacci[n] if $fibonacci.include?(n)
11
+
12
+ m = n >> 1
13
+ if n.even?
14
+ f1 = fibonacci(m - 1)
15
+ f2 = fibonacci(m)
16
+ $fibonacci[n] = (f1 + f1 + f2) * f2
17
+ else
18
+ f1 = fibonacci(m)
19
+ f2 = fibonacci(m + 1)
20
+ $fibonacci[n] = f1 ** 2 + f2 ** 2
21
+ end
22
+
23
+ return $fibonacci[n]
24
+ end
25
+
26
+ # Triangle numbers are generated by the formula, T_n = n * (n + 1) / 2.
27
+ # The first ten triangle numbers are:
28
+ # 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
29
+ def triangle(n)
30
+ return n * (n + 1) >> 1
31
+ end
32
+
33
+ # Pentagonal numbers are generated by the formula, P_n = n * (3 * n - 1) / 2.
34
+ # The first ten pentagonal numbers are:
35
+ # 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...
36
+ def pentagonal(n)
37
+ return n * (3 * n - 1) >> 1
38
+ end
39
+
40
+ # Hexagonal numbers are generated by the formula, H_n = n * (2 * n - 1)
41
+ # The first ten hexagonal numbers are:
42
+ # 1, 6, 15, 28, 45, 66, 91, 120, 153, 190, ...
43
+ def hexagonal(n)
44
+ return n * ((n << 1) - 1)
45
+ end
46
+
47
+ def heptagonal(n)
48
+ return n * (5 * n - 3) >> 1
49
+ end
50
+
51
+ def octagonal(n)
52
+ return n * (3 * n - 2)
53
+ end
54
+ end
@@ -0,0 +1,67 @@
1
+ class Set
2
+ include Enumerable
3
+
4
+ def initialize(ary = [])
5
+ @set = ary.uniq
6
+ end
7
+
8
+ def add(*items)
9
+ items.each do |i|
10
+ @set.push(i) unless @set.include?(i)
11
+ end
12
+ return self
13
+ end
14
+
15
+ def ==(other)
16
+ return false unless self.size == other.size
17
+ @set.each do |i|
18
+ return false unless other.include?(i)
19
+ end
20
+
21
+ return true
22
+ end
23
+
24
+ def each(&block)
25
+ @set.each(&block)
26
+ end
27
+
28
+ def size
29
+ @set.size
30
+ end
31
+
32
+ def dup
33
+ self.class.new(@set.dup)
34
+ end
35
+
36
+ def include?(a)
37
+ @set.include?(a)
38
+ end
39
+
40
+ def inspect
41
+ str = @set.inspect[1..-2]
42
+ return "{" + str + "}"
43
+ end
44
+
45
+ def to_a
46
+ return @set
47
+ end
48
+ end
49
+
50
+ class SortableSet < Set
51
+ def initialize(ary = [], &compare)
52
+ @set = ary.uniq.sort(&compare)
53
+ @compare = compare
54
+ end
55
+
56
+ def add(*items)
57
+ items.each do |i|
58
+ j = Bisect.bisect_left(@set, i, &@compare)
59
+ @set.insert(j, i) unless @set[j] == i
60
+ end
61
+ return self
62
+ end
63
+
64
+ def dup
65
+ self.class.new(@set.dup, &@compare)
66
+ end
67
+ end
@@ -0,0 +1,90 @@
1
+ module Abst
2
+ module_function
3
+
4
+ class Vector
5
+ class << self
6
+ attr_reader :coef_class, :size
7
+
8
+ def to_s
9
+ return "#{size} length #{self.coef_class} Vector"
10
+ end
11
+
12
+ def inspect
13
+ return to_s
14
+ end
15
+ end
16
+
17
+ attr_reader :coef
18
+ protected :coef
19
+
20
+ def initialize(coef)
21
+ raise VectorSizeError unless coef.size == self.class.size
22
+ @coef = coef.to_a
23
+ end
24
+
25
+ def +(other)
26
+ raise VectorSizeError unless self.size == other.size
27
+ return self.class.new(self.coef.zip(other.coef).map{|a, b| a + b})
28
+ end
29
+
30
+ def -(other)
31
+ raise VectorSizeError unless self.size == other.size
32
+ return self.class.new(self.coef.zip(other.coef).map{|a, b| a - b})
33
+ end
34
+
35
+ def ==(other)
36
+ return @coef == other.to_a
37
+ end
38
+
39
+ def size
40
+ return self.class.size
41
+ end
42
+
43
+ def each
44
+ return Enumerator.new(self) unless block_given?
45
+
46
+ @coef.each do |i|
47
+ yield i
48
+ end
49
+ end
50
+
51
+ def squared_length
52
+ return self.coef.map{|i| i ** 2}.inject(&:+)
53
+ end
54
+
55
+ def [](index)
56
+ return @coef[index]
57
+ end
58
+
59
+ def to_a
60
+ return @coef.dup
61
+ end
62
+
63
+ def to_s
64
+ return @coef.to_s
65
+ end
66
+
67
+ def inspect
68
+ return "#{self.class}\n#{self}"
69
+ end
70
+ end
71
+
72
+ def create_vector_space(coef_class, size)
73
+ if size.kind_of?(Array)
74
+ elems = size
75
+ size = size.size
76
+ end
77
+
78
+ vector = Class.new(Vector) do
79
+ @coef_class = coef_class
80
+ @size = size
81
+ end
82
+
83
+ return vector.new(elems) if elems
84
+ return vector
85
+ end
86
+ alias Vector create_vector_space
87
+ module_function :Vector
88
+
89
+ class VectorSizeError < Exception; end
90
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'test_array'
2
+ require_relative 'test_bisect'
3
+ require_relative 'test_combination'
4
+ require_relative 'test_float'
5
+ require_relative 'test_fundamental'
6
+ require_relative 'test_group'
7
+ require_relative 'test_integer'
8
+ require_relative 'test_matrix'
9
+ require_relative 'test_polynomial'
10
+ require_relative 'test_prime'
11
+ require_relative 'test_prime_mpqs'
12
+ require_relative 'test_rational'
13
+ require_relative 'test_sequence'
14
+ require_relative 'test_set'
15
+ require_relative 'test_vector'
@@ -0,0 +1,10 @@
1
+ require 'minitest/unit'
2
+ require 'minitest/autorun'
3
+ require 'abst'
4
+
5
+ class TC_Array < MiniTest::Unit::TestCase
6
+ def test_each_coefficient
7
+ assert_equal([[0, 0], [0, 1], [1, 0], [1, 1]].sort,
8
+ [1, 1].each_coefficient.to_a.sort)
9
+ end
10
+ end