ragni-cas 0.2.2 → 0.2.3

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.
data/lib/fnc-branch.rb DELETED
@@ -1,388 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- module CAS
4
- class Piecewise < CAS::BinaryOp
5
- attr_reader :condition
6
-
7
- def initialize(x, y, condition)
8
- CAS::Help.assert(condition, CAS::Condition)
9
-
10
- super(x, y)
11
- @condition = condition
12
- end
13
-
14
- def diff(v)
15
- CAS::Help.assert(v, CAS::Op)
16
-
17
- return CAS::Piecewise.new(@x.diff(v).simplify, @y.diff(v).simplify, condition)
18
- end
19
-
20
- def call(fd)
21
- CAS::Help.assert(fd, Hash)
22
-
23
- (@condition.call(fd) ? @x.call(fd) : @y.call(fd))
24
- end
25
-
26
- def ==(op)
27
- CAS::Help.assert(op, CAS::Op)
28
-
29
- if self.class != op.class
30
- return false
31
- else
32
- return ((@x == op.x) and (@y == op.y) and (@condition == op.condition))
33
- end
34
- end
35
-
36
- def to_code
37
- "(#{@condition.to_code} ? (#{@x.to_code}) : (#{@y.to_code}))"
38
- end
39
-
40
- def to_s
41
- "(#{@condition} ? #{@x} : #{@y})"
42
- end
43
-
44
- def dot_graph(node)
45
- cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
46
- "#{cls} -> #{@x.dot_graph node}\n #{cls} -> #{@y.dot_graph node}\n #{cls} -> #{@condition.dot_graph node}"
47
- end
48
-
49
- def to_latex
50
- "\\left\\{ \\begin{array}{lr} #{@x.to_latex} & #{@condition.to_latex} \\\\ #{@y.to_latex} \\end{array} \\right."
51
- end
52
- end
53
-
54
-
55
- def self.max(x, y)
56
- CAS::Piecewise.new(x, y, CAS::greater_equal(x, y))
57
- end
58
-
59
- def self.min(x, y)
60
- CAS::Piecewise.new(x, y, CAS::smaller_equal(x, y))
61
- end
62
-
63
- class Condition
64
- attr_reader :x, :y, :type
65
-
66
- def initialize(type, x, y)
67
- CAS::Help.assert(type, Symbol)
68
-
69
- @x = x
70
- @y = y
71
- case type
72
- when :eq
73
- @type = "=="
74
- self.define_singleton_method("call") do |fd|
75
- @x.call(fd) == @y.call(fd)
76
- end
77
- when :gt
78
- @type = ">"
79
- self.define_singleton_method("call") do |fd|
80
- @x.call(fd) > @y.call(fd)
81
- end
82
- when :lt
83
- @type = "<"
84
- self.define_singleton_method("call") do |fd|
85
- @x.call(fd) < @y.call(fd)
86
- end
87
- when :geq
88
- @type = "≥"
89
- self.define_singleton_method("call") do |fd|
90
- @x.call(fd) >= @y.call(fd)
91
- end
92
- when :leq
93
- @type = "≤"
94
- self.define_singleton_method("call") do |fd|
95
- @x.call(fd) <= @y.call(fd)
96
- end
97
- else
98
- raise CASError, "Unknown condition #{@type}"
99
- end
100
- end
101
-
102
- def inspect
103
- "#{@x.inspect} #{@type} #{@y.inspect}"
104
- end
105
-
106
- def to_s
107
- "#{@x} #{@type} #{@y}"
108
- end
109
-
110
- def to_code
111
- "#{@x}.call(fd) #{@type} #{@y}.call(fd)"
112
- end
113
-
114
- def args
115
- (@x.args + @y.args).uniq
116
- end
117
-
118
- def diff(v)
119
- @x.diff(v)
120
- @y.diff(v)
121
- self.simplify
122
- end
123
-
124
- def depend?(v)
125
- @x.depend?(v) or @y.depend?(v)
126
- end
127
-
128
- def ==(op)
129
- CAS::Help.assert(op, CAS::Op)
130
- condA = (@x == op.x) and (@y == op.y)
131
- condB = (@x == op.y) and (@y == op.x)
132
- condC = condA or condB
133
- return (condC and (self.class == op.class) and (@type == op.type))
134
- end
135
-
136
- def !=(op)
137
- not self == op
138
- end
139
-
140
- def simplify
141
- @x.simplify
142
- @y.simplify
143
- return self
144
- end
145
-
146
- def subs(fd)
147
- CAS::Help.assert(fd, Hash)
148
- @x.subs(fd)
149
- @y.subs(fd)
150
- return self
151
- end
152
-
153
- def dot_graph(node)
154
- cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
155
- "#{cls} -> #{@x.dot_graph node}\n #{cls} -> #{@y.dot_graph node}"
156
- end
157
- end # Condition
158
-
159
- class Equal < CAS::Condition
160
- def initialize(x, y)
161
- super(:eq, x, y)
162
- end
163
-
164
- def to_latex
165
- "#{@x.to_latex} = #{@y.to_latex}"
166
- end
167
- end # Equal
168
-
169
- class Greater < CAS::Condition
170
- def initialize(x, y)
171
- super(:gt, x, y)
172
- end
173
-
174
- def to_latex
175
- "#{@x.to_latex} > #{@y.to_latex}"
176
- end
177
- end # Greater
178
-
179
- class GreaterEqual < CAS::Condition
180
- def initialize(x, y)
181
- super(:geq, x, y)
182
- end
183
-
184
- def to_latex
185
- "#{@x.to_latex} \\geq #{@y.to_latex}"
186
- end
187
- end # GreaterEqual
188
-
189
- class Smaller < CAS::Condition
190
- def initialize(x, y)
191
- super(:lt, x, y)
192
- end
193
-
194
- def to_latex
195
- "#{@x.to_latex} < #{@y.to_latex}"
196
- end
197
- end # Smaller
198
-
199
- class SmallerEqual < CAS::Condition
200
- def initialize(x, y)
201
- super(:leq, x, y)
202
- end
203
-
204
- def to_latex
205
- "#{@x.to_latex} \\leq #{@y.to_latex}"
206
- end
207
- end # SmallerEqual
208
-
209
- class BoxCondition < CAS::Condition
210
- attr_reader :x, :lower, :upper
211
-
212
- def initialize(x, lower, upper, type=:closed)
213
- if lower.is_a? Numeric
214
- lower = CAS::const lower
215
- end
216
- if upper.is_a? Numeric
217
- upper = CAS::const upper
218
- end
219
- CAS::Help.assert(lower, CAS::Constant)
220
- CAS::Help.assert(upper, CAS::Constant)
221
-
222
- CAS::Help.assert(x, CAS::Op)
223
- CAS::Help.assert(type, Symbol)
224
-
225
- lower, upper = upper, lower if lower.x > upper.x
226
-
227
- @lower = lower
228
- @upper = upper
229
- @x = x
230
-
231
- case type
232
- when :open
233
- self.define_singleton_method :call do |fd|
234
- (@lower.call(fd) < @x.call(fd)) and (@x.call(fd) < @upper.call(fd))
235
- end
236
- self.define_singleton_method :inspect do
237
- "#{@lower.inspect} < #{@x.inspect} < #{@upper.inspect}"
238
- end
239
- self.define_singleton_method :to_s do
240
- "#{@lower} < #{@x} < #{@upper}"
241
- end
242
- self.define_singleton_method :to_code do
243
- "(#{@lower.to_code} < #{@x.to_code} and #{@x.to_code} < #{@upper.to_code}"
244
- end
245
- self.define_singleton_method :to_latex do
246
- "#{@lower.to_latex} < #{@x.to_latex} < #{@upper.to_latex}"
247
- end
248
- when :closed
249
- self.define_singleton_method :call do |fd|
250
- (@lower.call(fd) <= @x.call(fd)) and (@x.call(fd) <= @upper.call(fd))
251
- end
252
- self.define_singleton_method :inspect do
253
- "#{@lower.inspect} ≤ #{@x.inspect} ≤ #{@upper.inspect}"
254
- end
255
- self.define_singleton_method :to_s do
256
- "#{@lower} ≤ #{@x} ≤ #{@upper}"
257
- end
258
- self.define_singleton_method :to_code do
259
- "(#{@lower.to_code} <= #{@x.to_code} and #{@x.to_code} <= #{@upper.to_code}"
260
- end
261
- self.define_singleton_method :to_latex do
262
- "#{@lower.to_latex} \\leq #{@x.to_latex} \\leq #{@upper.to_latex}"
263
- end
264
- when :upper_closed
265
- self.define_singleton_method :call do |fd|
266
- (@lower.call(fd) < @x.call(fd)) and (@x.call(fd) <= @upper.call(fd))
267
- end
268
- self.define_singleton_method :inspect do
269
- "#{@lower.inspect} < #{@x.inspect} ≤ #{@upper.inspect}"
270
- end
271
- self.define_singleton_method :to_s do
272
- "#{@lower} < #{@x} ≤ #{@upper}"
273
- end
274
- self.define_singleton_method :to_code do
275
- "(#{@lower.to_code} < #{@x.to_code} and #{@x.to_code} <= #{@upper.to_code}"
276
- end
277
- self.define_singleton_method :to_latex do
278
- "#{@lower.to_latex} < #{@x.to_latex} \\leq #{@upper.to_latex}"
279
- end
280
- when :lower_closed
281
- self.define_singleton_method :call do |fd|
282
- (@lower.call(fd) <= @x.call(fd)) and (@x.call(fd) < @upper.call(fd))
283
- end
284
- self.define_singleton_method :inspect do
285
- "#{@lower.inspect} ≤ #{@x.inspect} < #{@upper.inspect}"
286
- end
287
- self.define_singleton_method :to_s do
288
- "#{@lower} ≤ #{@x} < #{@upper}"
289
- end
290
- self.define_singleton_method :to_code do
291
- "(#{@lower.to_code} <= #{@x.to_code} and #{@x.to_code} < #{@upper.to_code}"
292
- end
293
- self.define_singleton_method :to_latex do
294
- "#{@lower.to_latex} \\leq #{@x.to_latex} < #{@upper.to_latex}"
295
- end
296
- else
297
- raise ArgumentError, "Unknown type of box condition"
298
- end
299
- end
300
-
301
- def depend?(v)
302
- @x.depend? v
303
- end
304
-
305
- def simplify
306
- @x.simplify
307
- return self
308
- end
309
-
310
- def subs(fd)
311
- @x = @x.subs(fd)
312
- return self
313
- end
314
-
315
- def diff(v)
316
- CAS::equal(@x.diff(x).simplify, CAS::Zero)
317
- end
318
-
319
- def dot_graph(node)
320
- cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
321
- " #{cls} -> #{@lower.dot_graph node}\n #{cls} -> #{@x.dot_graph node}\n #{cls} -> #{@upper.dot_graph node}\n"
322
- end
323
-
324
- def ==(cond)
325
- return false if not self.class != cond.class
326
- return (@x == cond.x and @lower == cond.lower and @upper == cond.upper)
327
- end
328
-
329
- def !=(cond)
330
- not self == cond
331
- end
332
- end # BoxCondition
333
-
334
- class BoxConditionOpen < CAS::BoxCondition
335
- def initialize(x, a, b)
336
- super x, a, b, :open
337
- end
338
- end
339
-
340
- class BoxConditionClosed < CAS::BoxCondition
341
- def initialize(x, a, b)
342
- super x, a, b, :closed
343
- end
344
- end
345
-
346
- class BoxConditionUpperClosed < CAS::BoxCondition
347
- def initialize(x, a, b)
348
- super x, a, b, :upper_closed
349
- end
350
- end
351
-
352
- class BoxConditionLowerClosed < CAS::BoxCondition
353
- def initialize(x, a, b)
354
- super x, a, b, :lower_closed
355
- end
356
- end
357
-
358
- def self.equal(x, y); CAS::Equal.new(x, y); end
359
- def self.greater(x, y); CAS::Greater.new(x, y); end
360
- def self.greater_equal(x, y); CAS::GreaterEqual.new(x, y); end
361
- def self.smaller(x, y); CAS::Smaller.new(x, y); end
362
- def self.smaller_equal(x, y); CAS::SmallerEqual.new(x, y); end
363
-
364
- def self.box(x, a, b, type=:closed)
365
- case type
366
- when :closed
367
- return CAS::BoxConditionClosed.new(x, a, b)
368
- when :open
369
- return CAS::BoxConditionOpen.new(x, a, b)
370
- when :upper_closed
371
- return CAS::BoxConditionUpperClosed.new(x, a, b)
372
- when :lower_closed
373
- return CAS::BoxConditionLowerClosed.new(x, a, b)
374
- else
375
- raise CAS::CASError, "Unknown box condition type"
376
- end
377
- end
378
-
379
- class Op
380
- def equal(v); CAS.equal(self, v); end
381
- def greater(v); CAS.greater(self, v); end
382
- def smaller(v); CAS.smaller(self, v); end
383
- def greater_equal(v); CAS.greater_equal(self, v); end
384
- def smaller_equal(v); CAS.smaller_equal(self, v); end
385
-
386
- def limit(a, b, type=:closed); CAS.box(self, a, b, type); end
387
- end
388
- end
data/lib/fnc-trig.rb DELETED
@@ -1,336 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- module CAS
4
- # ___ _
5
- # / __(_)_ _
6
- # \__ \ | ' \
7
- # |___/_|_||_|
8
- class Sin < CAS::Op
9
- def diff(v)
10
- if @x.depend? v
11
- return @x.diff(v) * CAS.cos(@x)
12
- else
13
- return CAS::Zero
14
- end
15
- end
16
-
17
- # Same as `CAS::Op`
18
- def call(f)
19
- CAS::Help.assert(f, Hash)
20
-
21
- Math::sin @x.call(f)
22
- end
23
-
24
- # Same as `CAS::Op`
25
- def to_s
26
- "sin(#{@x})"
27
- end
28
-
29
- # Same as `CAS::Op`
30
- def simplify
31
- super
32
- if @x == CAS::Zero
33
- return CAS::Zero
34
- end
35
- if @x == CAS::Pi
36
- return CAS::Zero
37
- end
38
- if @x.is_a? CAS::Asin
39
- return @x.x
40
- end
41
- return self
42
- end
43
-
44
- # Same as `CAS::Op`
45
- def to_code
46
- "Math::sin(#{@x.to_code})"
47
- end
48
-
49
- # Return latex representation of current Op
50
- def to_latex
51
- "\\sin\\left( #{@x.to_latex} \\right)"
52
- end
53
- end # Sin
54
-
55
- def self.sin(x)
56
- CAS::Sin.new x
57
- end
58
-
59
- # _ _
60
- # /_\ __(_)_ _
61
- # / _ \ (_-< | ' \
62
- # /_/ \_\/__/_|_||_|
63
- class Asin < CAS::Op
64
- def diff(v)
65
- if @x.depend? v
66
- return @x.diff(v) / CAS.sqrt(CAS::One - CAS.pow(@x, CAS::Two))
67
- else
68
- return CAS::Zero
69
- end
70
- end
71
-
72
- # Same as `CAS::Op`
73
- def call(f)
74
- CAS::Help.assert(f, Hash)
75
-
76
- Math::acos @x.call(f)
77
- end
78
-
79
- # Same as `CAS::Op`
80
- def to_s
81
- "asin(#{@x})"
82
- end
83
-
84
- # Same as `CAS::Op`
85
- def simplify
86
- super
87
- if @x == CAS::Zero
88
- return CAS::Zero
89
- end
90
- if @x == CAS::One
91
- return CAS::Pi / 2
92
- end
93
- if @x.is_a? CAS::Sin
94
- return @x.x
95
- end
96
- return self
97
- end
98
-
99
- # Same as `CAS::Op`
100
- def to_code
101
- "Math::asin(#{@x.to_code})"
102
- end
103
-
104
- # Return latex representation of current Op
105
- def to_latex
106
- "\\arcsin\\left( #{@x.to_latex} \\right)"
107
- end
108
- end
109
-
110
- def self.asin(x)
111
- CAS::Asin.new x
112
- end
113
-
114
- # ___
115
- # / __|___ ___
116
- # | (__/ _ (_-<
117
- # \___\___/__/
118
- class Cos < CAS::Op
119
- def diff(v)
120
- if @x.depend? v
121
- return CAS.invert(@x.diff(v) * CAS.sin(@x))
122
- else
123
- return CAS::Zero
124
- end
125
- end
126
-
127
- # Same as `CAS::Op`
128
- def call(f)
129
- CAS::Help.assert(f, Hash)
130
-
131
- Math::cos @x.call(f)
132
- end
133
-
134
- # Same as `CAS::Op`
135
- def to_s
136
- "cos(#{@x})"
137
- end
138
-
139
- # Same as `CAS::Op`
140
- def simplify
141
- super
142
- if @x == CAS::Zero
143
- return CAS::One
144
- end
145
- if @x == CAS::Pi
146
- return CAS::One
147
- end
148
- if @x.is_a? CAS::Acos
149
- return @x.x
150
- end
151
- return self
152
- end
153
-
154
- # Same as `CAS::Op`
155
- def to_code
156
- "Math::cos(#{@x.to_code})"
157
- end
158
-
159
- # Return latex representation of current Op
160
- def to_latex
161
- "\\cos\\left( #{@x.to_latex} \\right)"
162
- end
163
- end
164
-
165
- def self.cos(x)
166
- CAS::Cos.new x
167
- end
168
-
169
- # _
170
- # /_\ __ ___ ___
171
- # / _ \/ _/ _ (_-<
172
- # /_/ \_\__\___/__/
173
- class Acos < CAS::Op
174
- def diff(v)
175
- if @x.depend? v
176
- return CAS.invert(@x.diff(v)/CAS.sqrt(CAS::One - CAS.pow(@x, CAS::Two)))
177
- else
178
- return CAS::Zero
179
- end
180
- end
181
-
182
- # Same as `CAS::Op`
183
- def call(f)
184
- CAS::Help.assert(f, Hash)
185
-
186
- return Math::acos @x
187
- end
188
-
189
- # Same as `CAS::Op`
190
- def to_s
191
- "acos(#{@x})"
192
- end
193
-
194
- # Same as `CAS::Op`
195
- def simplify
196
- super
197
- if @x == CAS::Zero
198
- return CAS::Pi / 2
199
- end
200
- if @x == CAS::One
201
- return CAS::Zero
202
- end
203
- if @x.is_a? CAS::Cos
204
- return @x.x
205
- end
206
- return self
207
- end
208
-
209
- # Same as `CAS::Op`
210
- def to_code
211
- "Math::acos(#{@x.to_code})"
212
- end
213
-
214
- # Return latex representation of current Op
215
- def to_latex
216
- "\\arccos\\left( #{@x.to_latex} \\right)"
217
- end
218
- end
219
-
220
- def self.acos(x)
221
- CAS::Acos.new x
222
- end
223
-
224
- # _____
225
- # |_ _|_ _ _ _
226
- # | |/ _` | ' \
227
- # |_|\__,_|_||_|
228
- class Tan < CAS::Op
229
- def diff(v)
230
- if @x.depend? v
231
- return @x.diff(v) * CAS.pow(CAS::One/CAS.cos(@x), CAS::Two)
232
- else
233
- return CAS::Zero
234
- end
235
- end
236
-
237
- # Same as `CAS::Op`
238
- def call(f)
239
- CAS::Help.assert(f, Hash)
240
-
241
- Math::tan @x.call
242
- end
243
-
244
- # Same as `CAS::Op`
245
- def to_s
246
- "tan(#{@x})"
247
- end
248
-
249
- # Same as `CAS::Op`
250
- def simplify
251
- super
252
- if @x == CAS::Zero
253
- return CAS::Zero
254
- end
255
- if @x == CAS::Pi
256
- return CAS::Zero
257
- end
258
- if @x.is_a? CAS::Atan
259
- return @x.x
260
- end
261
- return self
262
- end
263
-
264
- # Same as `CAS::Op`
265
- def to_code
266
- "Math::tan(#{@x.to_code})"
267
- end
268
-
269
- # Return latex representation of current Op
270
- def to_latex
271
- "\\tan\\left( #{@x.to_latex} \\right)"
272
- end
273
- end
274
-
275
- def self.tan(x)
276
- CAS::Tan.new x
277
- end
278
-
279
- # _ _
280
- # /_\| |_ __ _ _ _
281
- # / _ \ _/ _` | ' \
282
- # /_/ \_\__\__,_|_||_|
283
- class Atan < CAS::Op
284
- def diff(v)
285
- if @x.depend? v
286
- return @x.diff(v) / (CAS.pow(@x, CAS::Two) + CAS::One)
287
- else
288
- return CAS::Zero
289
- end
290
- end
291
-
292
- # Same as `CAS::Op`
293
- def call(f)
294
- CAS::Help.assert(f, Hash)
295
-
296
- Math::atan @x.call
297
- end
298
-
299
- # Same as `CAS::Op`
300
- def to_s
301
- "atan(#{@x})"
302
- end
303
-
304
- # Same as `CAS::Op`
305
- def simplify
306
- super
307
- if @x == CAS::Zero
308
- return CAS::Zero
309
- end
310
- if @x == CAS::One
311
- return CAS::Pi / 4
312
- end
313
- if @x == CAS::Infinity
314
- return CAS::Pi / 2
315
- end
316
- if @x.is_a? CAS::Tan
317
- return @x.x
318
- end
319
- return self
320
- end
321
-
322
- # Same as `CAS::Op`
323
- def to_code
324
- "Math::atan(#{@x.to_code})"
325
- end
326
-
327
- # Return latex representation of current Op
328
- def to_latex
329
- "\\arctan\\left( #{@x.to_latex} \\right)"
330
- end
331
- end
332
-
333
- def self.atan(x)
334
- CAS::Atan.new x
335
- end
336
- end