symath 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0d95fb0b1d0166de370188a2b9346d801dadfa9034b9d3c85b34fec82258a95
4
- data.tar.gz: e406bb63127befcdec892238a73f7c3597d41cfb7c6c2288b733a8dd61bc1756
3
+ metadata.gz: 9d903078ab94cf97187901574a014b88181b5e73abfa842a01903b62d7c9f22a
4
+ data.tar.gz: c2d0836540602c731aca5f7e1d105ff8bd368a0fac17e6cc0b4a5cd4803456f6
5
5
  SHA512:
6
- metadata.gz: a1989761481d6fbce08bb4bbb8858a5c5562fe2ab80521360b0138a6e615c0ed7b18e097df64b44ce70ba759fb33b613f71ce1dd5772eb8c8a690c511f9930f6
7
- data.tar.gz: 49b0de8326240da0aec67671fbaf457e335a13555675ca2517359e59e275ff1961ce4882f1676322677a5e26a75943b553b5c5b6ad9b095a8da400d2e15cb10e
6
+ metadata.gz: 18c3b80cb561ecaf389816d59f6f897373608dcc4226c6457339e36dca18bc32ea1448a0ec27d4788a221f1cfcdbcbd863b8f44c9396b2b5daa3b0a2ef3f6821
7
+ data.tar.gz: 3103890a22c71dcc232763990e1619d333323d789c03c7d95215144fd4a0733fb541594d0f8e51884c258a4cb2fe45ef798498651a79cd789e7218a85a387071
data/README.md CHANGED
@@ -304,8 +304,15 @@ The partial derivative is available as well as 'syntactic sugar':
304
304
 
305
305
  ### Integration
306
306
 
307
- Integration is available as the int-operator. With one argument, the
308
- operator evaluates to the antiderivative of the expression:
307
+ Integration is available as the int-operator. The algorithm is only a
308
+ very simple one, imitating the most basic techniques of finding the
309
+ anti-derivative, combined with a few well known equation patterns. The
310
+ operation also has a limitation when it comes to non-commutable
311
+ terms (matrices, quaternions, etc.). In that case, the result is not
312
+ reliable.
313
+
314
+ With one argument, the operator evaluates to the antiderivative of the
315
+ expression:
309
316
 
310
317
  <pre>
311
318
  > int(2**:x).evaluate
@@ -527,6 +534,21 @@ that it matches the original expression:
527
534
  {a=>y**2 + 3, b=>x**2}]
528
535
  </pre>
529
536
 
537
+ #### Match/replace operation
538
+
539
+ The match_replace method tries to find an occurence of a pattern in
540
+ the expression, and replaces it if it is found. The method can be used
541
+ together with the iterate method. The latter repeats a method until
542
+ there are no more changes:
543
+
544
+ <pre>
545
+ > a = sin(sin(sin(:a + :b) - sin(:f)))
546
+ > a.match_replace(sin(:x), :e*:x, [:x])
547
+ => e*sin(sin(a + b) - sin(f))
548
+ > a.iterate('match_replace', sin(:x), :e*:x, [:x])
549
+ => e*e*(e*(a + b) - e*f)
550
+ </pre>
551
+
530
552
  #### Factorization and product expansion
531
553
 
532
554
  The factorization method has been ripped from the python
@@ -102,6 +102,9 @@ module SyMath::Operation::Match
102
102
  # match is found, nil is returned. An optional boundvars hash contains a
103
103
  # map of variables to expressions which are required to match exactly.
104
104
  def match(exp, freevars, boundvars = {})
105
+ # Mathify free variables
106
+ freevars = freevars.map { |v| v.to_m }
107
+
105
108
  # Traverse self and exp in parallel. Match subexpressions recursively,
106
109
  # and match end nodes one by one. The two value nodes are compared for
107
110
  # equality and each argument are matched recursively.
@@ -163,4 +166,38 @@ module SyMath::Operation::Match
163
166
  raise 'Don\'t know how to compare value type ' + exp.class.to_s
164
167
  # :nocov:
165
168
  end
169
+
170
+ def match_replace(exp, replace, freevars)
171
+ # Recursively try to match exp to subexpressions of self. If a match
172
+ # is found, replace it and return.
173
+
174
+ # First try to match the top expression
175
+ matches = match(exp, freevars)
176
+ if !matches.nil? and matches.length >= 1
177
+ # If there are more than one match, pick the first
178
+ ret = replace.deep_clone
179
+ ret.replace(matches[0])
180
+ return ret
181
+ end
182
+
183
+ # No match at top level. Try to match sub expressions.
184
+ if is_a?(SyMath::Operator)
185
+ gotmatch = false
186
+
187
+ args2 = @args
188
+
189
+ args2.each_with_index do |a, i|
190
+ matched = a.match_replace(exp, replace, freevars)
191
+ if matched != a
192
+ args[i] = matched
193
+ ret = deep_clone
194
+ ret.args[i] = matched
195
+ return ret
196
+ end
197
+ end
198
+ end
199
+
200
+ # No match.
201
+ return self
202
+ end
166
203
  end
@@ -1,11 +1,11 @@
1
1
  module SyMath::Operation
2
2
  # Repeat method until there are no changes
3
- def iterate(method)
4
- ret = deep_clone.send(method)
3
+ def iterate(method, *args)
4
+ ret = deep_clone.send(method, *args)
5
5
  if ret == self
6
6
  return ret
7
7
  else
8
- return ret.iterate(method)
8
+ return ret.iterate(method, *args)
9
9
  end
10
10
  end
11
11
 
@@ -1,3 +1,3 @@
1
1
  module SyMath
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/symath.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.metadata["allowed_push_host"] = 'https://rubygems.org'
19
19
 
20
20
  spec.metadata["source_code_uri"] = "https://github.com/erikoest/symath"
21
+ spec.metadata["documentation_uri"] = "https://github.com/erikoest/symath/blob/main/README.md"
21
22
  # spec.metadata["changelog_uri"] = ""
22
23
  else
23
24
  raise "RubyGems 2.0 or newer is required to protect against " \
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - erikoest
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-19 00:00:00.000000000 Z
11
+ date: 2022-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,6 +138,7 @@ licenses:
138
138
  metadata:
139
139
  allowed_push_host: https://rubygems.org
140
140
  source_code_uri: https://github.com/erikoest/symath
141
+ documentation_uri: https://github.com/erikoest/symath/blob/main/README.md
141
142
  post_install_message:
142
143
  rdoc_options: []
143
144
  require_paths: