symbo 0.1.0pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'symbo/fraction'
4
+ require 'symbo/power'
5
+
6
+ module Symbo
7
+ class Sqrt
8
+ def self.[](x) # rubocop:disable Naming/MethodParameterName
9
+ Symbo::Power[x, Symbo::Fraction[1, 2]]
10
+ end
11
+ end
12
+
13
+ def √(x) # rubocop:disable Naming/MethodName, Naming/BinaryOperatorParameterName, Naming/MethodParameterName
14
+ Sqrt[x]
15
+ end
16
+ end
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'symbo/expression'
4
+ require 'symbo/factorial'
5
+ require 'symbo/function'
6
+ require 'symbo/mergeable'
7
+ require 'symbo/product'
8
+
9
+ module Symbo
10
+ # シンボリックな和
11
+ class Sum < Expression
12
+ include Mergeable
13
+
14
+ using Symbo
15
+
16
+ # :section: Power Transformation Methods
17
+
18
+ # べき乗の低
19
+ #
20
+ # (:x + :y).base # => :x + :y
21
+ def base
22
+ dup
23
+ end
24
+
25
+ # べき指数
26
+ #
27
+ # (:x + :y).exponent # => 1
28
+ def exponent
29
+ 1
30
+ end
31
+
32
+ # :section: Basic Distributive Transformation Methods
33
+
34
+ # 同類項の項部分
35
+ #
36
+ # (:x + :y).term # => Product[:x + :y]
37
+ def term
38
+ Product[self]
39
+ end
40
+
41
+ # 同類項の定数部分
42
+ #
43
+ # (:x + :y).const # => 1
44
+ def const
45
+ 1
46
+ end
47
+
48
+ # :section: Order Relation Methods
49
+
50
+ # 交換法則によるオペランド並べ替えに使う順序関係
51
+ #
52
+ # - 相手が和の場合
53
+ # 最右のオペランドから順に compare していき、異なるものがあればそれで順序を決定する。
54
+ # どちらかのオペランドがなくなれば、短いほうが左側。
55
+ #
56
+ # (:a + :b).compare(:a + :c) # => true
57
+ # Sum[:a, :c, :d].compare(Sum[:b, :c, :d]) # => true
58
+ # (:c + :d).compare(Sum[:b, :c, :d]) # => true
59
+ #
60
+ # - 階乗、関数、シンボルの場合
61
+ # 相手を単項の和にして比較
62
+ #
63
+ # (1 + :x).compare(:y) # => true
64
+ #
65
+ # - それ以外の場合
66
+ # 次のルールで比較
67
+ #
68
+ # !other.compare(self)
69
+ #
70
+ # rubocop:disable Metrics/CyclomaticComplexity
71
+ def compare(other)
72
+ case other
73
+ when Sum
74
+ return @operands.last.compare(other.operands.last) if @operands.last != other.operands.last
75
+
76
+ m = length
77
+ n = other.length
78
+ if [m, n].min >= 2
79
+ 1.upto([m, n].min) do |j|
80
+ return operand(m - j).compare(other.operand(n - j)) if operand(m - j) != other.operand(n - j)
81
+ end
82
+ end
83
+ m < n
84
+ when Factorial, Function, Symbol
85
+ compare Sum[other]
86
+ else
87
+ !other.compare(self)
88
+ end
89
+ end
90
+ # rubocop:enable Metrics/CyclomaticComplexity
91
+
92
+ # :section:
93
+
94
+ # rubocop:disable Metrics/PerceivedComplexity
95
+ # rubocop:disable Metrics/CyclomaticComplexity
96
+ def evaluate
97
+ v = @operands[0].evaluate
98
+ w = @operands[1].evaluate
99
+
100
+ if (v.integer? || v.complex?) && (w.integer? || w.complex?)
101
+ v.plus w
102
+ elsif v.constant? && w.constant?
103
+ Fraction[Sum[Product[v.numerator, w.denominator].evaluate, Product[w.numerator, v.denominator].evaluate].evaluate,
104
+ Product[v.denominator, w.denominator].evaluate].evaluate
105
+ else
106
+ Sum[v.simplify, w.simplify]
107
+ end
108
+ end
109
+ # rubocop:enable Metrics/PerceivedComplexity
110
+ # rubocop:enable Metrics/CyclomaticComplexity
111
+
112
+ def simplify_rational_number
113
+ self
114
+ end
115
+
116
+ def to_s
117
+ elements = @operands.map do |each|
118
+ case each
119
+ when Sum
120
+ if each.length > 1
121
+ [' + ', "(#{each})"]
122
+ else
123
+ [' + ', each.to_s]
124
+ end
125
+ when Product
126
+ if each.length > 1 && each.operand(0) == -1
127
+ [' - ', Product[*each.operands[1..-1]].to_s]
128
+ else
129
+ [' + ', each.to_s]
130
+ end
131
+ else
132
+ [' + ', each.to_s]
133
+ end
134
+ end
135
+ elements.flatten[1..-1].join
136
+ end
137
+
138
+ protected
139
+
140
+ def _simplify
141
+ return UNDEFINED if @operands.include?(UNDEFINED)
142
+ return operand(0) if length == 1
143
+
144
+ v = simplify_rec(@operands)
145
+ if v.size == 1
146
+ v[0]
147
+ elsif v.size > 1
148
+ Sum[*v]
149
+ else
150
+ 0
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ # rubocop:disable Metrics/PerceivedComplexity
157
+ # rubocop:disable Metrics/CyclomaticComplexity
158
+ def simplify_rec(l) # rubocop:disable Naming/MethodParameterName
159
+ case l
160
+ in Constant, Constant
161
+ p = Sum[*l].simplify_rne
162
+ p.zero? ? [] : [p]
163
+ in u1, u2 if u1.zero? && !u2.sum?
164
+ [u2]
165
+ in u1, u2 if u2.zero? && !u1.sum?
166
+ [u1]
167
+ in u1, u2 if l.none?(:sum?) && u1.term == u2.term
168
+ s = Sum[u1.const, u2.const].simplify
169
+ p = Product[u1.term, s].simplify
170
+ p.zero? ? [] : [p]
171
+ in u1, u2 if l.none?(&:sum?) && u2.compare(u1)
172
+ [u2, u1]
173
+ in _, _ if l.none?(&:sum?)
174
+ l
175
+ in Sum => u1, Sum => u2
176
+ merge u1.operands, u2.operands
177
+ in Sum => u1, u2
178
+ merge u1.operands, [u2]
179
+ in u1, Sum => u2
180
+ merge [u1], u2.operands
181
+ in Sum => u1, *rest
182
+ merge u1.operands, simplify_rec(rest)
183
+ in u1, *rest
184
+ merge [u1], simplify_rec(rest)
185
+ end
186
+ end
187
+ # rubocop:enable Metrics/PerceivedComplexity
188
+ # rubocop:enable Metrics/CyclomaticComplexity
189
+
190
+ # rubocop:disable Metrics/PerceivedComplexity
191
+ def simplify_rne_rec
192
+ if length == 1
193
+ v = operand(0).simplify_rne_rec
194
+ if v.undefined?
195
+ UNDEFINED
196
+ else
197
+ v
198
+ end
199
+ elsif length == 2
200
+ v = operand(0).simplify_rne_rec
201
+ w = operand(1).simplify_rne_rec
202
+ if v.undefined? || w.undefined?
203
+ UNDEFINED
204
+ else
205
+ Sum[v, w].evaluate
206
+ end
207
+ end
208
+ end
209
+ # rubocop:enable Metrics/PerceivedComplexity
210
+ end
211
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'symbo/algebraic_operators'
4
+ require 'symbo/expression_type'
5
+ require 'symbo/relational_operators'
6
+
7
+ module Symbo
8
+ refine Symbol do
9
+ include AlgebraicOperators
10
+ include ExpressionType
11
+ include RelationalOperators
12
+
13
+ # :section: Simplification Methods
14
+
15
+ def simplify
16
+ self
17
+ end
18
+
19
+ # :section: Power Transformation Methods
20
+
21
+ # べき乗の低
22
+ #
23
+ # :x.base # => :x
24
+ def base
25
+ self
26
+ end
27
+
28
+ # べき指数
29
+ #
30
+ # :x.exponent # => 1
31
+ def exponent
32
+ 1
33
+ end
34
+
35
+ # :section: Basic Distributive Transformation Methods
36
+
37
+ # 同類項の項部分
38
+ #
39
+ # :x.term # => Product[:x]
40
+ def term
41
+ Product[self]
42
+ end
43
+
44
+ # 同類項の定数部分
45
+ #
46
+ # :x.const # => 1
47
+ def const
48
+ 1
49
+ end
50
+
51
+ # :section: Order Relation Methods
52
+
53
+ # 交換法則によるオペランド並べ替えに使う順序関係
54
+ #
55
+ # - 相手がシンボルの場合
56
+ # 辞書順で順序を決定
57
+ #
58
+ # :a.compare(:b) # => true
59
+ # :A.compare(:a) # => true
60
+ # :v1.compare(:v2) # => true
61
+ # :x1.compare(:xa) # => true
62
+ #
63
+ # - それ以外の場合
64
+ # :x.compare(:x**2) # => true
65
+ # :x.compare(Function(:x, :t)) # => true
66
+ # :x.compare(Function(:y, :t)) # => true
67
+ def compare(other)
68
+ if other.is_a?(Symbol)
69
+ if self == :π
70
+ -1
71
+ else
72
+ self < other
73
+ end
74
+ else
75
+ !other.compare(self)
76
+ end
77
+ end
78
+
79
+ # :section: Relational Operator Methods
80
+
81
+ def ==(other)
82
+ other.is_a?(Symbol) && to_s == other.to_s
83
+ end
84
+
85
+ # :category: Simplification Methods
86
+
87
+ def simplify_rational_number
88
+ raise unless self == UNDEFINED
89
+
90
+ UNDEFINED
91
+ end
92
+ end
93
+ end
94
+
95
+ # Matrix などの中で使われる Symbol#+ などをハイジャック
96
+ class Symbol
97
+ include Symbo::ExpressionType
98
+
99
+ def +(other)
100
+ Symbo::Sum[self, other]
101
+ end
102
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Symbo
4
+ class TensorProduct
5
+ def self.[](matrix0, matrix1)
6
+ col_ms = (0...matrix0.column_size).map do |col|
7
+ ms = (0...matrix0.row_size).map do |row|
8
+ matrix0[row, col] * matrix1
9
+ end
10
+ Matrix.vstack(*ms)
11
+ end
12
+ Matrix.hstack(*col_ms)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'symbo/function'
4
+
5
+ module Symbo
6
+ class TrigonometricFunction < Function
7
+ using Symbo
8
+
9
+ def x
10
+ @operands[1]
11
+ end
12
+
13
+ def simplify
14
+ self.class.new(x.simplify)._simplify
15
+ end
16
+
17
+ private
18
+
19
+ # rubocop:disable Metrics/AbcSize
20
+ def kn_pi?
21
+ x.product? && x.length == 2 && x.operand(0).constant? && x.operand(1) == PI &&
22
+ [1, 2, 3, 4, 6].include?(x.operand(0).denominator) && x.operand(0).numerator.integer?
23
+ end
24
+ # rubocop:enable Metrics/AbcSize
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Symbo
4
+ VERSION = '0.1.0pre'
5
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'symbo/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'symbo'
10
+ spec.version = Symbo::VERSION
11
+ spec.authors = ['Yasuhito Takamiya']
12
+ spec.email = ['yasuhito@gmail.com']
13
+
14
+ spec.summary = 'A simple CAS (computer algebra system) in Ruby'
15
+ spec.homepage = 'https://github.com/yasuhito/symbo'
16
+ spec.license = 'MIT'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/yasuhito/symbo'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/yasuhito/symbo/blob/develop/CHANGELOG.md'
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_development_dependency 'bundler'
32
+ spec.add_development_dependency 'rake'
33
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: symbo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0pre
5
+ platform: ruby
6
+ authors:
7
+ - Yasuhito Takamiya
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - yasuhito@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".github/workflows/ruby.yml"
49
+ - ".gitignore"
50
+ - ".rubocop.yml"
51
+ - ".ruby-version"
52
+ - CHANGELOG.md
53
+ - Gemfile
54
+ - Gemfile.lock
55
+ - LICENSE
56
+ - README.md
57
+ - Rakefile
58
+ - bin/console
59
+ - bin/setup
60
+ - lib/symbo.rb
61
+ - lib/symbo/algebraic_operators.rb
62
+ - lib/symbo/complex.rb
63
+ - lib/symbo/constant.rb
64
+ - lib/symbo/cos.rb
65
+ - lib/symbo/diff.rb
66
+ - lib/symbo/e.rb
67
+ - lib/symbo/expression.rb
68
+ - lib/symbo/expression_type.rb
69
+ - lib/symbo/factorial.rb
70
+ - lib/symbo/float.rb
71
+ - lib/symbo/fraction.rb
72
+ - lib/symbo/function.rb
73
+ - lib/symbo/integer.rb
74
+ - lib/symbo/matrix.rb
75
+ - lib/symbo/mergeable.rb
76
+ - lib/symbo/pi.rb
77
+ - lib/symbo/power.rb
78
+ - lib/symbo/product.rb
79
+ - lib/symbo/qubit.rb
80
+ - lib/symbo/quot.rb
81
+ - lib/symbo/relational_operators.rb
82
+ - lib/symbo/sin.rb
83
+ - lib/symbo/sqrt.rb
84
+ - lib/symbo/sum.rb
85
+ - lib/symbo/symbol.rb
86
+ - lib/symbo/tensor_product.rb
87
+ - lib/symbo/trigonometric_function.rb
88
+ - lib/symbo/version.rb
89
+ - symbo.gemspec
90
+ homepage: https://github.com/yasuhito/symbo
91
+ licenses:
92
+ - MIT
93
+ metadata:
94
+ homepage_uri: https://github.com/yasuhito/symbo
95
+ source_code_uri: https://github.com/yasuhito/symbo
96
+ changelog_uri: https://github.com/yasuhito/symbo/blob/develop/CHANGELOG.md
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.3.1
111
+ requirements: []
112
+ rubygems_version: 3.1.2
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: A simple CAS (computer algebra system) in Ruby
116
+ test_files: []