symcalc 0.6.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/symcalc.rb +278 -382
- metadata +16 -10
- data/lib/LICENSE.txt +0 -202
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1cb3c53ef5f25cad69cde67e01cffa1114da6954c06cd75b5a8377ffc382777
|
4
|
+
data.tar.gz: 617a794848e3a658f83f5a8aaf0873e9727acd46ceb485b12020c8813efabcfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0108441596b3221a311b2ff0fd7f423adfb4440c0400f0bbbc138d454ea2db163fbb71b453566e89b3dfa70704dbb4ed7bae648b641d7966d5e04986db8ba50b'
|
7
|
+
data.tar.gz: 59e7edab69404cb37e93f82a6cfa0de2a05b8a4ae2105bbf9d526792359717539b0059640d5b8d141870b3964b6a31675a490a5071df2b4838fafb32fcc85782
|
data/lib/symcalc.rb
CHANGED
@@ -6,10 +6,6 @@
|
|
6
6
|
#
|
7
7
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
8
|
#
|
9
|
-
# or
|
10
|
-
#
|
11
|
-
# read LICENSE.txt in the SymCalc lib folder
|
12
|
-
#
|
13
9
|
# Unless required by applicable law or agreed to in writing, software
|
14
10
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -17,38 +13,70 @@
|
|
17
13
|
# limitations under the License.
|
18
14
|
|
19
15
|
|
16
|
+
# SymCalc auto simplify option
|
17
|
+
if !$SYMCALC_AUTO_SIMPLIFY
|
18
|
+
$SYMCALC_AUTO_SIMPLIFY = true
|
19
|
+
end
|
20
|
+
|
21
|
+
# The SymCalc module
|
22
|
+
module SymCalc
|
23
|
+
|
20
24
|
class Equation
|
21
25
|
|
22
26
|
def to_s
|
23
27
|
self.display()
|
24
28
|
end
|
25
29
|
|
26
|
-
def inspect
|
27
|
-
|
30
|
+
# def inspect
|
31
|
+
# self.display()
|
32
|
+
# end
|
33
|
+
|
34
|
+
def display
|
35
|
+
""
|
28
36
|
end
|
29
37
|
|
30
38
|
def coerce(other)
|
31
|
-
[to_equation(other), self]
|
39
|
+
[SymCalc.to_equation(other), self]
|
32
40
|
end
|
33
41
|
|
34
42
|
def *(eq)
|
35
|
-
|
43
|
+
eq = Multiplication.new([self, SymCalc.to_equation(eq)])
|
44
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
45
|
+
eq
|
36
46
|
end
|
37
47
|
|
38
48
|
def /(eq)
|
39
|
-
|
49
|
+
eq = Division.new(self, SymCalc.to_equation(eq))
|
50
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
51
|
+
eq
|
40
52
|
end
|
41
53
|
|
42
54
|
def +(eq)
|
43
|
-
|
55
|
+
eq = Sum.new([self, SymCalc.to_equation(eq)])
|
56
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
57
|
+
eq
|
58
|
+
end
|
59
|
+
|
60
|
+
def -@()
|
61
|
+
eq = Negate.new(self)
|
62
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
63
|
+
eq
|
44
64
|
end
|
45
65
|
|
46
66
|
def -(eq)
|
47
|
-
|
67
|
+
eq = Sum.new([self, Negate.new(SymCalc.to_equation(eq))])
|
68
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
69
|
+
eq
|
48
70
|
end
|
49
71
|
|
50
72
|
def **(eq)
|
51
|
-
|
73
|
+
eq = Power.new(self, SymCalc.to_equation(eq))
|
74
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
75
|
+
eq
|
76
|
+
end
|
77
|
+
|
78
|
+
def __derivative__(variable: nil)
|
79
|
+
raise "No derivative function implemented for this object"
|
52
80
|
end
|
53
81
|
|
54
82
|
# Calculate the derivative of the given function
|
@@ -66,17 +94,19 @@ class Equation
|
|
66
94
|
#
|
67
95
|
def derivative(order: 1, variable: nil)
|
68
96
|
if variable == nil && self.all_variables.size < 2
|
69
|
-
fx = self
|
97
|
+
fx = self.simplify
|
70
98
|
order.times do
|
71
|
-
fx = fx.
|
99
|
+
fx = fx.__derivative__
|
100
|
+
fx = fx.simplify if $SYMCALC_AUTO_SIMPLIFY
|
72
101
|
end
|
73
102
|
return fx
|
74
103
|
elsif variable == nil && self.all_variables.size > 1
|
75
104
|
raise "Expected a variable as input for a #{self.all_variables.size}-dimensional function"
|
76
105
|
else
|
77
|
-
fx = self
|
106
|
+
fx = self.simplify
|
78
107
|
order.times do
|
79
|
-
fx = fx.
|
108
|
+
fx = fx.__derivative__(variable: variable)
|
109
|
+
fx = fx.simplify if $SYMCALC_AUTO_SIMPLIFY
|
80
110
|
end
|
81
111
|
return fx
|
82
112
|
end
|
@@ -90,98 +120,12 @@ class Equation
|
|
90
120
|
# Accepts no arguments
|
91
121
|
#
|
92
122
|
def simplify
|
93
|
-
|
94
|
-
simplified = self.__simplify__
|
95
|
-
|
96
|
-
if [Multiplication, Division].include? simplified.class
|
97
|
-
m_els = simplified.__get_m_elements__(Hash.new)
|
98
|
-
|
99
|
-
if m_els.keys.size == 0
|
100
|
-
return EquationValue.new(0)
|
101
|
-
elsif m_els.keys.size == 1
|
102
|
-
part = m_els.keys[0]
|
103
|
-
power = to_equation(m_els.values[0])
|
104
|
-
if part == "exp"
|
105
|
-
part = (power == to_equation(1)) ? BasicVars::E : Exp.new(power)
|
106
|
-
else
|
107
|
-
part = part ** power if power != to_equation(1)
|
108
|
-
end
|
109
|
-
return part
|
110
|
-
else
|
111
|
-
els_index = 0
|
112
|
-
eq = nil
|
113
|
-
|
114
|
-
coeff = to_equation(1)
|
115
|
-
|
116
|
-
m_els.size.times do |els_index|
|
117
|
-
base = m_els.keys[els_index]
|
118
|
-
power = m_els[base]
|
119
|
-
|
120
|
-
base = base.simplify if base.is_a? Equation
|
121
|
-
power = power.simplify if power.is_a? Equation
|
122
|
-
|
123
|
-
base = to_equation base if base != "exp"
|
124
|
-
power = to_equation power
|
125
|
-
|
126
|
-
if power == to_equation(0)
|
127
|
-
next
|
128
|
-
end
|
129
|
-
|
130
|
-
if base.is_a?(EquationValue) && power.is_a?(EquationValue)
|
131
|
-
case power
|
132
|
-
when EquationValue.new(1)
|
133
|
-
coeff *= base
|
134
|
-
else
|
135
|
-
coeff *= base ** power
|
136
|
-
end
|
137
|
-
next
|
138
|
-
end
|
139
|
-
|
140
|
-
if base == "exp"
|
141
|
-
case power
|
142
|
-
when to_equation(1)
|
143
|
-
part = BasicVars::E
|
144
|
-
else
|
145
|
-
part = Exp.new(power)
|
146
|
-
end
|
147
|
-
else
|
148
|
-
case power
|
149
|
-
when to_equation(1)
|
150
|
-
part = base
|
151
|
-
else
|
152
|
-
part = base ** power
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
if eq == nil
|
157
|
-
eq = part
|
158
|
-
else
|
159
|
-
eq *= part
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
coeff = coeff.__simplify__
|
165
|
-
|
166
|
-
if coeff == to_equation(1)
|
167
|
-
eq = eq
|
168
|
-
elsif coeff == to_equation(0)
|
169
|
-
eq = to_equation(0)
|
170
|
-
elsif eq == nil
|
171
|
-
eq = coeff
|
172
|
-
else
|
173
|
-
eq = coeff * eq
|
174
|
-
end
|
175
|
-
|
176
|
-
return eq
|
177
|
-
end
|
178
|
-
|
179
|
-
else
|
180
|
-
return simplified
|
181
|
-
end
|
182
|
-
|
123
|
+
self.__simplify__
|
183
124
|
end
|
184
125
|
|
126
|
+
def __eval__(var_hash)
|
127
|
+
raise "__eval__ method not implemented for this class"
|
128
|
+
end
|
185
129
|
|
186
130
|
# Evaluates the function at given variable values
|
187
131
|
# Accepts the hash of variables and their values to evalualte the function
|
@@ -191,9 +135,10 @@ class Equation
|
|
191
135
|
# fx = x ** 2
|
192
136
|
# puts fx.eval(x: 3)
|
193
137
|
#
|
194
|
-
def eval(var_hash)
|
138
|
+
def eval(var_hash = nil)
|
139
|
+
var_hash = Hash.new if !var_hash
|
195
140
|
if var_hash.values.size == 0
|
196
|
-
result = self.__eval__(
|
141
|
+
result = self.__eval__(var_hash)
|
197
142
|
elsif !var_hash.values[0].is_a?(Array)
|
198
143
|
result = self.__eval__ var_hash
|
199
144
|
elsif var_hash.values[0].is_a? Array
|
@@ -209,7 +154,7 @@ class Equation
|
|
209
154
|
|
210
155
|
|
211
156
|
def __sub__ original, replacement
|
212
|
-
return to_equation(replacement) if self == to_equation(original)
|
157
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
213
158
|
return self
|
214
159
|
end
|
215
160
|
|
@@ -222,8 +167,11 @@ class Equation
|
|
222
167
|
# puts f.sub(a, 3 * x) # => (3 * x) ** 2
|
223
168
|
#
|
224
169
|
def sub original, replacement
|
225
|
-
self.__sub__(original, replacement)
|
170
|
+
eq = self.__sub__(original, replacement)
|
171
|
+
eq = eq.simplify if $SYMCALC_AUTO_SIMPLIFY
|
172
|
+
eq
|
226
173
|
end
|
174
|
+
|
227
175
|
end
|
228
176
|
|
229
177
|
# Converts the given argument into the equation type, if not already an equation
|
@@ -264,31 +212,49 @@ class EquationValue < Equation
|
|
264
212
|
@value == value
|
265
213
|
end
|
266
214
|
|
267
|
-
def
|
268
|
-
|
215
|
+
def all_variables
|
216
|
+
[]
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
# Implements the Constant class. Behaves like EquationValue when evaluating and like Variable when printing
|
222
|
+
class Constant < Equation
|
223
|
+
|
224
|
+
attr_accessor :value, :name
|
225
|
+
|
226
|
+
def initialize(name, value)
|
227
|
+
@value = value
|
228
|
+
@name = name
|
269
229
|
end
|
270
230
|
|
271
|
-
def
|
272
|
-
return
|
273
|
-
return obj.value == @value
|
231
|
+
def display
|
232
|
+
return @name
|
274
233
|
end
|
275
234
|
|
276
|
-
def
|
277
|
-
if
|
278
|
-
|
235
|
+
def __eval__ var_hash
|
236
|
+
if @value.is_a? Integer
|
237
|
+
return @value.to_f
|
279
238
|
else
|
280
|
-
|
239
|
+
return @value
|
281
240
|
end
|
282
|
-
return var_hash
|
283
241
|
end
|
284
242
|
|
243
|
+
def __derivative__ variable: nil
|
244
|
+
return EquationValue.new 0
|
245
|
+
end
|
246
|
+
|
247
|
+
def ==(value)
|
248
|
+
@value == value
|
249
|
+
end
|
285
250
|
|
286
251
|
def all_variables
|
287
252
|
[]
|
288
253
|
end
|
289
|
-
|
254
|
+
|
290
255
|
end
|
291
256
|
|
257
|
+
|
292
258
|
# Implements the Variable class
|
293
259
|
class Variable < Equation
|
294
260
|
|
@@ -301,9 +267,8 @@ class Variable < Equation
|
|
301
267
|
# fx = x ** 2
|
302
268
|
# fx.eval # => 25
|
303
269
|
#
|
304
|
-
def initialize name
|
270
|
+
def initialize name
|
305
271
|
@name = name
|
306
|
-
@fixed_value = fixed_value
|
307
272
|
end
|
308
273
|
|
309
274
|
def display
|
@@ -311,9 +276,7 @@ class Variable < Equation
|
|
311
276
|
end
|
312
277
|
|
313
278
|
def __eval__ var_hash
|
314
|
-
if @
|
315
|
-
return @fixed_value
|
316
|
-
elsif var_hash.keys.include?(@name.to_sym) or var_hash.keys.include?(@name.to_s)
|
279
|
+
if var_hash.keys.include?(@name.to_sym) or var_hash.keys.include?(@name.to_s)
|
317
280
|
return (var_hash[@name.to_sym] or var_hash[@name.to_s])
|
318
281
|
else
|
319
282
|
raise "No value provided for #{@name.to_s} in eval"
|
@@ -325,17 +288,12 @@ class Variable < Equation
|
|
325
288
|
if variable == nil || variable == self
|
326
289
|
return EquationValue.new 1
|
327
290
|
else
|
328
|
-
return to_equation(0)
|
291
|
+
return SymCalc.to_equation(0)
|
329
292
|
end
|
330
293
|
end
|
331
294
|
|
332
|
-
def
|
333
|
-
|
334
|
-
var_hash[self] += 1
|
335
|
-
else
|
336
|
-
var_hash[self] = 1
|
337
|
-
end
|
338
|
-
return var_hash
|
295
|
+
def __simplify__
|
296
|
+
self
|
339
297
|
end
|
340
298
|
|
341
299
|
def all_variables
|
@@ -343,174 +301,183 @@ class Variable < Equation
|
|
343
301
|
end
|
344
302
|
end
|
345
303
|
|
346
|
-
# Basic variables that are already implemented in SymCalc and have fixed values
|
347
|
-
module BasicVars
|
348
|
-
|
349
|
-
E = Variable.new "e", Math::E
|
350
|
-
|
351
|
-
end
|
352
304
|
|
353
305
|
# Implements sum operations in SymCalc
|
354
306
|
class Sum < Equation
|
355
|
-
def initialize
|
356
|
-
@
|
357
|
-
|
307
|
+
def initialize elements
|
308
|
+
@elements = []
|
309
|
+
elements.each do |eq|
|
310
|
+
if eq.is_a? Sum
|
311
|
+
@elements += eq.instance_variable_get(:@elements)
|
312
|
+
else
|
313
|
+
@elements << eq
|
314
|
+
end
|
315
|
+
end
|
358
316
|
end
|
359
317
|
|
360
318
|
def display
|
361
|
-
return "(#{
|
319
|
+
return @elements.map{|eq| "(#{eq.display})"}.join(" + ")
|
362
320
|
end
|
363
321
|
|
364
322
|
def __eval__ var_hash
|
365
|
-
return @
|
323
|
+
return @elements.map{|eq| eq.eval(var_hash)}.sum
|
366
324
|
end
|
367
325
|
|
368
326
|
def __derivative__ variable: nil
|
369
|
-
return
|
327
|
+
return Sum.new(@elements.map{|eq| eq.__derivative__(variable: variable)})
|
370
328
|
end
|
371
329
|
|
372
330
|
def __simplify__
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
return @lside
|
381
|
-
else
|
382
|
-
return self
|
331
|
+
simplified = @elements.map{|eq| eq.__simplify__}
|
332
|
+
|
333
|
+
simplified.filter! do |el|
|
334
|
+
if el.is_a? EquationValue
|
335
|
+
next if el.value == 0
|
336
|
+
end
|
337
|
+
true
|
383
338
|
end
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
if el_hash.keys.include? self
|
388
|
-
el_hash[self] += 1
|
389
|
-
else
|
390
|
-
el_hash[self] = 1
|
339
|
+
|
340
|
+
if simplified.size == 1
|
341
|
+
return simplified[0]
|
391
342
|
end
|
392
|
-
|
343
|
+
|
344
|
+
return Sum.new(simplified)
|
393
345
|
end
|
394
346
|
|
395
347
|
def all_variables
|
396
|
-
return
|
348
|
+
return @elements.map{|eq| eq.all_variables }.flatten.uniq
|
397
349
|
end
|
398
350
|
|
399
351
|
def __sub__ original, replacement
|
400
|
-
return to_equation(replacement) if self == to_equation(original)
|
401
|
-
|
352
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
353
|
+
|
354
|
+
return Sum.new(@elements.map{|eq| eq.__sub__(original, replacement)})
|
402
355
|
end
|
403
356
|
end
|
404
357
|
|
405
358
|
# Implements the subtraction operation in SymCalc
|
406
|
-
class
|
407
|
-
def initialize
|
408
|
-
@
|
409
|
-
@rside = rside
|
359
|
+
class Negate < Equation
|
360
|
+
def initialize eq
|
361
|
+
@eq = eq
|
410
362
|
end
|
411
363
|
|
412
364
|
def display
|
413
|
-
return "
|
365
|
+
return "-(#{@eq.display})"
|
414
366
|
end
|
415
367
|
|
416
368
|
def __eval__ var_hash
|
417
|
-
return
|
369
|
+
return -@eq.eval(var_hash)
|
418
370
|
end
|
419
371
|
|
420
372
|
def __derivative__ variable: nil
|
421
|
-
return
|
422
|
-
end
|
423
|
-
|
424
|
-
def __get_m_elements__ el_hash
|
425
|
-
if el_hash.keys.include? self
|
426
|
-
el_hash[self] += 1
|
427
|
-
else
|
428
|
-
el_hash[self] = 1
|
429
|
-
end
|
430
|
-
return el_hash
|
373
|
+
return -@eq.__derivative__(variable: variable)
|
431
374
|
end
|
432
375
|
|
433
376
|
def __simplify__
|
434
|
-
|
435
|
-
@rside = @rside.__simplify__
|
436
|
-
|
437
|
-
if (@lside.is_a? EquationValue) && (@rside.is_a? EquationValue)
|
438
|
-
return EquationValue.new((@lside - @rside).eval(Hash.new))
|
439
|
-
elsif @rside == EquationValue.new(0)
|
440
|
-
return @lside
|
441
|
-
elsif @lside == EquationValue.new(0)
|
442
|
-
return -1 * @rside
|
443
|
-
elsif @lside == @rside
|
444
|
-
return EquationValue.new(0)
|
445
|
-
else
|
446
|
-
return self
|
447
|
-
end
|
377
|
+
return Negate.new(@eq.__simplify__)
|
448
378
|
end
|
449
379
|
|
450
380
|
def all_variables
|
451
|
-
return
|
381
|
+
return @eq.all_variables
|
452
382
|
end
|
453
383
|
|
454
384
|
def __sub__ original, replacement
|
455
|
-
return to_equation(replacement) if self == to_equation(original)
|
456
|
-
return
|
385
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
386
|
+
return Negate.new(@eq.__sub__(original, replacement))
|
457
387
|
end
|
458
388
|
end
|
459
389
|
|
460
390
|
# Implements the multiplication operation in SymCalc
|
461
391
|
class Multiplication < Equation
|
462
|
-
def initialize
|
463
|
-
@
|
464
|
-
|
392
|
+
def initialize elements
|
393
|
+
@elements = []
|
394
|
+
elements.each do |el|
|
395
|
+
if el.is_a? Multiplication
|
396
|
+
@elements += el.instance_variable_get(:@elements)
|
397
|
+
else
|
398
|
+
@elements << el
|
399
|
+
end
|
400
|
+
end
|
465
401
|
end
|
466
402
|
|
467
403
|
def display
|
468
|
-
return "(#{
|
404
|
+
return @elements.map{|el| "(#{el.display})"}.join(" * ")
|
469
405
|
end
|
470
406
|
|
471
407
|
def __eval__ var_hash
|
472
|
-
|
408
|
+
result = 1
|
409
|
+
@elements.each do |el|
|
410
|
+
result *= el.__eval__(var_hash)
|
411
|
+
end
|
412
|
+
result
|
473
413
|
end
|
474
414
|
|
475
415
|
def __derivative__ variable: nil
|
476
|
-
|
416
|
+
|
417
|
+
sum_of_mults_arr = []
|
418
|
+
|
419
|
+
@elements.size.times do |element_index|
|
420
|
+
mult_arr = []
|
421
|
+
|
422
|
+
|
423
|
+
mult_arr << @elements[element_index].__derivative__(variable: variable)
|
424
|
+
|
425
|
+
@elements.size.times do |mult_el_index|
|
426
|
+
if element_index == mult_el_index
|
427
|
+
next
|
428
|
+
end
|
429
|
+
mult_arr << @elements[mult_el_index]
|
430
|
+
end
|
431
|
+
|
432
|
+
sum_of_mults_arr << Multiplication.new(mult_arr)
|
433
|
+
end
|
434
|
+
|
435
|
+
return Sum.new(sum_of_mults_arr)
|
477
436
|
end
|
478
437
|
|
479
438
|
def __simplify__
|
480
|
-
@lside = @lside.__simplify__
|
481
|
-
@rside = @rside.__simplify__
|
482
439
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
440
|
+
numbers = []
|
441
|
+
simplified = []
|
442
|
+
|
443
|
+
@elements.each do |eq|
|
444
|
+
s_eq = eq.__simplify__()
|
445
|
+
|
446
|
+
if s_eq.is_a? EquationValue
|
447
|
+
if s_eq.value == 0
|
448
|
+
return EquationValue.new(0)
|
449
|
+
elsif s_eq.value == 1
|
450
|
+
next
|
451
|
+
else
|
452
|
+
numbers << s_eq.value
|
453
|
+
end
|
493
454
|
else
|
494
|
-
|
495
|
-
end
|
496
|
-
else
|
497
|
-
return self
|
455
|
+
simplified << s_eq
|
456
|
+
end
|
498
457
|
end
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
458
|
+
|
459
|
+
|
460
|
+
coeff = 1
|
461
|
+
numbers.each {|n| coeff *= n}
|
462
|
+
|
463
|
+
if coeff != 1
|
464
|
+
simplified.insert 0, EquationValue.new(coeff)
|
465
|
+
end
|
466
|
+
|
467
|
+
if simplified.size == 1
|
468
|
+
return simplified[0]
|
469
|
+
end
|
470
|
+
|
471
|
+
return Multiplication.new(simplified)
|
505
472
|
end
|
506
473
|
|
507
474
|
def all_variables
|
508
|
-
return
|
475
|
+
return @elements.map{|el| el.all_variables}.flatten.uniq
|
509
476
|
end
|
510
477
|
|
511
478
|
def __sub__ original, replacement
|
512
|
-
return to_equation(replacement) if self == to_equation(original)
|
513
|
-
return
|
479
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
480
|
+
return Multiplication.new(@elements.map{|el| el.__sub__(original, replacement)})
|
514
481
|
end
|
515
482
|
end
|
516
483
|
|
@@ -533,8 +500,8 @@ class Division < Equation
|
|
533
500
|
end
|
534
501
|
|
535
502
|
def __derivative__ variable: nil
|
536
|
-
return (@lside * @rside ** (-1)).derivative(variable: variable)
|
537
|
-
|
503
|
+
# return (@lside * @rside ** (-1)).derivative(variable: variable)
|
504
|
+
return (@lside.derivative(variable: variable) * @rside - @lside * @rside.derivative(variable: variable)) / (@rside ** 2)
|
538
505
|
end
|
539
506
|
|
540
507
|
def __simplify__
|
@@ -555,26 +522,13 @@ class Division < Equation
|
|
555
522
|
end
|
556
523
|
end
|
557
524
|
|
558
|
-
def __get_m_elements__ el_hash
|
559
|
-
mult = @lside.__get_m_elements__(el_hash)
|
560
|
-
div = @rside.__get_m_elements__({})
|
561
|
-
div.each do |k, v|
|
562
|
-
if mult.keys.include? k
|
563
|
-
mult[k] -= v
|
564
|
-
else
|
565
|
-
mult[k] = -v
|
566
|
-
end
|
567
|
-
end
|
568
|
-
return mult
|
569
|
-
end
|
570
|
-
|
571
525
|
|
572
526
|
def all_variables
|
573
527
|
return (@lside.all_variables + @rside.all_variables).uniq
|
574
528
|
end
|
575
529
|
|
576
530
|
def __sub__ original, replacement
|
577
|
-
return to_equation(replacement) if self == to_equation(original)
|
531
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
578
532
|
return @lside.__sub__(original, replacement) / @rside.__sub__(original, replacement)
|
579
533
|
end
|
580
534
|
end
|
@@ -586,7 +540,7 @@ class Exp < Equation
|
|
586
540
|
attr_accessor :power
|
587
541
|
|
588
542
|
def initialize power
|
589
|
-
@power = to_equation(power)
|
543
|
+
@power = SymCalc.to_equation(power)
|
590
544
|
end
|
591
545
|
|
592
546
|
def display
|
@@ -619,21 +573,12 @@ class Exp < Equation
|
|
619
573
|
end
|
620
574
|
end
|
621
575
|
|
622
|
-
def __get_m_elements__ var_hash
|
623
|
-
if var_hash.keys.include? "exp"
|
624
|
-
var_hash["exp"] += @power
|
625
|
-
else
|
626
|
-
var_hash["exp"] = @power
|
627
|
-
end
|
628
|
-
return var_hash
|
629
|
-
end
|
630
|
-
|
631
576
|
def all_variables
|
632
577
|
return @power.all_variables
|
633
578
|
end
|
634
579
|
|
635
580
|
def __sub__ original, replacement
|
636
|
-
return to_equation(replacement) if self == to_equation(original)
|
581
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
637
582
|
return Exp.new(@power.__sub__(original, replacement))
|
638
583
|
end
|
639
584
|
end
|
@@ -671,41 +616,29 @@ class Power < Equation
|
|
671
616
|
return false
|
672
617
|
end
|
673
618
|
end
|
674
|
-
|
675
|
-
def __get_m_elements__ var_hash
|
676
|
-
elms = @base.__get_m_elements__({})
|
677
|
-
elms.each do |k, v|
|
678
|
-
if var_hash.keys.include? k
|
679
|
-
var_hash[k] += v * @power
|
680
|
-
else
|
681
|
-
var_hash[k] = @power
|
682
|
-
end
|
683
|
-
end
|
684
|
-
return var_hash
|
685
|
-
end
|
686
|
-
|
619
|
+
|
687
620
|
def __simplify__
|
688
621
|
|
689
|
-
|
690
|
-
|
622
|
+
s_base = @base.__simplify__
|
623
|
+
s_power = @power.__simplify__
|
691
624
|
|
692
|
-
if
|
625
|
+
if s_power == EquationValue.new(0)
|
693
626
|
return EquationValue.new(1)
|
694
|
-
elsif
|
695
|
-
return
|
696
|
-
elsif
|
697
|
-
computed =
|
627
|
+
elsif s_power == EquationValue.new(1)
|
628
|
+
return s_base
|
629
|
+
elsif s_base.is_a?(EquationValue) && s_power.is_a?(EquationValue)
|
630
|
+
computed = s_base.value ** s_power.value
|
698
631
|
if computed.to_s.size <= 6
|
699
|
-
return to_equation(computed)
|
632
|
+
return SymCalc.to_equation(computed)
|
700
633
|
else
|
701
|
-
return
|
634
|
+
return s_base ** power
|
702
635
|
end
|
703
|
-
elsif
|
704
|
-
new_base =
|
705
|
-
new_power =
|
706
|
-
return (new_base ** new_power).
|
636
|
+
elsif s_base.is_a?(Power)
|
637
|
+
new_base = s_base.base
|
638
|
+
new_power = s_base.power * s_power
|
639
|
+
return (new_base ** new_power).__simplify__
|
707
640
|
else
|
708
|
-
return
|
641
|
+
return Power.new(s_base, s_power)
|
709
642
|
end
|
710
643
|
|
711
644
|
end
|
@@ -715,7 +648,7 @@ class Power < Equation
|
|
715
648
|
end
|
716
649
|
|
717
650
|
def __sub__ original, replacement
|
718
|
-
return to_equation(replacement) if self == to_equation(original)
|
651
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
719
652
|
return @base.__sub__(original, replacement) ** @power.__sub__(original, replacement)
|
720
653
|
end
|
721
654
|
end
|
@@ -742,21 +675,12 @@ class Sin < Equation
|
|
742
675
|
return Sin.new(@eq.__simplify__)
|
743
676
|
end
|
744
677
|
|
745
|
-
def __get_m_elements__ var_hash
|
746
|
-
if var_hash.keys.include? self
|
747
|
-
var_hash[self] += 1
|
748
|
-
else
|
749
|
-
var_hash[self] = 1
|
750
|
-
end
|
751
|
-
return var_hash
|
752
|
-
end
|
753
|
-
|
754
678
|
def all_variables
|
755
679
|
return @eq.all_variables
|
756
680
|
end
|
757
681
|
|
758
682
|
def __sub__ original, replacement
|
759
|
-
return to_equation(replacement) if self == to_equation(original)
|
683
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
760
684
|
return Sin.new(@eq.__sub__(original, replacement))
|
761
685
|
end
|
762
686
|
end
|
@@ -783,21 +707,12 @@ class Cos < Equation
|
|
783
707
|
return Cos.new(@eq.__simplify__)
|
784
708
|
end
|
785
709
|
|
786
|
-
def __get_m_elements__ var_hash
|
787
|
-
if var_hash.keys.include? self
|
788
|
-
var_hash[self] += 1
|
789
|
-
else
|
790
|
-
var_hash[self] = 1
|
791
|
-
end
|
792
|
-
return var_hash
|
793
|
-
end
|
794
|
-
|
795
710
|
def all_variables
|
796
711
|
return @eq.all_variables
|
797
712
|
end
|
798
713
|
|
799
714
|
def __sub__ original, replacement
|
800
|
-
return to_equation(replacement) if self == to_equation(original)
|
715
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
801
716
|
return Cos.new(@eq.__sub__(original, replacement))
|
802
717
|
end
|
803
718
|
end
|
@@ -827,22 +742,13 @@ class Ln < Equation
|
|
827
742
|
def __simplify__
|
828
743
|
return Ln.new(@eq.__simplify__)
|
829
744
|
end
|
830
|
-
|
831
|
-
def __get_m_elements__ var_hash
|
832
|
-
if var_hash.keys.include? self
|
833
|
-
var_hash[self] += 1
|
834
|
-
else
|
835
|
-
var_hash[self] = 1
|
836
|
-
end
|
837
|
-
return var_hash
|
838
|
-
end
|
839
|
-
|
745
|
+
|
840
746
|
def all_variables
|
841
747
|
return @eq.all_variables
|
842
748
|
end
|
843
749
|
|
844
750
|
def __sub__ original, replacement
|
845
|
-
return to_equation(replacement) if self == to_equation(original)
|
751
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
846
752
|
return Ln.new(@eq.__sub__(original, replacement))
|
847
753
|
end
|
848
754
|
end
|
@@ -861,8 +767,8 @@ class Log < Equation
|
|
861
767
|
# fx = Log.new 10, x ** 2
|
862
768
|
#
|
863
769
|
def initialize base, eq
|
864
|
-
@base = to_equation(base)
|
865
|
-
@eq = to_equation(eq)
|
770
|
+
@base = SymCalc.to_equation(base)
|
771
|
+
@eq = SymCalc.to_equation(eq)
|
866
772
|
end
|
867
773
|
|
868
774
|
def display
|
@@ -881,21 +787,12 @@ class Log < Equation
|
|
881
787
|
return Log.new(@base.__simplify__, @eq.__simplify__)
|
882
788
|
end
|
883
789
|
|
884
|
-
def __get_m_elements__ var_hash
|
885
|
-
if var_hash.keys.include? self
|
886
|
-
var_hash[self] += 1
|
887
|
-
else
|
888
|
-
var_hash[self] = 1
|
889
|
-
end
|
890
|
-
return var_hash
|
891
|
-
end
|
892
|
-
|
893
790
|
def all_variables
|
894
791
|
return (@base.all_variables + @eq.all_variables).uniq
|
895
792
|
end
|
896
793
|
|
897
794
|
def __sub__ original, replacement
|
898
|
-
return to_equation(replacement) if self == to_equation(original)
|
795
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
899
796
|
return Log.new(@base.__sub__(original, replacement), @eq.__sub__(original, replacement))
|
900
797
|
end
|
901
798
|
end
|
@@ -906,7 +803,7 @@ class Abs < Equation
|
|
906
803
|
attr_accessor :eq
|
907
804
|
|
908
805
|
def initialize eq
|
909
|
-
@eq = to_equation(eq)
|
806
|
+
@eq = SymCalc.to_equation(eq)
|
910
807
|
end
|
911
808
|
|
912
809
|
def display
|
@@ -921,19 +818,6 @@ class Abs < Equation
|
|
921
818
|
return @eq / Abs.new(@eq) * @eq.derivative(variable: variable)
|
922
819
|
end
|
923
820
|
|
924
|
-
def __simplify__
|
925
|
-
return Abs.new(@eq.__simplify__)
|
926
|
-
end
|
927
|
-
|
928
|
-
def __get_m_elements__ var_hash
|
929
|
-
if var_hash.keys.include? self
|
930
|
-
var_hash[self] += 1
|
931
|
-
else
|
932
|
-
var_hash[self] = 1
|
933
|
-
end
|
934
|
-
return var_hash
|
935
|
-
end
|
936
|
-
|
937
821
|
def __simplify__
|
938
822
|
if @eq.is_a?(Power) && @eq.power.is_a?(EquationValue) && @eq.power.value.is_a?(Numeric) && (@eq.power.value % 2 == 0)
|
939
823
|
return @eq
|
@@ -946,50 +830,62 @@ class Abs < Equation
|
|
946
830
|
end
|
947
831
|
|
948
832
|
def __sub__ original, replacement
|
949
|
-
return to_equation(replacement) if self == to_equation(original)
|
833
|
+
return SymCalc.to_equation(replacement) if self == SymCalc.to_equation(original)
|
950
834
|
return Abs.new(@eq.__sub__(original, replacement))
|
951
835
|
end
|
952
836
|
end
|
953
837
|
|
954
838
|
|
955
|
-
#
|
956
|
-
module
|
957
|
-
|
958
|
-
# sin(equation) is the same as Sin.new(equation), just shorter
|
959
|
-
def sin(eq)
|
960
|
-
return Sin.new(to_equation(eq))
|
961
|
-
end
|
962
|
-
|
963
|
-
# cos(equation) is the same as Cos.new(equation), just shorter
|
964
|
-
def cos(eq)
|
965
|
-
return Cos.new(to_equation(eq))
|
966
|
-
end
|
967
|
-
|
968
|
-
# ln(equation) is the same as Ln.new(equation), just shorter
|
969
|
-
def ln(eq)
|
970
|
-
return Ln.new(to_equation(eq))
|
971
|
-
end
|
972
|
-
|
973
|
-
# log(base, equation) is the same as Log.new(base, equation), just shorter
|
974
|
-
def log(base, eq)
|
975
|
-
return Log.new(to_equation(base), to_equation(eq))
|
976
|
-
end
|
977
|
-
|
978
|
-
# exp(equation) is the same as Exp.new(equation), just shorter
|
979
|
-
def exp(power)
|
980
|
-
return Exp.new(to_equation(power))
|
981
|
-
end
|
982
|
-
|
983
|
-
# var(name) is the same as Variable.new(name), just shorter
|
984
|
-
def var(name, fixed_value=nil)
|
985
|
-
Variable.new name, fixed_value
|
986
|
-
end
|
987
|
-
|
988
|
-
# abs(equation) is the same as Abs.new(equation), just shorter
|
989
|
-
def abs eq
|
990
|
-
return Abs.new(to_equation(eq))
|
991
|
-
end
|
839
|
+
# Basic variables that are already implemented in SymCalc and have fixed values
|
840
|
+
module Constants
|
992
841
|
|
993
|
-
|
842
|
+
Pi = Constant.new "pi", Math::PI
|
843
|
+
E = Constant.new "e", Math::E
|
844
|
+
|
845
|
+
end
|
846
|
+
|
847
|
+
|
848
|
+
|
849
|
+
|
850
|
+
# sin(equation) is the same as Sin.new(equation), just shorter
|
851
|
+
def sin(eq)
|
852
|
+
return Sin.new(SymCalc.to_equation(eq))
|
853
|
+
end
|
854
|
+
|
855
|
+
# cos(equation) is the same as Cos.new(equation), just shorter
|
856
|
+
def cos(eq)
|
857
|
+
return Cos.new(SymCalc.to_equation(eq))
|
858
|
+
end
|
859
|
+
|
860
|
+
# ln(equation) is the same as Ln.new(equation), just shorter
|
861
|
+
def ln(eq)
|
862
|
+
return Ln.new(SymCalc.to_equation(eq))
|
863
|
+
end
|
864
|
+
|
865
|
+
# log(base, equation) is the same as Log.new(base, equation), just shorter
|
866
|
+
def log(base, eq)
|
867
|
+
return Log.new(SymCalc.to_equation(base), SymCalc.to_equation(eq))
|
868
|
+
end
|
869
|
+
|
870
|
+
# exp(equation) is the same as Exp.new(equation), just shorter
|
871
|
+
def exp(power)
|
872
|
+
return Exp.new(SymCalc.to_equation(power))
|
873
|
+
end
|
874
|
+
|
875
|
+
# var(name) is the same as Variable.new(name), just shorter
|
876
|
+
def var(name)
|
877
|
+
Variable.new name
|
878
|
+
end
|
879
|
+
|
880
|
+
def const(name, value)
|
881
|
+
Constant.new name, value
|
882
|
+
end
|
883
|
+
|
884
|
+
# abs(equation) is the same as Abs.new(equation), just shorter
|
885
|
+
def abs eq
|
886
|
+
return Abs.new(SymCalc.to_equation(eq))
|
887
|
+
end
|
888
|
+
|
889
|
+
module_function :sin, :cos, :ln, :log, :exp, :var, :abs, :const, :to_equation
|
994
890
|
|
995
891
|
end
|
metadata
CHANGED
@@ -1,28 +1,34 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symcalc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyryl Shyshko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: SymCalc
|
14
|
-
|
13
|
+
description: 'SymCalc adds symbolic mathematics and calculus to your code. Create,
|
14
|
+
evaluate and differentiate mathematical functions with a single method call.
|
15
|
+
|
16
|
+
'
|
15
17
|
email: kyryloshy@gmail.com
|
16
18
|
executables: []
|
17
19
|
extensions: []
|
18
20
|
extra_rdoc_files: []
|
19
21
|
files:
|
20
|
-
- lib/LICENSE.txt
|
21
22
|
- lib/symcalc.rb
|
22
|
-
homepage: https://
|
23
|
+
homepage: https://symcalc.site/ruby
|
23
24
|
licenses:
|
24
25
|
- Apache-2.0
|
25
|
-
metadata:
|
26
|
+
metadata:
|
27
|
+
changelog_uri: https://symcalc.site/ruby/changelog
|
28
|
+
documentation_uri: https://symcalc.site/ruby/docs
|
29
|
+
homepage_uri: https://symcalc.site/ruby
|
30
|
+
source_code_uri: https://github.com/symcalc/symcalc-ruby
|
31
|
+
bug_tracker_uri: https://github.com/symcalc/symcalc-ruby/issues
|
26
32
|
post_install_message:
|
27
33
|
rdoc_options: []
|
28
34
|
require_paths:
|
@@ -31,15 +37,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
31
37
|
requirements:
|
32
38
|
- - ">="
|
33
39
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
40
|
+
version: 3.0.0
|
35
41
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
42
|
requirements:
|
37
43
|
- - ">="
|
38
44
|
- !ruby/object:Gem::Version
|
39
45
|
version: '0'
|
40
46
|
requirements: []
|
41
|
-
rubygems_version: 3.
|
47
|
+
rubygems_version: 3.5.10
|
42
48
|
signing_key:
|
43
49
|
specification_version: 4
|
44
|
-
summary:
|
50
|
+
summary: Symbolic mathematics and calculus in Ruby
|
45
51
|
test_files: []
|
data/lib/LICENSE.txt
DELETED
@@ -1,202 +0,0 @@
|
|
1
|
-
|
2
|
-
Apache License
|
3
|
-
Version 2.0, January 2004
|
4
|
-
http://www.apache.org/licenses/
|
5
|
-
|
6
|
-
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
7
|
-
|
8
|
-
1. Definitions.
|
9
|
-
|
10
|
-
"License" shall mean the terms and conditions for use, reproduction,
|
11
|
-
and distribution as defined by Sections 1 through 9 of this document.
|
12
|
-
|
13
|
-
"Licensor" shall mean the copyright owner or entity authorized by
|
14
|
-
the copyright owner that is granting the License.
|
15
|
-
|
16
|
-
"Legal Entity" shall mean the union of the acting entity and all
|
17
|
-
other entities that control, are controlled by, or are under common
|
18
|
-
control with that entity. For the purposes of this definition,
|
19
|
-
"control" means (i) the power, direct or indirect, to cause the
|
20
|
-
direction or management of such entity, whether by contract or
|
21
|
-
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
22
|
-
outstanding shares, or (iii) beneficial ownership of such entity.
|
23
|
-
|
24
|
-
"You" (or "Your") shall mean an individual or Legal Entity
|
25
|
-
exercising permissions granted by this License.
|
26
|
-
|
27
|
-
"Source" form shall mean the preferred form for making modifications,
|
28
|
-
including but not limited to software source code, documentation
|
29
|
-
source, and configuration files.
|
30
|
-
|
31
|
-
"Object" form shall mean any form resulting from mechanical
|
32
|
-
transformation or translation of a Source form, including but
|
33
|
-
not limited to compiled object code, generated documentation,
|
34
|
-
and conversions to other media types.
|
35
|
-
|
36
|
-
"Work" shall mean the work of authorship, whether in Source or
|
37
|
-
Object form, made available under the License, as indicated by a
|
38
|
-
copyright notice that is included in or attached to the work
|
39
|
-
(an example is provided in the Appendix below).
|
40
|
-
|
41
|
-
"Derivative Works" shall mean any work, whether in Source or Object
|
42
|
-
form, that is based on (or derived from) the Work and for which the
|
43
|
-
editorial revisions, annotations, elaborations, or other modifications
|
44
|
-
represent, as a whole, an original work of authorship. For the purposes
|
45
|
-
of this License, Derivative Works shall not include works that remain
|
46
|
-
separable from, or merely link (or bind by name) to the interfaces of,
|
47
|
-
the Work and Derivative Works thereof.
|
48
|
-
|
49
|
-
"Contribution" shall mean any work of authorship, including
|
50
|
-
the original version of the Work and any modifications or additions
|
51
|
-
to that Work or Derivative Works thereof, that is intentionally
|
52
|
-
submitted to Licensor for inclusion in the Work by the copyright owner
|
53
|
-
or by an individual or Legal Entity authorized to submit on behalf of
|
54
|
-
the copyright owner. For the purposes of this definition, "submitted"
|
55
|
-
means any form of electronic, verbal, or written communication sent
|
56
|
-
to the Licensor or its representatives, including but not limited to
|
57
|
-
communication on electronic mailing lists, source code control systems,
|
58
|
-
and issue tracking systems that are managed by, or on behalf of, the
|
59
|
-
Licensor for the purpose of discussing and improving the Work, but
|
60
|
-
excluding communication that is conspicuously marked or otherwise
|
61
|
-
designated in writing by the copyright owner as "Not a Contribution."
|
62
|
-
|
63
|
-
"Contributor" shall mean Licensor and any individual or Legal Entity
|
64
|
-
on behalf of whom a Contribution has been received by Licensor and
|
65
|
-
subsequently incorporated within the Work.
|
66
|
-
|
67
|
-
2. Grant of Copyright License. Subject to the terms and conditions of
|
68
|
-
this License, each Contributor hereby grants to You a perpetual,
|
69
|
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
70
|
-
copyright license to reproduce, prepare Derivative Works of,
|
71
|
-
publicly display, publicly perform, sublicense, and distribute the
|
72
|
-
Work and such Derivative Works in Source or Object form.
|
73
|
-
|
74
|
-
3. Grant of Patent License. Subject to the terms and conditions of
|
75
|
-
this License, each Contributor hereby grants to You a perpetual,
|
76
|
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
77
|
-
(except as stated in this section) patent license to make, have made,
|
78
|
-
use, offer to sell, sell, import, and otherwise transfer the Work,
|
79
|
-
where such license applies only to those patent claims licensable
|
80
|
-
by such Contributor that are necessarily infringed by their
|
81
|
-
Contribution(s) alone or by combination of their Contribution(s)
|
82
|
-
with the Work to which such Contribution(s) was submitted. If You
|
83
|
-
institute patent litigation against any entity (including a
|
84
|
-
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
85
|
-
or a Contribution incorporated within the Work constitutes direct
|
86
|
-
or contributory patent infringement, then any patent licenses
|
87
|
-
granted to You under this License for that Work shall terminate
|
88
|
-
as of the date such litigation is filed.
|
89
|
-
|
90
|
-
4. Redistribution. You may reproduce and distribute copies of the
|
91
|
-
Work or Derivative Works thereof in any medium, with or without
|
92
|
-
modifications, and in Source or Object form, provided that You
|
93
|
-
meet the following conditions:
|
94
|
-
|
95
|
-
(a) You must give any other recipients of the Work or
|
96
|
-
Derivative Works a copy of this License; and
|
97
|
-
|
98
|
-
(b) You must cause any modified files to carry prominent notices
|
99
|
-
stating that You changed the files; and
|
100
|
-
|
101
|
-
(c) You must retain, in the Source form of any Derivative Works
|
102
|
-
that You distribute, all copyright, patent, trademark, and
|
103
|
-
attribution notices from the Source form of the Work,
|
104
|
-
excluding those notices that do not pertain to any part of
|
105
|
-
the Derivative Works; and
|
106
|
-
|
107
|
-
(d) If the Work includes a "NOTICE" text file as part of its
|
108
|
-
distribution, then any Derivative Works that You distribute must
|
109
|
-
include a readable copy of the attribution notices contained
|
110
|
-
within such NOTICE file, excluding those notices that do not
|
111
|
-
pertain to any part of the Derivative Works, in at least one
|
112
|
-
of the following places: within a NOTICE text file distributed
|
113
|
-
as part of the Derivative Works; within the Source form or
|
114
|
-
documentation, if provided along with the Derivative Works; or,
|
115
|
-
within a display generated by the Derivative Works, if and
|
116
|
-
wherever such third-party notices normally appear. The contents
|
117
|
-
of the NOTICE file are for informational purposes only and
|
118
|
-
do not modify the License. You may add Your own attribution
|
119
|
-
notices within Derivative Works that You distribute, alongside
|
120
|
-
or as an addendum to the NOTICE text from the Work, provided
|
121
|
-
that such additional attribution notices cannot be construed
|
122
|
-
as modifying the License.
|
123
|
-
|
124
|
-
You may add Your own copyright statement to Your modifications and
|
125
|
-
may provide additional or different license terms and conditions
|
126
|
-
for use, reproduction, or distribution of Your modifications, or
|
127
|
-
for any such Derivative Works as a whole, provided Your use,
|
128
|
-
reproduction, and distribution of the Work otherwise complies with
|
129
|
-
the conditions stated in this License.
|
130
|
-
|
131
|
-
5. Submission of Contributions. Unless You explicitly state otherwise,
|
132
|
-
any Contribution intentionally submitted for inclusion in the Work
|
133
|
-
by You to the Licensor shall be under the terms and conditions of
|
134
|
-
this License, without any additional terms or conditions.
|
135
|
-
Notwithstanding the above, nothing herein shall supersede or modify
|
136
|
-
the terms of any separate license agreement you may have executed
|
137
|
-
with Licensor regarding such Contributions.
|
138
|
-
|
139
|
-
6. Trademarks. This License does not grant permission to use the trade
|
140
|
-
names, trademarks, service marks, or product names of the Licensor,
|
141
|
-
except as required for reasonable and customary use in describing the
|
142
|
-
origin of the Work and reproducing the content of the NOTICE file.
|
143
|
-
|
144
|
-
7. Disclaimer of Warranty. Unless required by applicable law or
|
145
|
-
agreed to in writing, Licensor provides the Work (and each
|
146
|
-
Contributor provides its Contributions) on an "AS IS" BASIS,
|
147
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
148
|
-
implied, including, without limitation, any warranties or conditions
|
149
|
-
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
150
|
-
PARTICULAR PURPOSE. You are solely responsible for determining the
|
151
|
-
appropriateness of using or redistributing the Work and assume any
|
152
|
-
risks associated with Your exercise of permissions under this License.
|
153
|
-
|
154
|
-
8. Limitation of Liability. In no event and under no legal theory,
|
155
|
-
whether in tort (including negligence), contract, or otherwise,
|
156
|
-
unless required by applicable law (such as deliberate and grossly
|
157
|
-
negligent acts) or agreed to in writing, shall any Contributor be
|
158
|
-
liable to You for damages, including any direct, indirect, special,
|
159
|
-
incidental, or consequential damages of any character arising as a
|
160
|
-
result of this License or out of the use or inability to use the
|
161
|
-
Work (including but not limited to damages for loss of goodwill,
|
162
|
-
work stoppage, computer failure or malfunction, or any and all
|
163
|
-
other commercial damages or losses), even if such Contributor
|
164
|
-
has been advised of the possibility of such damages.
|
165
|
-
|
166
|
-
9. Accepting Warranty or Additional Liability. While redistributing
|
167
|
-
the Work or Derivative Works thereof, You may choose to offer,
|
168
|
-
and charge a fee for, acceptance of support, warranty, indemnity,
|
169
|
-
or other liability obligations and/or rights consistent with this
|
170
|
-
License. However, in accepting such obligations, You may act only
|
171
|
-
on Your own behalf and on Your sole responsibility, not on behalf
|
172
|
-
of any other Contributor, and only if You agree to indemnify,
|
173
|
-
defend, and hold each Contributor harmless for any liability
|
174
|
-
incurred by, or claims asserted against, such Contributor by reason
|
175
|
-
of your accepting any such warranty or additional liability.
|
176
|
-
|
177
|
-
END OF TERMS AND CONDITIONS
|
178
|
-
|
179
|
-
APPENDIX: How to apply the Apache License to your work.
|
180
|
-
|
181
|
-
To apply the Apache License to your work, attach the following
|
182
|
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
183
|
-
replaced with your own identifying information. (Don't include
|
184
|
-
the brackets!) The text should be enclosed in the appropriate
|
185
|
-
comment syntax for the file format. We also recommend that a
|
186
|
-
file or class name and description of purpose be included on the
|
187
|
-
same "printed page" as the copyright notice for easier
|
188
|
-
identification within third-party archives.
|
189
|
-
|
190
|
-
Copyright [yyyy] [name of copyright owner]
|
191
|
-
|
192
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
193
|
-
you may not use this file except in compliance with the License.
|
194
|
-
You may obtain a copy of the License at
|
195
|
-
|
196
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
197
|
-
|
198
|
-
Unless required by applicable law or agreed to in writing, software
|
199
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
200
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
201
|
-
See the License for the specific language governing permissions and
|
202
|
-
limitations under the License.
|