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-base.rb DELETED
@@ -1,560 +0,0 @@
1
- #!/usr/vin/env ruby
2
-
3
- module CAS
4
- # ```
5
- # ___
6
- # / __|_ _ _ __
7
- # \__ \ || | ' \
8
- # |___/\_,_|_|_|_|
9
- # ```
10
- class Sum < CAS::BinaryOp
11
- # Performs the sum between two `CAS::Op`
12
- #
13
- # ```
14
- # d
15
- # ---- (f(x) + g(x)) = f'(x) + g'(x)
16
- # dx
17
- # ```
18
- def diff(v)
19
- left, right = super v
20
-
21
- return left if right == CAS::Zero
22
- return right if left == CAS::Zero
23
- left + right
24
- end
25
-
26
- # Same as `CAS::Op`
27
- def call(f)
28
- CAS::Help.assert(f, Hash)
29
-
30
- return @x.call(f) + @y.call(f)
31
- end
32
-
33
- # Same as `CAS::Op`
34
- def to_s
35
- "(#{@x} + #{@y})"
36
- end
37
-
38
- # Same as `CAS::Op`
39
- def simplify
40
- super
41
- if @x == CAS::Zero
42
- return @y
43
- end
44
- if @y == CAS::Zero
45
- return @x
46
- end
47
- if @x == @y
48
- return @x * 2.0
49
- end
50
- if @x == -@y or -@x == @y
51
- return CAS::Zero
52
- end
53
- if @y.is_a? CAS::Invert
54
- return (@x - @y.x)
55
- end
56
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
57
- return CAS.const(self.call({}))
58
- end
59
- return self
60
- end
61
-
62
- # Same as `CAS::Op`
63
- def ==(op)
64
- CAS::Help.assert(op, CAS::Op)
65
-
66
- self.class == op.class and ((@x == op.x and @y == op.y) or (@y == op.x and @x == op.y))
67
- end
68
-
69
- # Same as `CAS::Op`
70
- def to_code
71
- "(#{@x.to_code} + #{@y.to_code})"
72
- end
73
-
74
- # Returns a latex represenntation of the current Op
75
- def to_latex
76
- "\\left(#{@x.to_latex} + #{@y.to_latex}\\right)"
77
- end
78
- end # Sum
79
-
80
- # ```
81
- # ___ _ __ __
82
- # | \(_)/ _|/ _|
83
- # | |) | | _| _/
84
- # |___/|_|_| |_|
85
- # ```
86
- class Diff < CAS::BinaryOp
87
- # Performs the difference between two `CAS::Op`s
88
- #
89
- # ```
90
- # d
91
- # ---- (f(x) - g(x)) = f'(x) - g'(x)
92
- # dx
93
- # ```
94
- def diff(v)
95
- left, right = super v
96
- return left if right == CAS::Zero
97
- return CAS::Invert.new(right) if left == CAS::Zero
98
- left - right
99
- end
100
-
101
- # Same as `CAS::Op`
102
- def call(f)
103
- CAS::Help.assert(f, Hash)
104
-
105
- return @x.call(f) - @y.call(f)
106
- end
107
-
108
- # Same as `CAS::Op`
109
- def to_s
110
- "(#{@x} - #{@y})"
111
- end
112
-
113
- # Same as `CAS::Op`
114
- def simplify
115
- super
116
- if @x == CAS::Zero
117
- return CAS.invert(@y)
118
- end
119
- if @y == CAS::Zero
120
- return @x
121
- end
122
- if @x == @y
123
- return CAS::Zero
124
- end
125
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
126
- return CAS.const(self.call({}))
127
- end
128
- if @y.is_a? CAS::Invert
129
- return @x + @y.x
130
- end
131
- if @x.is_a? CAS::Invert
132
- return -(@x.x + @y)
133
- end
134
- return self
135
- end
136
-
137
- # Same as `CAS::Op`
138
- def ==(op)
139
- CAS::Help.assert(op, CAS::Op)
140
- self.class == op.class and ((@x == op.x and @y == op.y) or (@y == op.x and @x == op.y))
141
- end
142
-
143
- # Same as `CAS::Op`
144
- def to_code
145
- "(#{@x.to_code} - #{@y.to_code})"
146
- end
147
-
148
- # Returns a latex representation of the current Op
149
- def to_latex
150
- "\\left(#{@x.to_latex} - #{@y.to_latex}\\right)"
151
- end
152
- end # Difference
153
-
154
- # ```
155
- # ___ _
156
- # | _ \_ _ ___ __| |
157
- # | _/ '_/ _ \/ _` |
158
- # |_| |_| \___/\__,_|
159
- # ```
160
- class Prod < CAS::BinaryOp
161
- # Performs the product between two `CAS::Op`
162
- #
163
- # ```
164
- # d
165
- # ---- (f(x) * g(x)) = f'(x) * g(x) + f(x) * g'(x)
166
- # dx
167
- # ```
168
- def diff(v)
169
- left, right = super v
170
- return left * @y if right == CAS::Zero
171
- return right * @x if left == CAS::Zero
172
- (left * @y) + (right * @x)
173
- end
174
-
175
- # Same as `CAS::Op`
176
- def call(f)
177
- CAS::Help.assert(f, Hash)
178
-
179
- return @x.call(f) * @y.call(f)
180
- end
181
-
182
- # Same as `CAS::Op`
183
- def to_s
184
- "(#{@x} * #{@y})"
185
- end
186
-
187
- # Same as `CAS::Op`
188
- def simplify
189
- super
190
- if @x == CAS::Zero or @y == CAS::Zero
191
- return CAS::Zero
192
- end
193
- if @x == CAS::One
194
- return @y
195
- end
196
- if @y == CAS::One
197
- return @x
198
- end
199
- if @x == @y
200
- return @x ** 2.0
201
- end
202
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
203
- return CAS.const(self.call({}))
204
- end
205
- return self
206
- end
207
-
208
- # Same as `CAS::Op`
209
- def ==(op)
210
- CAS::Help.assert(op, CAS::Op)
211
-
212
- self.class == op.class and ((@x == op.x and @y == op.y) or (@y == op.x and @x == op.y))
213
- end
214
-
215
- # Same as `CAS::Op`
216
- def to_code
217
- "(#{@x.to_code} * #{@y.to_code})"
218
- end
219
-
220
- # Returns a latex represstation of the Op
221
- def to_latex
222
- "#{@x.to_latex}\\,#{@y.to_latex}"
223
- end
224
- end # Prod
225
-
226
- # ```
227
- # ___
228
- # | _ \_____ __ __
229
- # | _/ _ \ V V /
230
- # |_| \___/\_/\_/
231
- # ```
232
- class Pow < CAS::BinaryOp
233
- # Performs the power between two `CAS::Op`
234
- #
235
- # ```
236
- # d
237
- # ---- (f(x)^a) = f(x)^(a - 1) * a * f'(x)
238
- # dx
239
- #
240
- # d
241
- # ---- (a^f(x)) = a^f(x) * f'(x) * ln a
242
- # dx
243
- #
244
- # d
245
- # ---- (f(x)^g(x)) = (f(x)^g(x)) * (g'(x) * ln f(x) + g(x) * f'(x) / f(x))
246
- # dx
247
- # ```
248
- def diff(v)
249
- diff_x, diff_y = super v
250
- if diff_y == CAS::Zero
251
- return ((@x ** (@y - 1.0)) * @y * diff_x)
252
- elsif diff_x == CAS::Zero
253
- return (@x ** @y) * diff_y * CAS.ln(@x)
254
- else
255
- return (@x ** @y) * ((diff_y * CAS.ln(@x)) + (@y * diff_x / @x))
256
- end
257
- end
258
-
259
- # Same as `CAS::Op`
260
- def call(f)
261
- CAS::Help.assert(f, Hash)
262
-
263
- @x.call(f) ** @y.call(f)
264
- end
265
-
266
- # Same as `CAS::Op`
267
- def to_s
268
- "#{@x}^#{@y}"
269
- end
270
-
271
- # Same as `CAS::Op`
272
- def simplify
273
- super
274
- if @x == CAS::Zero
275
- return CAS::Zero
276
- end
277
- if @x == CAS::One
278
- return CAS::One
279
- end
280
- if @y == CAS::One
281
- return @x
282
- end
283
- if @y == CAS::Zero
284
- return CAS::One
285
- end
286
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
287
- return CAS.const(self.call({}))
288
- end
289
- return self
290
- end
291
-
292
- # Same as `CAS::Op`
293
- def to_code
294
- "(#{@x.to_code} ** #{@y.to_code})"
295
- end
296
-
297
- # Returns the latex representation of the op
298
- def to_latex
299
- "{#{@x.to_latex}}^{#{@y.to_latex}}"
300
- end
301
- end
302
-
303
- def self.pow(x, y)
304
- CAS::Pow.new x, y
305
- end
306
-
307
- # ```
308
- # ___ _
309
- # | \(_)_ __
310
- # | |) | \ V /
311
- # |___/|_|\_/
312
- # ```
313
- class Div < CAS::BinaryOp
314
- # Performs the division between two `CAS::Op`
315
- #
316
- # ```
317
- # d
318
- # ---- (f(x) / g(x)) = (f'(x) * g(x) - f(x) * g'(x))/(g(x)^2)
319
- # dx
320
- # ```
321
- def diff(v)
322
- diff_x, diff_y = super v
323
- if diff_y == CAS::Zero
324
- return (diff_x/@y)
325
- elsif diff_x == CAS::Zero
326
- return CAS.invert(@x * diff_y / CAS.pow(@y, CAS.const(2.0)))
327
- else
328
- return ((diff_x * @y) - (diff_y * @x))/CAS.pow(@y, CAS.const(2.0))
329
- end
330
- end
331
-
332
- # Same as `CAS::Op`
333
- def call(f)
334
- CAS::Help.assert(f, Hash)
335
-
336
- @x.call(f)/@y.call(f)
337
- end
338
-
339
- # Same as `CAS::Op`
340
- def to_s
341
- "(#{@x}) / (#{@y})"
342
- end
343
-
344
- # Same as `CAS::Op`
345
- def simplify
346
- super
347
- if @x == CAS::Zero
348
- return CAS::Zero
349
- end
350
- if @y == CAS::Zero
351
- return CAS::Infinity
352
- end
353
- if @y == CAS::One
354
- return @x
355
- end
356
- if @y == CAS::Infinity
357
- return CAS::Zero
358
- end
359
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
360
- return CAS.const(self.call({}))
361
- end
362
- return self
363
- end
364
-
365
- # Same as `CAS::Op`
366
- def to_code
367
- "(#{@x.to_code} / #{@y.to_code})"
368
- end
369
-
370
- # Returns the latex reppresentation of the current Op
371
- def to_latex
372
- "\\dfrac{#{@x.to_latex}}{#{@y.to_latex}}"
373
- end
374
- end # Div
375
-
376
- # ___ _
377
- # / __| __ _ _ _| |_
378
- # \__ \/ _` | '_| _|
379
- # |___/\__, |_| \__|
380
- # |_|
381
- class Sqrt < CAS::Op
382
- # Performs the square root between two `CAS::Op`
383
- #
384
- # ```
385
- # d
386
- # ---- √f(x) = 1/2 * f'(x) * √f(x)
387
- # dx
388
- # ```
389
- def diff(v)
390
- if @x.depend? v
391
- return (@x.diff(v) / (CAS.const(2.0) * CAS.sqrt(@x)))
392
- else
393
- return CAS::Zero
394
- end
395
- end
396
-
397
- # Same as `CAS::Op`
398
- def call(f)
399
- CAS::Help.assert(f, Hash)
400
-
401
- Math::sqrt @x.call(f)
402
- end
403
-
404
- # Same as `CAS::Op`
405
- def to_s
406
- "√(#{@x})"
407
- end
408
-
409
- # Same as `CAS::Op`
410
- def simplify
411
- super
412
- if @x.is_a? CAS::Pow
413
- return CAS.pow(@x.x, @y - 0.5)
414
- end
415
- if @x == CAS::Zero
416
- return CAS::Zero
417
- end
418
- if @x == CAS::One
419
- return CAS::One
420
- end
421
- if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
422
- return CAS.const(self.call({}))
423
- end
424
- return self
425
- end
426
-
427
- # Same as `CAS::Op`
428
- def to_code
429
- "Math::sqrt(#{@x.to_code})"
430
- end
431
-
432
- # Returns the latex representation of the current Op
433
- def to_latex
434
- "\\sqrt{#{@x.to_latex}}"
435
- end
436
- end # Sqrt
437
-
438
- def self.sqrt(x)
439
- CAS::Sqrt.new x
440
- end
441
-
442
- # ___ _
443
- # |_ _|_ ___ _____ _ _| |_
444
- # | || ' \ V / -_) '_| _|
445
- # |___|_||_\_/\___|_| \__|
446
- class Invert < CAS::Op
447
- # Performs the inversion of a `CAS::Op`
448
- #
449
- # ```
450
- # d
451
- # ---- (-f(x)) = -f'(x)
452
- # dx
453
- # ```
454
- def diff(v)
455
- if @x.depend? v
456
- CAS::const(-1.0) * @x.diff(v)
457
- else
458
- CAS::Zero
459
- end
460
- end
461
-
462
- # Same as `CAS::Op`
463
- def call(f)
464
- CAS::Help.assert(f, Hash)
465
-
466
- -1.0 * @x.call(f)
467
- end
468
-
469
- # Same as `CAS::Op`
470
- def to_s
471
- "-#{@x}"
472
- end
473
-
474
- # Same as `CAS::Op`
475
- def simplify
476
- super
477
- if @x == CAS::Zero
478
- return CAS::Zero
479
- end
480
- if @x.is_a? CAS::Invert
481
- return @x.x
482
- end
483
- return self
484
- end
485
-
486
- # Same as `CAS::Op`
487
- def to_code
488
- "(-#{@x.to_code})"
489
- end
490
-
491
- # Returns the latex representation of the current op
492
- def to_latex
493
- "-{#{@x.to_latex}}"
494
- end
495
- end
496
-
497
- def self.invert(x)
498
- CAS::Invert.new x
499
- end
500
-
501
- # _ _
502
- # /_\ | |__ ___
503
- # / _ \| '_ (_-<
504
- # /_/ \_\_.__/__/
505
- class Abs < CAS::Op
506
- # Performs the absolute value of a `CAS::Op`
507
- #
508
- # ```
509
- # d
510
- # ---- |f(x)| = f'(x) * (f(x) / |f(x)|)
511
- # dx
512
- # ```
513
- def diff(v)
514
- if @x.depend? v
515
- return @x.diff(x) * (@x/CAS.abs(@x))
516
- else
517
- return CAS::Zero
518
- end
519
- end
520
-
521
- # Same as `CAS::Op`
522
- def call(f)
523
- CAS::Help.assert(f, Hash)
524
-
525
- s = (@x.call(f) >= 0 ? 1 : -1)
526
- return s * @x.call(f)
527
- end
528
-
529
- # Same as `CAS::Op`
530
- def to_s
531
- "|#{@x}|"
532
- end
533
-
534
- # Same as `CAS::Op`
535
- def simplify
536
- super
537
- if @x == CAS::Zero
538
- return CAS::Zero
539
- end
540
- if @x.is_a? CAS::Invert
541
- return CAS.abs(@x.x)
542
- end
543
- return self
544
- end
545
-
546
- # Same as `CAS::Op`
547
- def to_code
548
- "(#{@x.to_code}).abs"
549
- end
550
-
551
- # Returns the latex representation of the current Op
552
- def to_latex
553
- "\\left|#{@x.to_latex}\\right|"
554
- end
555
- end
556
-
557
- def self.abs(x)
558
- CAS::Abs.new x
559
- end
560
- end