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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b056fe6568af3a1aaeb4ae3442554aac4a971c33
4
- data.tar.gz: fa872c9f903c62a8627d49990c536df10b811af7
3
+ metadata.gz: 1f5aedceb3a3141a14a807fdbbac42e5bc66fd85
4
+ data.tar.gz: caa36f84a6e77cac0f1a6c5410c63cd2940297bd
5
5
  SHA512:
6
- metadata.gz: 64343ce07b37fd80d0415293c72137d837792f10a1afb41669c0a7987a28fa9c73e834c0aaf9319f27627a871f23166afd30d32787b77a62a93728f3c7a71594
7
- data.tar.gz: 189a27a57b2d6bd6808b8cec54ed5b1d06644f3a24a0b2070366163ab5d8718fb32036ddaa0067492b852d58dcea3ef96106ef4c963e82c99f6320a17e724267
6
+ metadata.gz: 9a56cda36bc0ac20cb444e1ad663b29c4ddeaac92e97239edfbc8631ef7ec054bc4d626919ed7efbf7200898f62bd7e731380f708bb0631345e60677eba684c2
7
+ data.tar.gz: 7c9ac6f8cb07d8a0a967b8afd655790a4d8d147fbcf4c2f9d939d763427e2e18405513c24b1bd0a4eb1bd72cee11d4c8ef710ed8c47e775afdda49ce3a12a606
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,660 @@
1
+ #!/usr/vin/env ruby
2
+
3
+ module CAS
4
+ # ___
5
+ # / __|_ _ _ __
6
+ # \__ \ || | ' \
7
+ # |___/\_,_|_|_|_|
8
+
9
+ ##
10
+ # **Sum basic operation**. As for now it is implemented as a simple
11
+ # binary operation. It will be implemented as n-ary op.
12
+ class Sum < CAS::BinaryOp
13
+ # Performs the sum between two `CAS::Op`
14
+ #
15
+ # ```
16
+ # d
17
+ # ---- (f(x) + g(x)) = f'(x) + g'(x)
18
+ # dx
19
+ # ```
20
+ #
21
+ # * **argument**: `CAS::Op` argument of derivative
22
+ # * **returns**: `CAS::Op` derivative
23
+ def diff(v)
24
+ left, right = super v
25
+
26
+ return left if right == CAS::Zero
27
+ return right if left == CAS::Zero
28
+ left + right
29
+ end
30
+
31
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
32
+ # or `Float` (depends upon promotions).
33
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
34
+ # as keys, and a `Numeric` as a value. In this case it will call
35
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
36
+ #
37
+ # * **argument**: `Hash` with feed dictionary
38
+ # * **returns**: `Numeric`
39
+ def call(f)
40
+ CAS::Help.assert(f, Hash)
41
+ return @x.call(f).overloaded_plus(@y.call(f))
42
+ end
43
+
44
+ # Convert expression to string
45
+ #
46
+ # * **returns**: `String` to print on screen
47
+ def to_s
48
+ "(#{@x} + #{@y})"
49
+ end
50
+
51
+ # Same as `CAS::Op`
52
+ #
53
+ # Simplifcation engine supports:
54
+ #
55
+ # * x + 0 = x
56
+ # * 0 + y = y
57
+ # * x + x = 2 x
58
+ # * x + (-x) = 0
59
+ # * x + (-y) = x - y
60
+ # * 1 + 2 = 3 (constants reduction)
61
+ #
62
+ # * **returns**: `CAS::Op` simplified version
63
+ def simplify
64
+ super
65
+ return @y if @x == CAS::Zero
66
+ return @x if @y == CAS::Zero
67
+ return @x * 2.0 if @x == @y
68
+ return CAS::Zero if @x == -@y or -@x == @y
69
+ return (@x - @y.x) if @y.is_a? CAS::Invert
70
+ return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
71
+ return self
72
+ end
73
+
74
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
75
+ #
76
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
77
+ def to_code
78
+ "(#{@x.to_code} + #{@y.to_code})"
79
+ end
80
+ end # Sum
81
+ CAS::Sum.init_simplify_dict
82
+
83
+ # ___ _ __ __
84
+ # | \(_)/ _|/ _|
85
+ # | |) | | _| _/
86
+ # |___/|_|_| |_|
87
+
88
+ ##
89
+ # **Difference basic operation**. It's a binary operation. This cannot
90
+ # be implemented as a n-ary op, thus will not be changed
91
+ class Diff < CAS::BinaryOp
92
+ # Performs the difference between two `CAS::Op`s
93
+ #
94
+ # ```
95
+ # d
96
+ # ---- (f(x) - g(x)) = f'(x) - g'(x)
97
+ # dx
98
+ # ```
99
+ #
100
+ # * **argument**: `CAS::Op` argument of derivative
101
+ # * **returns**: `CAS::Op` derivative
102
+ def diff(v)
103
+ left, right = super v
104
+ return left if right == CAS::Zero
105
+ return CAS::Invert.new(right) if left == CAS::Zero
106
+ left - right
107
+ end
108
+
109
+ # Same as `CAS::Op`
110
+ def call(f)
111
+ CAS::Help.assert(f, Hash)
112
+
113
+ return @x.call(f).overloaded_minus(@y.call(f))
114
+ end
115
+
116
+ # Same as `CAS::Op`
117
+ def to_s
118
+ "(#{@x} - #{@y})"
119
+ end
120
+
121
+ # Same as `CAS::Op`
122
+ #
123
+ # Simplifcation engine supports:
124
+ #
125
+ # * 0 - y = -y
126
+ # * x - 0 = x
127
+ # * a - b = c (constants reduction)
128
+ # * x - x = 0
129
+ # * x - (-y) = x + y
130
+ #
131
+ # * **returns**: `CAS::Op` simplified version
132
+ def simplify
133
+ super
134
+ return CAS.invert(@y) if @x == CAS::Zero
135
+ return @x if @y == CAS::Zero
136
+ return CAS::Zero if @x == @y
137
+ return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
138
+ return @x + @y.x if @y.is_a? CAS::Invert
139
+ return -(@x.x + @y) if @x.is_a? CAS::Invert
140
+ return self
141
+ end
142
+
143
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
144
+ #
145
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
146
+ def to_code
147
+ "(#{@x.to_code} - #{@y.to_code})"
148
+ end
149
+ end # Difference
150
+ CAS::Diff.init_simplify_dict
151
+
152
+ # ___ _
153
+ # | _ \_ _ ___ __| |
154
+ # | _/ '_/ _ \/ _` |
155
+ # |_| |_| \___/\__,_|
156
+
157
+ ##
158
+ # Product class. Performs the product between two elements.
159
+ # This class will be soon modified as an n-ary operator.
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
+ #
169
+ # * **argument**: `CAS::Op` argument of derivative
170
+ # * **returns**: `CAS::Op` derivative
171
+ def diff(v)
172
+ left, right = super v
173
+ return left * @y if right == CAS::Zero
174
+ return right * @x if left == CAS::Zero
175
+ (left * @y) + (right * @x)
176
+ end
177
+
178
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
179
+ # or `Float` (depends upon promotions).
180
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
181
+ # as keys, and a `Numeric` as a value. In this case it will call
182
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
183
+ #
184
+ # * **argument**: `Hash` with feed dictionary
185
+ # * **returns**: `Numeric`
186
+ def call(f)
187
+ CAS::Help.assert(f, Hash)
188
+
189
+ return @x.call(f).overloaded_mul(@y.call(f))
190
+ end
191
+
192
+ # Convert expression to string
193
+ #
194
+ # * **returns**: `String` to print on screen
195
+ def to_s
196
+ "(#{@x} * #{@y})"
197
+ end
198
+
199
+ # Same as `CAS::Op`
200
+ #
201
+ # Simplifcation engine supports:
202
+ #
203
+ # * x * 0 = x * y = 0
204
+ # * 1 * y = y
205
+ # * x * 1 = x
206
+ # * x * x = x²
207
+ # * a * b = c (constants reduction)
208
+ #
209
+ # * **returns**: `CAS::Op` simplified version
210
+ def simplify
211
+ super
212
+ return CAS::Zero if (@x == CAS::Zero or @y == CAS::Zero)
213
+ return @y if @x == CAS::One
214
+ return @x if @y == CAS::One
215
+ return @x ** 2.0 if @x == @y
216
+ return CAS.const(self.call({})) if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
217
+ return self
218
+ end
219
+
220
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
221
+ #
222
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
223
+ def to_code
224
+ "(#{@x.to_code} * #{@y.to_code})"
225
+ end
226
+ end # Prod
227
+ CAS::Prod.init_simplify_dict
228
+
229
+ # ___
230
+ # | _ \_____ __ __
231
+ # | _/ _ \ V V /
232
+ # |_| \___/\_/\_/
233
+
234
+ ##
235
+ # Power function.
236
+ class Pow < CAS::BinaryOp
237
+ # Performs the power between two `CAS::Op`
238
+ #
239
+ # ```
240
+ # d
241
+ # ---- (f(x)^a) = f(x)^(a - 1) * a * f'(x)
242
+ # dx
243
+ #
244
+ # d
245
+ # ---- (a^f(x)) = a^f(x) * f'(x) * ln a
246
+ # dx
247
+ #
248
+ # d
249
+ # ---- (f(x)^g(x)) = (f(x)^g(x)) * (g'(x) * ln f(x) + g(x) * f'(x) / f(x))
250
+ # dx
251
+ # ```
252
+ #
253
+ # * **argument**: `CAS::Op` argument of derivative
254
+ # * **returns**: `CAS::Op` derivative
255
+ def diff(v)
256
+ diff_x, diff_y = super v
257
+ if diff_y == CAS::Zero
258
+ return ((@x ** (@y - 1.0)) * @y * diff_x)
259
+ elsif diff_x == CAS::Zero
260
+ return (@x ** @y) * diff_y * CAS.ln(@x)
261
+ else
262
+ return (@x ** @y) * ((diff_y * CAS.ln(@x)) + (@y * diff_x / @x))
263
+ end
264
+ end
265
+
266
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
267
+ # or `Float` (depends upon promotions).
268
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
269
+ # as keys, and a `Numeric` as a value. In this case it will call
270
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
271
+ #
272
+ # * **argument**: `Hash` with feed dictionary
273
+ # * **returns**: `Numeric`
274
+ def call(f)
275
+ CAS::Help.assert(f, Hash)
276
+ @x.call(f).overloaded_pow(@y.call(f))
277
+ end
278
+
279
+ # Convert expression to string
280
+ #
281
+ # * **returns**: `String` to print on screen
282
+ def to_s
283
+ "(#{@x})^(#{@y})"
284
+ end
285
+
286
+ # Same as `CAS::Op`
287
+ #
288
+ # Simplifcation engine supports:
289
+ #
290
+ # * 0 ^ y = 0
291
+ # * x ^ 0 = 1
292
+ # * a ^ b = c (constants reduction)
293
+ # * x ^ 1 = x
294
+ # * 1 ^ y = 1
295
+ #
296
+ # * **returns**: `CAS::Op` simplified version
297
+ def simplify
298
+ super
299
+ return CAS::Zero if @x == CAS::Zero
300
+ return CAS::One if @x == CAS::One
301
+ return @x if @y == CAS::One
302
+ return CAS::One if @y == CAS::Zero
303
+ return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
304
+ return self
305
+ end
306
+
307
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
308
+ #
309
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
310
+ def to_code
311
+ "(#{@x.to_code} ** #{@y.to_code})"
312
+ end
313
+ end # Pow
314
+ CAS::Pow.init_simplify_dict
315
+
316
+ # Shortcut for `CAS::Pow` initializer
317
+ #
318
+ # * **argument**: `CAS::Op` base
319
+ # * **argument**: `CAS::Op` exponent
320
+ # * **returns**: `CAS::Pow` new instance
321
+ def self.pow(x, y)
322
+ CAS::Pow.new x, y
323
+ end
324
+
325
+ # ___ _
326
+ # | \(_)_ __
327
+ # | |) | \ V /
328
+ # |___/|_|\_/
329
+
330
+ ##
331
+ # Division between two functions. A function divided by zero it is considered
332
+ # as an Infinity.
333
+ class Div < CAS::BinaryOp
334
+ # Performs the division between two `CAS::Op`
335
+ #
336
+ # ```
337
+ # d
338
+ # ---- (f(x) / g(x)) = (f'(x) * g(x) - f(x) * g'(x))/(g(x)^2)
339
+ # dx
340
+ # ```
341
+ #
342
+ # * **argument**: `CAS::Op` argument of derivative
343
+ # * **returns**: `CAS::Op` derivative
344
+ def diff(v)
345
+ diff_x, diff_y = super v
346
+ if diff_y == CAS::Zero
347
+ return (diff_x/@y)
348
+ elsif diff_x == CAS::Zero
349
+ return CAS.invert(@x * diff_y / CAS.pow(@y, CAS.const(2.0)))
350
+ else
351
+ return ((diff_x * @y) - (diff_y * @x))/CAS.pow(@y, CAS.const(2.0))
352
+ end
353
+ end
354
+
355
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
356
+ # or `Float` (depends upon promotions).
357
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
358
+ # as keys, and a `Numeric` as a value. In this case it will call
359
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
360
+ #
361
+ # * **argument**: `Hash` with feed dictionary
362
+ # * **returns**: `Numeric`
363
+ def call(f)
364
+ CAS::Help.assert(f, Hash)
365
+
366
+ @x.call(f).overloaded_div(@y.call(f))
367
+ end
368
+
369
+ # Convert expression to string
370
+ #
371
+ # * **returns**: `String` to print on screen
372
+ def to_s
373
+ "(#{@x}) / (#{@y})"
374
+ end
375
+
376
+ # Same as `CAS::Op`
377
+ #
378
+ # Simplifcation engine supports:
379
+ #
380
+ # * 0 / y = 0
381
+ # * x / 0 = Inf
382
+ # * x / 1 = x
383
+ # * x / Inf = 0
384
+ # * a / b = c (constants reduction)
385
+ #
386
+ # * **returns**: `CAS::Op` simplified version
387
+ def simplify
388
+ super
389
+ return CAS::Zero if @x == CAS::Zero
390
+ return CAS::Infinity if @y == CAS::Zero
391
+ return @x if @y == CAS::One
392
+ return CAS::Zero if @y == CAS::Infinity
393
+ return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
394
+ return self
395
+ end
396
+
397
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
398
+ #
399
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
400
+ def to_code
401
+ "(#{@x.to_code} / #{@y.to_code})"
402
+ end
403
+ end # Div
404
+ CAS::Div.init_simplify_dict
405
+
406
+ # ___ _
407
+ # / __| __ _ _ _| |_
408
+ # \__ \/ _` | '_| _|
409
+ # |___/\__, |_| \__|
410
+ # |_|
411
+
412
+ ##
413
+ # Square Root of a function. Even if it can be implemented as a power function,
414
+ # it is a separated class.
415
+ class Sqrt < CAS::Op
416
+ # Performs the square root between two `CAS::Op`
417
+ #
418
+ # ```
419
+ # d
420
+ # ---- √f(x) = 1/2 * f'(x) * √f(x)
421
+ # dx
422
+ # ```
423
+ #
424
+ # * **argument**: `CAS::Op` argument of derivative
425
+ # * **returns**: `CAS::Op` derivative
426
+ def diff(v)
427
+ if @x.depend? v
428
+ return (@x.diff(v) / (CAS.const(2.0) * CAS.sqrt(@x)))
429
+ else
430
+ return CAS::Zero
431
+ end
432
+ end
433
+
434
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
435
+ # or `Float` (depends upon promotions).
436
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
437
+ # as keys, and a `Numeric` as a value. In this case it will call
438
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
439
+ #
440
+ # * **argument**: `Hash` with feed dictionary
441
+ # * **returns**: `Numeric`
442
+ def call(f)
443
+ CAS::Help.assert(f, Hash)
444
+
445
+ Math::sqrt @x.call(f)
446
+ end
447
+
448
+ # Convert expression to string
449
+ #
450
+ # * **returns**: `String` to print on screen
451
+ def to_s
452
+ "√(#{@x})"
453
+ end
454
+
455
+ # Same as `CAS::Op`
456
+ #
457
+ # Simplifcation engine supports:
458
+ #
459
+ # * √(x^z) = x^(z - 1/2)
460
+ # * √x = 0
461
+ # * √x = 1
462
+ # * √a = b (constants reduction)
463
+ #
464
+ # * **returns**: `CAS::Op` simplified version
465
+ def simplify
466
+ super
467
+ return CAS.pow(@x.x, @y - 0.5) if @x.is_a? CAS::Pow
468
+ return CAS::Zero if @x == CAS::Zero
469
+ return CAS::One if @x == CAS::One
470
+ return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
471
+ return self
472
+ end
473
+
474
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
475
+ #
476
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
477
+ def to_code
478
+ "Math::sqrt(#{@x.to_code})"
479
+ end
480
+ end # Sqrt
481
+ CAS::Sqrt.init_simplify_dict
482
+
483
+ # Shortcut for `CAS::Sqrt` initializer
484
+ #
485
+ # * **argument**: `CAS::Op` argument of square root
486
+ # * **returns**: `CAS::Sqrt` new instance
487
+ def self.sqrt(x)
488
+ CAS::Sqrt.new x
489
+ end
490
+
491
+ # ___ _
492
+ # |_ _|_ ___ _____ _ _| |_
493
+ # | || ' \ V / -_) '_| _|
494
+ # |___|_||_\_/\___|_| \__|
495
+
496
+ ##
497
+ # Invert is the same as multiply by `-1` a function.
498
+ # `Invert(x)` is equal to `-x`
499
+ class Invert < CAS::Op
500
+ # Performs the inversion of a `CAS::Op`
501
+ #
502
+ # ```
503
+ # d
504
+ # ---- (-f(x)) = -f'(x)
505
+ # dx
506
+ # ```
507
+ #
508
+ # * **argument**: `CAS::Op` argument of derivative
509
+ # * **returns**: `CAS::Op` derivative
510
+ def diff(v)
511
+ if @x.depend? v
512
+ CAS::const(-1.0) * @x.diff(v)
513
+ else
514
+ CAS::Zero
515
+ end
516
+ end
517
+
518
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
519
+ # or `Float` (depends upon promotions).
520
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
521
+ # as keys, and a `Numeric` as a value. In this case it will call
522
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
523
+ #
524
+ # * **argument**: `Hash` with feed dictionary
525
+ # * **returns**: `Numeric`
526
+ def call(f)
527
+ CAS::Help.assert(f, Hash)
528
+
529
+ -1.0 * @x.call(f)
530
+ end
531
+
532
+ # Convert expression to string
533
+ #
534
+ # * **returns**: `String` to print on screen
535
+ def to_s
536
+ "-#{@x}"
537
+ end
538
+
539
+ # Same as `CAS::Op`
540
+ #
541
+ # Simplifcation engine supports:
542
+ #
543
+ # * -(-x) = x
544
+ # * -0 = 0
545
+ #
546
+ # * **returns**: `CAS::Op` simplified version
547
+ def simplify
548
+ super
549
+ return @x.x if @x.is_a? CAS::Invert
550
+ return self.simplify_dictionary
551
+ end
552
+
553
+ def self.init_simplify_dict
554
+ @simplify_dict = {
555
+ CAS::Zero => CAS::Zero
556
+ }
557
+ end
558
+
559
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
560
+ #
561
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
562
+ def to_code
563
+ "(-#{@x.to_code})"
564
+ end
565
+ end # Invert
566
+ CAS::Invert.init_simplify_dict
567
+
568
+ # Shortcut for `CAs::Invert` initializer
569
+ #
570
+ # * **argument**: `CAs::Op` argument of the inversion
571
+ # * **returns**: `CAS::Invert` new instance
572
+ def self.invert(x)
573
+ CAS::Invert.new x
574
+ end
575
+
576
+ # _ _
577
+ # /_\ | |__ ___
578
+ # / _ \| '_ (_-<
579
+ # /_/ \_\_.__/__/
580
+
581
+ ##
582
+ # Absolute value of a function. It can be also implemented as a Piecewise function.
583
+ class Abs < CAS::Op
584
+ # Performs the absolute value of a `CAS::Op`
585
+ #
586
+ # ```
587
+ # d
588
+ # ---- |f(x)| = f'(x) * (f(x) / |f(x)|)
589
+ # dx
590
+ # ```
591
+ #
592
+ # * **argument**: `CAS::Op` argument of derivative
593
+ # * **returns**: `CAS::Op` derivative
594
+ def diff(v)
595
+ if @x.depend? v
596
+ return @x.diff(x) * (@x/CAS.abs(@x))
597
+ else
598
+ return CAS::Zero
599
+ end
600
+ end
601
+
602
+ # Call resolves the operation tree in a `Numeric` (if `Fixnum`)
603
+ # or `Float` (depends upon promotions).
604
+ # As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name`
605
+ # as keys, and a `Numeric` as a value. In this case it will call
606
+ # the `Fixnum#overloaded_plus`, that is the old plus function.
607
+ #
608
+ # * **argument**: `Hash` with feed dictionary
609
+ # * **returns**: `Numeric`
610
+ def call(f)
611
+ CAS::Help.assert(f, Hash)
612
+
613
+ s = (@x.call(f) >= 0 ? 1 : -1)
614
+ return s * @x.call(f)
615
+ end
616
+
617
+ # Convert expression to string
618
+ #
619
+ # * **returns**: `String` to print on screen
620
+ def to_s
621
+ "|#{@x}|"
622
+ end
623
+
624
+ # Same as `CAS::Op`
625
+ #
626
+ # Simplifcation engine supports:
627
+ #
628
+ # * |-x| = x
629
+ # * |0| = 0
630
+ #
631
+ # * **returns**: `CAS::Op` simplified version
632
+ def simplify
633
+ super
634
+ return CAS.abs(@x.x) if @x.is_a? CAS::Invert
635
+ return self.simplify_dictionary
636
+ end
637
+
638
+ def self.init_simplify_dict
639
+ @simplify_dict = {
640
+ CAS::Zero => CAS::Zero
641
+ }
642
+ end
643
+
644
+ # Convert expression to code (internal, for `CAS::Op#to_proc` method)
645
+ #
646
+ # * **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`
647
+ def to_code
648
+ "(#{@x.to_code}).abs"
649
+ end
650
+ end # Abs
651
+ CAS::Abs.init_simplify_dict
652
+
653
+ # Shortcut for `CAs::Abs` initializer
654
+ #
655
+ # * **argument**: `CAs::Op` argument of absolute value
656
+ # * **returns**: `CAS::Abs` new instance
657
+ def self.abs(x)
658
+ CAS::Abs.new x
659
+ end
660
+ end