Skip to content

Commit

Permalink
Improve Rust ergonomics
Browse files Browse the repository at this point in the history
- Introduce symb! macro for easy symbol definitions
- Overload arithmetical operators for symbols and atoms
- fun! macro now accepts many more types that can be converted to an atom
- Increase expansion depth if 1/0 is encountered during series expansion
  • Loading branch information
benruijl committed Sep 24, 2024
1 parent 74b1d29 commit 22c50b9
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 89 deletions.
19 changes: 9 additions & 10 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ Variables ending with a `_` are wildcards that match to any subexpression.
In the following example we try to match the pattern `f(w1_,w2_)`:

```python
from symbolica import Expression
x, y, w1_, w2_, f = Expression.symbols('x','y','w1_','w2_', 'f')
from symbolica import *
x, y, w1_, w2_, f = S('x','y','w1_','w2_', 'f')
e = f(3,x)*y**2+5
r = e.replace_all(f(w1_,w2_), f(w1_ - 1, w2_**2))
print(r)
Expand All @@ -88,9 +88,9 @@ which yields `y^2*f(2,x^2)+5`.
Solve a linear system in `x` and `y` with a parameter `c`:

```python
from symbolica import Expression
from symbolica import *

x, y, c, f = Expression.symbols('x', 'y', 'c', 'f')
x, y, c, f = S('x', 'y', 'c', 'f')

x_r, y_r = Expression.solve_linear_system(
[f(c)*x + y + c, y + c**2], [x, y])
Expand All @@ -103,20 +103,19 @@ which yields `x = (-c+c^2)*f(c)^-1` and `y = -c^2`.
Perform a series expansion in `x`:

```python
from symbolica import Expression
x = Expression.symbol('x')
e = Expression.parse('exp(5+x)/(1-x)').series(x, 0, 3)
from symbolica import *
e = E('exp(5+x)/(1-x)').series(S('x'), 0, 3)

print(e)
```
which yields `(exp(5))+(2*exp(5))*x+(5/2*exp(5))*x^2+(8/3*exp(5))*x^3+O(x^4)`.
which yields `(exp(5))+(2*exp(5))*x+(5/2*exp(5))*x^2+(8/3*exp(5))*x^3+𝒪(x^4)`.

### Rational arithmetic

Symbolica is world-class in rational arithmetic, outperforming Mathematica, Maple, Form, Fermat, and other computer algebra packages. Simply convert an expression to a rational polynomial:
```python
from symbolica import Expression
p = Expression.parse('(x*y^2*5+5)^2/(2*x+5)+(x+4)/(6*x^2+1)').to_rational_polynomial()
from symbolica import *
p = E('(x*y^2*5+5)^2/(2*x+5)+(x+4)/(6*x^2+1)').to_rational_polynomial()
print(p)
```
which yields `(45+13*x+50*x*y^2+152*x^2+25*x^2*y^4+300*x^3*y^2+150*x^4*y^4)/(5+2*x+30*x^2+12*x^3)`.
Expand Down
10 changes: 4 additions & 6 deletions examples/builder.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use symbolica::{atom::Atom, fun, state::State};
use symbolica::{fun, symb};

fn main() {
let x = Atom::parse("x").unwrap();
let y = Atom::parse("y").unwrap();
let f_id = State::get_symbol("f");
let (x, y, f) = symb!("x", "y", "f");

let f = fun!(f_id, x, y, Atom::new_num(2));
let f = fun!(f, x, y, 2);

let xb = (-(&y + &x + 2) * &y * 6).npow(5) / &y * &f / 4;
let xb = (-(y + x + 2) * y * 6).npow(5) / y * f / 4;

println!("{}", xb);
}
Loading

0 comments on commit 22c50b9

Please sign in to comment.