ragni-cas 0.1.0
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/lib/fnc-base.rb +333 -0
- data/lib/fnc-trig.rb +246 -0
- data/lib/fnc-trsc.rb +96 -0
- data/lib/numbers.rb +177 -0
- data/lib/op.rb +143 -0
- data/lib/ragni-cas.rb +7 -0
- data.tar.gz.sig +2 -0
- metadata +70 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 865e68bc49826e2cf3c598fcb830c38929cb226d
|
4
|
+
data.tar.gz: e2685fded45fa443f467f3a40033c25595a006d7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c1084b05b544cf06f8ff9248cd74a3a9774054ff3b96901370bfbf3336763eabf218c0346b539acd1128d7aabf56de9f8355743e4aa4c8263f381903d46b207
|
7
|
+
data.tar.gz: 97b1c18b185911086f604db022e5f2943a75e667f9a3320463bd747b6ffeaa71afa63b8b9da622e04e609448b3409f58aedf369a15c4bcb1d03b20a5053cc1b0
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/lib/fnc-base.rb
ADDED
@@ -0,0 +1,333 @@
|
|
1
|
+
#!/usr/vin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
# ___
|
5
|
+
# / __|_ _ _ __
|
6
|
+
# \__ \ || | ' \
|
7
|
+
# |___/\_,_|_|_|_|
|
8
|
+
class Sum < CAS::BinaryOp
|
9
|
+
def diff(v)
|
10
|
+
left, right = super v
|
11
|
+
return left if (right == nil or right == CAS::Zero)
|
12
|
+
return right if (left == nil or left == CAS::Zero)
|
13
|
+
left + right
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(f)
|
17
|
+
return @x.call(f) + @y.call(f)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"(#{@x} + #{@y})"
|
22
|
+
end
|
23
|
+
|
24
|
+
def simplify
|
25
|
+
super
|
26
|
+
if @x == CAS::Zero
|
27
|
+
return @y
|
28
|
+
end
|
29
|
+
if @y == CAS::Zero
|
30
|
+
return @x
|
31
|
+
end
|
32
|
+
if @x == @y
|
33
|
+
return @x * 2.0
|
34
|
+
end
|
35
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
36
|
+
return CAS.const(self.call({}))
|
37
|
+
end
|
38
|
+
return self
|
39
|
+
end
|
40
|
+
end # Sum
|
41
|
+
|
42
|
+
# ___ _ __ __
|
43
|
+
# | \(_)/ _|/ _|
|
44
|
+
# | |) | | _| _/
|
45
|
+
# |___/|_|_| |_|
|
46
|
+
class Diff < CAS::BinaryOp
|
47
|
+
def diff(v)
|
48
|
+
left, right = super v
|
49
|
+
return left if (right == nil or right == CAS::Zero)
|
50
|
+
return CAS::Invert.new(right) if (left == nil or left == CAS::Zero)
|
51
|
+
left - right
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(f)
|
55
|
+
return @x.call(f) - @y.call(f)
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"(#{@x} - #{@y})"
|
60
|
+
end
|
61
|
+
|
62
|
+
def simplify
|
63
|
+
super
|
64
|
+
if @x == CAS::Zero
|
65
|
+
return CAS.invert(@y)
|
66
|
+
end
|
67
|
+
if @y == CAS::Zero
|
68
|
+
return @x
|
69
|
+
end
|
70
|
+
if @x == @y
|
71
|
+
return CAS::Zero
|
72
|
+
end
|
73
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
74
|
+
return CAS.const(self.call({}))
|
75
|
+
end
|
76
|
+
return self
|
77
|
+
end
|
78
|
+
end # Difference
|
79
|
+
|
80
|
+
# ___ _
|
81
|
+
# | _ \_ _ ___ __| |
|
82
|
+
# | _/ '_/ _ \/ _` |
|
83
|
+
# |_| |_| \___/\__,_|
|
84
|
+
class Prod < CAS::BinaryOp
|
85
|
+
def diff(v)
|
86
|
+
left, right = super v
|
87
|
+
return left * @y if (right == nil or right == CAS::Zero)
|
88
|
+
return right * @x if (left == nil or left == CAS::Zero)
|
89
|
+
(left * @y) + (right * @x)
|
90
|
+
end
|
91
|
+
|
92
|
+
def call(f)
|
93
|
+
return @x.call(f) * @y.call(f)
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_s
|
97
|
+
"(#{@x} * #{@y})"
|
98
|
+
end
|
99
|
+
|
100
|
+
def simplify
|
101
|
+
super
|
102
|
+
if @x == CAS::Zero or @y == CAS::Zero
|
103
|
+
return CAS::Zero
|
104
|
+
end
|
105
|
+
if @x == CAS::One
|
106
|
+
return @y
|
107
|
+
end
|
108
|
+
if @y == CAS::One
|
109
|
+
return @x
|
110
|
+
end
|
111
|
+
if @x == @y
|
112
|
+
return @x ** 2.0
|
113
|
+
end
|
114
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
115
|
+
return CAS.const(self.call({}))
|
116
|
+
end
|
117
|
+
return self
|
118
|
+
end
|
119
|
+
end # Prod
|
120
|
+
|
121
|
+
# ___
|
122
|
+
# | _ \_____ __ __
|
123
|
+
# | _/ _ \ V V /
|
124
|
+
# |_| \___/\_/\_/
|
125
|
+
class Pow < CAS::BinaryOp
|
126
|
+
def diff(v)
|
127
|
+
diff_x, diff_y = super v
|
128
|
+
if diff_y == nil or diff_y == CAS::Zero
|
129
|
+
return ((@x ** (@y - 1.0)) * @y * diff_x)
|
130
|
+
elsif diff_x == nil or diff_x == CAS::Zero
|
131
|
+
return (@x ** @y) * diff_y * CAS.ln(@x)
|
132
|
+
else
|
133
|
+
return (@x ** @y) * ((diff_y * CAS.ln(@x)) + (@y * diff_x / @x))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def call(f)
|
138
|
+
@x.call(f) ** @y.call(f)
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_s
|
142
|
+
"#{@x}^#{@y}"
|
143
|
+
end
|
144
|
+
|
145
|
+
def simplify
|
146
|
+
super
|
147
|
+
if @x == CAS::Zero
|
148
|
+
return CAS::Zero
|
149
|
+
end
|
150
|
+
if @x == CAS::One
|
151
|
+
return CAS::One
|
152
|
+
end
|
153
|
+
if @y == CAS::One
|
154
|
+
return @x
|
155
|
+
end
|
156
|
+
if @y == CAS::Zero
|
157
|
+
return CAS::One
|
158
|
+
end
|
159
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
160
|
+
return CAS.const(self.call({}))
|
161
|
+
end
|
162
|
+
return self
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.pow(x, y)
|
167
|
+
CAS::Pow.new x, y
|
168
|
+
end
|
169
|
+
|
170
|
+
# ___ _
|
171
|
+
# | \(_)_ __
|
172
|
+
# | |) | \ V /
|
173
|
+
# |___/|_|\_/
|
174
|
+
class Div < CAS::BinaryOp
|
175
|
+
def diff(v)
|
176
|
+
diff_x, diff_y = super v
|
177
|
+
if diff_y == nil or diff_y == CAS::Zero
|
178
|
+
return (diff_x/@y)
|
179
|
+
elsif diff_x == nil or diff_x == CAS::Zero
|
180
|
+
return CAS.invert(@x * diff_y / CAS.pow(@y, CAS.const(2.0)))
|
181
|
+
else
|
182
|
+
return ((diff_x * @y) - (diff_y * @x))/CAS.pow(@y, CAS.const(2.0))
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def call(f)
|
187
|
+
@x.call(f)/@y.call(f)
|
188
|
+
end
|
189
|
+
|
190
|
+
def to_s
|
191
|
+
"(#{@x}) / (#{@y})"
|
192
|
+
end
|
193
|
+
|
194
|
+
def simplify
|
195
|
+
super
|
196
|
+
if @x == CAS::Zero
|
197
|
+
return CAS::Zero
|
198
|
+
end
|
199
|
+
if @y == CAS::Zero
|
200
|
+
return CAS::Infinity
|
201
|
+
end
|
202
|
+
if @y == CAS::One
|
203
|
+
return @x
|
204
|
+
end
|
205
|
+
if @y == CAS::Infinity
|
206
|
+
return CAS::Zero
|
207
|
+
end
|
208
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
209
|
+
return CAS.const(self.call({}))
|
210
|
+
end
|
211
|
+
return self
|
212
|
+
end
|
213
|
+
end # Div
|
214
|
+
|
215
|
+
# ___ _
|
216
|
+
# / __| __ _ _ _| |_
|
217
|
+
# \__ \/ _` | '_| _|
|
218
|
+
# |___/\__, |_| \__|
|
219
|
+
# |_|
|
220
|
+
class Sqrt < CAS::Op
|
221
|
+
def diff(v)
|
222
|
+
if @x.depend? v
|
223
|
+
return (@x.diff(v) / (CAS.const(2.0) * CAS.sqrt(@x)))
|
224
|
+
else
|
225
|
+
return CAS::Zero
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def call(f)
|
230
|
+
Math::sqrt @x.call(f)
|
231
|
+
end
|
232
|
+
|
233
|
+
def to_s
|
234
|
+
"√(#{@x})"
|
235
|
+
end
|
236
|
+
|
237
|
+
def simplify
|
238
|
+
super
|
239
|
+
if @x.is_a? CAS::Pow
|
240
|
+
return CAS.pow(@x.x, @y - 0.5)
|
241
|
+
end
|
242
|
+
if @x == CAS::Zero
|
243
|
+
return CAS::Zero
|
244
|
+
end
|
245
|
+
if @x == CAS::One
|
246
|
+
return CAS::One
|
247
|
+
end
|
248
|
+
if @x.is_a? CAS::Constant and @y.is_a? CAS::Constant
|
249
|
+
return CAS.const(self.call({}))
|
250
|
+
end
|
251
|
+
return self
|
252
|
+
end
|
253
|
+
end # Sqrt
|
254
|
+
|
255
|
+
def self.sqrt(x)
|
256
|
+
CAS::Sqrt.new x
|
257
|
+
end
|
258
|
+
|
259
|
+
# ___ _
|
260
|
+
# |_ _|_ ___ _____ _ _| |_
|
261
|
+
# | || ' \ V / -_) '_| _|
|
262
|
+
# |___|_||_\_/\___|_| \__|
|
263
|
+
class Invert < CAS::Op
|
264
|
+
def diff(v)
|
265
|
+
if @x.depend? v
|
266
|
+
CAS::const(-1.0) * @x.diff
|
267
|
+
else
|
268
|
+
CAS::Zero
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def call(f)
|
273
|
+
-1.0 * @x.call(f)
|
274
|
+
end
|
275
|
+
|
276
|
+
def to_s
|
277
|
+
"-#{@x}"
|
278
|
+
end
|
279
|
+
|
280
|
+
def simplify
|
281
|
+
super
|
282
|
+
if @x == CAS::Zero
|
283
|
+
return CAS::Zero
|
284
|
+
end
|
285
|
+
if @x.is_a? CAS::Invert
|
286
|
+
return @x.x
|
287
|
+
end
|
288
|
+
return self
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def self.invert(x)
|
293
|
+
CAS::Invert.new x
|
294
|
+
end
|
295
|
+
|
296
|
+
# _ _
|
297
|
+
# /_\ | |__ ___
|
298
|
+
# / _ \| '_ (_-<
|
299
|
+
# /_/ \_\_.__/__/
|
300
|
+
class Abs < CAS::Op
|
301
|
+
def diff(v)
|
302
|
+
if @x.depend? v
|
303
|
+
return @x.diff * (@x/CAS.abs(@x))
|
304
|
+
else
|
305
|
+
return CAS::Zero
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def call(f)
|
310
|
+
s = (@x.call(f) >= 0 ? 1 : -1)
|
311
|
+
return s * @x.call(f)
|
312
|
+
end
|
313
|
+
|
314
|
+
def to_s
|
315
|
+
"|#{@x}|"
|
316
|
+
end
|
317
|
+
|
318
|
+
def simplify
|
319
|
+
super
|
320
|
+
if @x == CAS::Zero
|
321
|
+
return CAS::Zero
|
322
|
+
end
|
323
|
+
if @x.is_a? CAS::Invert
|
324
|
+
return CAS.abs(@x.x)
|
325
|
+
end
|
326
|
+
return self
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.abs(x)
|
331
|
+
CAS::Abs.new x
|
332
|
+
end
|
333
|
+
end
|
data/lib/fnc-trig.rb
ADDED
@@ -0,0 +1,246 @@
|
|
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
|
+
def call(f)
|
18
|
+
Math::sin @x.call(f)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"sin(#{@x})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def simplify
|
26
|
+
super
|
27
|
+
if @x == CAS::Zero
|
28
|
+
return CAS::Zero
|
29
|
+
end
|
30
|
+
if @x == CAS::Pi
|
31
|
+
return CAS::Zero
|
32
|
+
end
|
33
|
+
if @x.is_a? CAS::Asin
|
34
|
+
return @x.x
|
35
|
+
end
|
36
|
+
return self
|
37
|
+
end
|
38
|
+
end # Sin
|
39
|
+
|
40
|
+
def self.sin(x)
|
41
|
+
CAS::Sin.new x
|
42
|
+
end
|
43
|
+
|
44
|
+
# _ _
|
45
|
+
# /_\ __(_)_ _
|
46
|
+
# / _ \ (_-< | ' \
|
47
|
+
# /_/ \_\/__/_|_||_|
|
48
|
+
class Asin < CAS::Op
|
49
|
+
def diff(v)
|
50
|
+
if @x.depend? v
|
51
|
+
return @x.diff(v) / CAS.sqrt(CAS::One - CAS.pow(@x, CAS::Two))
|
52
|
+
else
|
53
|
+
return CAS::Zero
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def call(f)
|
58
|
+
Math::acos @x.call(f)
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
"asin(#{@x})"
|
63
|
+
end
|
64
|
+
|
65
|
+
def simplify
|
66
|
+
super
|
67
|
+
if @x == CAS::Zero
|
68
|
+
return CAS::Zero
|
69
|
+
end
|
70
|
+
if @x == CAS::One
|
71
|
+
return CAS::Pi / 2
|
72
|
+
end
|
73
|
+
if @x.is_a? CAS::Sin
|
74
|
+
return @x.x
|
75
|
+
end
|
76
|
+
return self
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.asin(x)
|
81
|
+
CAS::Asin.new x
|
82
|
+
end
|
83
|
+
|
84
|
+
# ___
|
85
|
+
# / __|___ ___
|
86
|
+
# | (__/ _ (_-<
|
87
|
+
# \___\___/__/
|
88
|
+
class Cos < CAS::Op
|
89
|
+
def diff(v)
|
90
|
+
if @x.depend? v
|
91
|
+
return CAS.invert(@x.diff(v) * CAS.sin(@x))
|
92
|
+
else
|
93
|
+
return CAS::Zero
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def call(f)
|
98
|
+
Math::cos self.x.call(f)
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
"cos(#{self.x})"
|
103
|
+
end
|
104
|
+
|
105
|
+
def simplify
|
106
|
+
super
|
107
|
+
if @x == CAS::Zero
|
108
|
+
return CAS::One
|
109
|
+
end
|
110
|
+
if @x == CAS::Pi
|
111
|
+
return CAS::One
|
112
|
+
end
|
113
|
+
if @x.is_a? CAS::Acos
|
114
|
+
return @x.x
|
115
|
+
end
|
116
|
+
return self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.cos(x)
|
121
|
+
CAS::Cos.new x
|
122
|
+
end
|
123
|
+
|
124
|
+
# _
|
125
|
+
# /_\ __ ___ ___
|
126
|
+
# / _ \/ _/ _ (_-<
|
127
|
+
# /_/ \_\__\___/__/
|
128
|
+
class Acos < CAS::Op
|
129
|
+
def diff(v)
|
130
|
+
if @x.depend? v
|
131
|
+
return CAS.invert(@x.diff(v)/CAS.sqrt(CAS::One - CAS.pow(@x, CAS::Two)))
|
132
|
+
else
|
133
|
+
return CAS::Zero
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def call(f)
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_s
|
142
|
+
"acos(#{self.x})"
|
143
|
+
end
|
144
|
+
|
145
|
+
def simplify
|
146
|
+
super
|
147
|
+
if @x == CAS::Zero
|
148
|
+
return CAS::Pi / 2
|
149
|
+
end
|
150
|
+
if @x == CAS::One
|
151
|
+
return CAS::Zero
|
152
|
+
end
|
153
|
+
if @x.is_a? CAS::Cos
|
154
|
+
return @x.x
|
155
|
+
end
|
156
|
+
return self
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.acos(x)
|
161
|
+
CAS::Acos.new x
|
162
|
+
end
|
163
|
+
|
164
|
+
# _____
|
165
|
+
# |_ _|_ _ _ _
|
166
|
+
# | |/ _` | ' \
|
167
|
+
# |_|\__,_|_||_|
|
168
|
+
class Tan < CAS::Op
|
169
|
+
def diff(v)
|
170
|
+
if @x.depend? v
|
171
|
+
return @x.diff(v) * CAS.pow(CAS::One/CAS.cos(@x), CAS::Two)
|
172
|
+
else
|
173
|
+
return CAS::Zero
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def call(f)
|
178
|
+
Math::tan self.x.call
|
179
|
+
end
|
180
|
+
|
181
|
+
def to_s
|
182
|
+
"tan(#{self.x})"
|
183
|
+
end
|
184
|
+
|
185
|
+
def simplify
|
186
|
+
super
|
187
|
+
if @x == CAS::Zero
|
188
|
+
return CAS::Zero
|
189
|
+
end
|
190
|
+
if @x == CAS::Pi
|
191
|
+
return CAS::Zero
|
192
|
+
end
|
193
|
+
if @x.is_a? CAS::Atan
|
194
|
+
return @x.x
|
195
|
+
end
|
196
|
+
return self
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.tan(x)
|
201
|
+
CAS::Tan.new x
|
202
|
+
end
|
203
|
+
|
204
|
+
# _ _
|
205
|
+
# /_\| |_ __ _ _ _
|
206
|
+
# / _ \ _/ _` | ' \
|
207
|
+
# /_/ \_\__\__,_|_||_|
|
208
|
+
class Atan < CAS::Op
|
209
|
+
def diff(v)
|
210
|
+
if @x.depend? v
|
211
|
+
return @x.diff(v) / (CAS.pow(@x, CAS::Two) + CAS::One)
|
212
|
+
else
|
213
|
+
return CAS::Zero
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def call
|
218
|
+
Math::atan self.x.call
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_s
|
222
|
+
"atan(#{self.x})"
|
223
|
+
end
|
224
|
+
|
225
|
+
def simplify
|
226
|
+
super
|
227
|
+
if @x == CAS::Zero
|
228
|
+
return CAS::Zero
|
229
|
+
end
|
230
|
+
if @x == CAS::One
|
231
|
+
return CAS::Pi / 4
|
232
|
+
end
|
233
|
+
if @x == CAS::Infinity
|
234
|
+
return CAS::Pi / 2
|
235
|
+
end
|
236
|
+
if @x.is_a? CAS::Tan
|
237
|
+
return @x.x
|
238
|
+
end
|
239
|
+
return self
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.atan(x)
|
244
|
+
CAS::Atan.new x
|
245
|
+
end
|
246
|
+
end
|
data/lib/fnc-trsc.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
# ___ _
|
5
|
+
# | __|_ ___ __ ___ _ _ ___ _ _| |_
|
6
|
+
# | _|\ \ / '_ \/ _ \ ' \/ -_) ' \ _|
|
7
|
+
# |___/_\_\ .__/\___/_||_\___|_||_\__|
|
8
|
+
# |_|
|
9
|
+
class Exp < CAS::Op
|
10
|
+
def diff(v)
|
11
|
+
if @x.depend? v
|
12
|
+
return @x.diff(v) * CAS.exp(@x)
|
13
|
+
else
|
14
|
+
return CAS::Zero
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(f)
|
19
|
+
Math::exp @x.call(f)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"exp(#{@x})"
|
24
|
+
end
|
25
|
+
|
26
|
+
def simplify
|
27
|
+
super
|
28
|
+
if @x == CAS::Zero
|
29
|
+
return CAS::One
|
30
|
+
end
|
31
|
+
if @x == CAS::One
|
32
|
+
return CAS::E
|
33
|
+
end
|
34
|
+
if @x == CAS::Infinity
|
35
|
+
return CAS::Infinity
|
36
|
+
end
|
37
|
+
if @x.is_a? CAS::Ln
|
38
|
+
return @x.x
|
39
|
+
end
|
40
|
+
return self
|
41
|
+
end
|
42
|
+
end # Exp
|
43
|
+
|
44
|
+
def self.exp(x)
|
45
|
+
CAS::Exp.new x
|
46
|
+
end
|
47
|
+
|
48
|
+
# _ _ _ _
|
49
|
+
# | | ___ __ _ __ _ _ _(_) |_| |_ _ __
|
50
|
+
# | |__/ _ \/ _` / _` | '_| | _| ' \| ' \
|
51
|
+
# |____\___/\__, \__,_|_| |_|\__|_||_|_|_|_|
|
52
|
+
# |___/
|
53
|
+
class Ln < CAS::Op
|
54
|
+
def diff(v)
|
55
|
+
if @x.depend? v
|
56
|
+
return CAS::One / @x
|
57
|
+
else
|
58
|
+
return CAS::Zero
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def call(f)
|
63
|
+
# I'm leaving to Math the honor
|
64
|
+
# of handling negative values...
|
65
|
+
Math::log @x.call(f)
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"log(#{@x})"
|
70
|
+
end
|
71
|
+
|
72
|
+
def simplify
|
73
|
+
super
|
74
|
+
if @x == CAS::Zero
|
75
|
+
return CAS.invert(CAS::Infinity)
|
76
|
+
end
|
77
|
+
if @x == CAS::One
|
78
|
+
return CAS::Zero
|
79
|
+
end
|
80
|
+
if @x == CAS::E
|
81
|
+
return CAS::One
|
82
|
+
end
|
83
|
+
if @x.is_a? CAS::Exp
|
84
|
+
return @x.x
|
85
|
+
end
|
86
|
+
return self
|
87
|
+
end
|
88
|
+
end # Ln
|
89
|
+
|
90
|
+
def self.ln(x)
|
91
|
+
CAS::Ln.new x
|
92
|
+
end
|
93
|
+
def self.log(x)
|
94
|
+
CAS::Ln.new x
|
95
|
+
end
|
96
|
+
end
|
data/lib/numbers.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
# ___ _ _
|
5
|
+
# / __|___ _ _ __| |_ __ _ _ _| |_
|
6
|
+
# | (__/ _ \ ' \(_-< _/ _` | ' \ _|
|
7
|
+
# \___\___/_||_/__/\__\__,_|_||_\__|
|
8
|
+
class Constant < CAS::Op
|
9
|
+
def initialize(x)
|
10
|
+
@x = x
|
11
|
+
end
|
12
|
+
|
13
|
+
def diff(v); CAS::Zero; end
|
14
|
+
def call(f = {}); @x; end
|
15
|
+
def depend?(v); false; end
|
16
|
+
def to_s; "#{@x}"; end
|
17
|
+
def simplify
|
18
|
+
case x
|
19
|
+
when 0
|
20
|
+
return CAS::Zero
|
21
|
+
when 1
|
22
|
+
return CAS::One
|
23
|
+
when Math::PI
|
24
|
+
return CAS::Pi
|
25
|
+
when Math::E
|
26
|
+
return CAS::E
|
27
|
+
when 1.0/0.0
|
28
|
+
return CAS::Infinity
|
29
|
+
else
|
30
|
+
return self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def self.const(f)
|
35
|
+
CAS::Constant.new f
|
36
|
+
end
|
37
|
+
|
38
|
+
# __ __ _ _ _
|
39
|
+
# \ \ / /_ _ _ _(_)__ _| |__| |___
|
40
|
+
# \ V / _` | '_| / _` | '_ \ / -_)
|
41
|
+
# \_/\__,_|_| |_\__,_|_.__/_\___|
|
42
|
+
class Variable < CAS::Op
|
43
|
+
def initialize(name = "x")
|
44
|
+
self.is(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def is(name)
|
48
|
+
@name = name
|
49
|
+
end
|
50
|
+
|
51
|
+
def diff(v)
|
52
|
+
CAS::One
|
53
|
+
end
|
54
|
+
|
55
|
+
def depend?(v)
|
56
|
+
self == v
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(f)
|
60
|
+
f[self]
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
"#{@name}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def simplify
|
68
|
+
return self
|
69
|
+
end
|
70
|
+
end # Number
|
71
|
+
|
72
|
+
# _______ ___ ___
|
73
|
+
# |_ / __| _ \/ _ \
|
74
|
+
# / /| _|| / (_) |
|
75
|
+
# /___|___|_|_\\___/
|
76
|
+
class ZERO_CONSTANT < CAS::Constant
|
77
|
+
def initialize
|
78
|
+
@x = 0.0
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
"0"
|
83
|
+
end
|
84
|
+
end # Zero
|
85
|
+
Zero = CAS::ZERO_CONSTANT.new
|
86
|
+
|
87
|
+
# ___
|
88
|
+
# / _ \ _ _ ___
|
89
|
+
# | (_) | ' \/ -_)
|
90
|
+
# \___/|_||_\___|
|
91
|
+
class ONE_CONSTANT < CAS::Constant
|
92
|
+
def initialize
|
93
|
+
@x = 1.0
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_s
|
97
|
+
"1"
|
98
|
+
end
|
99
|
+
end # Zero
|
100
|
+
One = CAS::ONE_CONSTANT.new
|
101
|
+
|
102
|
+
# _____
|
103
|
+
# |_ _|_ __ _____
|
104
|
+
# | | \ V V / _ \
|
105
|
+
# |_| \_/\_/\___/
|
106
|
+
class TWO_CONSTANT < CAS::Constant
|
107
|
+
def initialize
|
108
|
+
@x = 2.0
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_s
|
112
|
+
"2"
|
113
|
+
end
|
114
|
+
end # Zero
|
115
|
+
Two = CAS::TWO_CONSTANT.new
|
116
|
+
|
117
|
+
# ___ ___
|
118
|
+
# | _ \_ _|
|
119
|
+
# | _/| |
|
120
|
+
# |_| |___|
|
121
|
+
class PI_CONSTANT < CAS::Constant
|
122
|
+
def initialize
|
123
|
+
@x = Math::PI
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_s
|
127
|
+
"π"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
Pi = CAS::PI_CONSTANT.new
|
131
|
+
|
132
|
+
# ___
|
133
|
+
# | __|
|
134
|
+
# | _|
|
135
|
+
# |___|
|
136
|
+
class E_CONSTANT < CAS::Constant
|
137
|
+
def initialize
|
138
|
+
@x = Math::E
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_s
|
142
|
+
"e"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
E = CAS::E_CONSTANT.new
|
146
|
+
|
147
|
+
# ___ __ _ _ _
|
148
|
+
# |_ _|_ _ / _(_)_ _ (_) |_ _ _
|
149
|
+
# | || ' \| _| | ' \| | _| || |
|
150
|
+
# |___|_||_|_| |_|_||_|_|\__|\_, |
|
151
|
+
# |__/
|
152
|
+
class INFINITY_CONSTANT < CAS::Constant
|
153
|
+
def initialize
|
154
|
+
@x = (1.0/0.0)
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_s
|
158
|
+
"∞"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
Infinity = CAS::INFINITY_CONSTANT.new
|
162
|
+
|
163
|
+
# _
|
164
|
+
# ___/ |
|
165
|
+
# |___| |
|
166
|
+
# |_|
|
167
|
+
class MINUS_ONE_CONSTANT < CAS::Constant
|
168
|
+
def initialize
|
169
|
+
@x = -1.0
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_s
|
173
|
+
"-1"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
MinusOne = CAS::MINUS_ONE_CONSTANT.new
|
177
|
+
end
|
data/lib/op.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
class CASError < RuntimeError; end
|
5
|
+
|
6
|
+
# ___
|
7
|
+
# / _ \ _ __
|
8
|
+
# | (_) | '_ \
|
9
|
+
# \___/| .__/
|
10
|
+
# |_|
|
11
|
+
class Op
|
12
|
+
attr_reader :x
|
13
|
+
|
14
|
+
def initialize(x)
|
15
|
+
if x.is_a? Numeric
|
16
|
+
case x
|
17
|
+
when 0
|
18
|
+
x = CAS::Zero
|
19
|
+
when 1
|
20
|
+
x = CAS::One
|
21
|
+
else
|
22
|
+
x = CAS.const x
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@x = x
|
26
|
+
end
|
27
|
+
|
28
|
+
def depend?(v)
|
29
|
+
@x.depend? v
|
30
|
+
end
|
31
|
+
|
32
|
+
def diff(v)
|
33
|
+
if @x.depend? v
|
34
|
+
return @x.diff(v)
|
35
|
+
end
|
36
|
+
CAS::Zero
|
37
|
+
end
|
38
|
+
|
39
|
+
def call(f)
|
40
|
+
@x.call(f)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"#{@x}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def +(op)
|
48
|
+
CAS::Sum.new self, op
|
49
|
+
end
|
50
|
+
|
51
|
+
def -(op)
|
52
|
+
CAS::Diff.new self, op
|
53
|
+
end
|
54
|
+
|
55
|
+
def *(op)
|
56
|
+
CAS::Prod.new self, op
|
57
|
+
end
|
58
|
+
|
59
|
+
def /(op)
|
60
|
+
CAS::Div.new self, op
|
61
|
+
end
|
62
|
+
|
63
|
+
def **(op)
|
64
|
+
CAS.pow(self, op)
|
65
|
+
end
|
66
|
+
|
67
|
+
def simplify # TODO: improve this
|
68
|
+
hash = @x.to_s
|
69
|
+
@x = @x.simplify
|
70
|
+
while @x.to_s != hash
|
71
|
+
hash = @x.to_s
|
72
|
+
@x = @x.simplify
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end # Op
|
76
|
+
|
77
|
+
# ___ _ ___
|
78
|
+
# | _ |_)_ _ __ _ _ _ _ _ / _ \ _ __
|
79
|
+
# | _ \ | ' \/ _` | '_| || | (_) | '_ \
|
80
|
+
# |___/_|_||_\__,_|_| \_, |\___/| .__/
|
81
|
+
# |__/ |_|
|
82
|
+
class BinaryOp < CAS::Op
|
83
|
+
attr_reader :x, :y
|
84
|
+
|
85
|
+
def initialize(x, y)
|
86
|
+
if x.is_a? Numeric
|
87
|
+
case x
|
88
|
+
when 0
|
89
|
+
x = CAS::Zero
|
90
|
+
when 1
|
91
|
+
x = CAS::One
|
92
|
+
else
|
93
|
+
x = CAS.const x
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if y.is_a? Numeric
|
97
|
+
case y
|
98
|
+
when 0
|
99
|
+
y = CAS::Zero
|
100
|
+
when 1
|
101
|
+
y = CAS::One
|
102
|
+
else
|
103
|
+
y = CAS.const y
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@x = x
|
107
|
+
@y = y
|
108
|
+
end
|
109
|
+
|
110
|
+
def depend?(v)
|
111
|
+
@x.depend? v or @y.depend? v
|
112
|
+
end
|
113
|
+
|
114
|
+
def diff(v)
|
115
|
+
left = @x.diff(v) if @x.depend? v
|
116
|
+
right = @y.diff(v) if @y.depend? v
|
117
|
+
return left, right
|
118
|
+
end
|
119
|
+
|
120
|
+
def call
|
121
|
+
raise CASError, "Not Implemented. This is a virtual method"
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_s
|
125
|
+
raise CASError, "Not Implemented. This is a virtual method"
|
126
|
+
end
|
127
|
+
|
128
|
+
def simplify # TODO: improve this
|
129
|
+
hash = @x.to_s
|
130
|
+
@x = @x.simplify
|
131
|
+
while @x.to_s != hash
|
132
|
+
hash = @x.to_s
|
133
|
+
@x = @x.simplify
|
134
|
+
end
|
135
|
+
hash = @y.to_s
|
136
|
+
@y = @y.simplify
|
137
|
+
while @y.to_s != hash
|
138
|
+
hash = @y.to_s
|
139
|
+
@y = @y.simplify
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end # BinaryOp
|
143
|
+
end
|
data/lib/ragni-cas.rb
ADDED
data.tar.gz.sig
ADDED
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ragni-cas
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matteo Ragni
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDXDCCAkSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARpbmZv
|
14
|
+
MRUwEwYKCZImiZPyLGQBGRYFcmFnbmkxEjAQBgoJkiaJk/IsZAEZFgJtZTAeFw0x
|
15
|
+
NjA3MTkwOTM5NDlaFw0xNzA3MTkwOTM5NDlaMDoxDTALBgNVBAMMBGluZm8xFTAT
|
16
|
+
BgoJkiaJk/IsZAEZFgVyYWduaTESMBAGCgmSJomT8ixkARkWAm1lMIIBIjANBgkq
|
17
|
+
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5pUTV/VZWpaYCwB2rr98GHoqv7UfD4Fo
|
18
|
+
3pFi+Ds21h0laaniQ0LrJSj0JVQmYQwcqJ0AZKDuunQvMo23PZyIJAqKXktaGaYX
|
19
|
+
4y0KT0wIiZqlQLlwgRgkdMkVpKOSQGXrfNdXrULnHVTBLpE5f/S6ZQbsgWZudy1x
|
20
|
+
vDjgp3KTeLymcCBuIcypPziSFL/M9kUXYz13hxJsPjkEJ/BGmkXE03dG9o9VF202
|
21
|
+
gvQ5P5PWfLoSraVySngdVeT961eLvyBSBXAxVwdyRdI7Xm/TndjJNWh87q0Jhy8Q
|
22
|
+
WIV5gL/uNj8MXJX+g9h95TUbygg+FkI/dQHyIlAQ2xkVEH5NJ6Y/CQIDAQABo20w
|
23
|
+
azAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUHVooQSoXXUXlIT4/
|
24
|
+
9PIoqmGwd/IwGAYDVR0RBBEwD4ENaW5mb0ByYWduaS5tZTAYBgNVHRIEETAPgQ1p
|
25
|
+
bmZvQHJhZ25pLm1lMA0GCSqGSIb3DQEBBQUAA4IBAQBcPsPbIm7Oo3qQ3X9niTxZ
|
26
|
+
pv6eocyknwGZXZCH9LLgEXRSWXKHKr/MODo+zCUzi7cNV0hDf5v9+VATMNILH1L8
|
27
|
+
OXWyvnb80Shs9mCgSVbkgb0QImllwIdLiPJF9ywFs3WJDbUVXPRfGWS8BfSxUbvV
|
28
|
+
+fanYc7ZC6ffsjv7+2rEgWhPlZKnWG7cqCxv5gVVldCOSvbot6ai9x6hFHlG7rud
|
29
|
+
XorZtzkkLImvKFj35xKLFfVkv0Vd8tGQoiL8vdmQNJjAjtE+C+Y7OI4dpiZPKO4G
|
30
|
+
R/8JOvUuk9jPbyLxjQH/sFaFqqYGX2xo1zk2CRy/A0WhJrSaXVw1r5lEi7b0W5gg
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2016-07-19 00:00:00.000000000 Z
|
33
|
+
dependencies: []
|
34
|
+
description:
|
35
|
+
email: info@ragni.me
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- lib/fnc-base.rb
|
41
|
+
- lib/fnc-trig.rb
|
42
|
+
- lib/fnc-trsc.rb
|
43
|
+
- lib/numbers.rb
|
44
|
+
- lib/op.rb
|
45
|
+
- lib/ragni-cas.rb
|
46
|
+
homepage: https://github.com/MatteoRagni/cas-rb
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.5.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: An extremely simple CAS system for my optimizers
|
70
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|