# Symbolic rewriting, expanding and collecting

**URL:** <https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503>\
**Category:** Specific Domains\
**Tags:** question, package, symbolic\
**Created:** [February 18, 2021, 2:13am UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503 "2021-02-18T02:13:25Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [February 18, 2021, 2:13am UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/1 "2021-02-18T02:13:25Z")

</div>

Hi!

I need to revise a lot of mundane analytical calculations which I guess could be automated. In its essence, I have three sets of symbols: operators E, X, C, S \in \rm{Op}, sigma matrices \eta\_x, \eta\_y, \eta\_z \in SU(2) and a set of constants a,c,s \in \rm{Re}. These symbols have the following rules:

- \eta\_x \eta\_y = i \eta\_z, \eta\_y \eta\_z = i \eta\_x, \eta\_z \eta\_x = i\eta\_y, \eta\_y \eta\_x =- i \eta\_z, \eta\_z \eta\_y = -i \eta\_x, \eta\_x \eta\_z = -i\eta\_y
- The symbols of Op do not commute with themselves
- Symbols from Re commute with themselves
- The symbols from different sets commute with each other

With these rules, I need to expand multiplications such as:

(E \eta\_z - a X \eta\_x) (C - \frac{i\eta\_y}{2}\ S)(c \eta\_x - s \eta\_y ) (C + \frac{i \eta\_y}{2} S) = i c \eta\_y E (C + \frac{i \eta\_y}{2} S) + i s \eta\_x E - a c X (C + \frac{i \eta\_y}{2} S) + i s \eta\_z X

which is a simple but rather lengthy calculation which is hard to make manageable. Are there any Julia package or any other CAS which could help me with such error-prone tasks?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 18, 2021, 2:17am UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/2 "2021-02-18T02:17:48Z")

</div>

SymbolicUtils.jl would be the way to go with this. Define a ruleset and it’ll apply it.

---

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [February 18, 2021, 11:01am UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/3 "2021-02-18T11:01:08Z")

</div>

`SymbolicUtils` looks cool. However, I cannot understand how to use it for expressions that are not with predefined types `Real`, `Complex` and `Int`. Is it possible to define nonnumber symbols or types?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 18, 2021, 12:54pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/4 "2021-02-18T12:54:49Z")

</div>

> [@Janis\_Erdmanis](#):
>
> `SymbolicUtils` looks cool. However, I cannot understand how to use it for expressions that are not with predefined types `Real` , `Complex` and `Int` . Is it possible to define nonnumber symbols or types?

It’s literally just a dispatching rule system, so you just create a different set of rules.

> <https://github.com/JuliaSymbolics/SymbolicUtils.jl/blob/master/src/simplify_rules.jl>

Nothing specifies `Number`.

---

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [February 18, 2021, 2:39pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/5 "2021-02-18T14:39:27Z")

</div>

It is quite hard to get into the meaning of these rules. I guess my biggest obstacle is what is the meaning of `~`? In the Github `README.md`, I see that the rules are defined with single `~`. In the code, I see `~~x` to be used most often.

I see it is also possible to define rules without `~` for rules applying to particular symbols. I guess it would be the right place do define rules for \eta\_{x,y,z}. However, I am puzzled why for instance if I define a rule

```julia
 r = @rule sinh(im * y) => sin(y)

```

and apply it to the example

```julia
simplify(cos(y)^2 + sinh(im*y)^2, RuleSet([r]))

```

I get `(cos(y))^2 + (sin(y))^2` instead of `1` if the rule would be defined with `~x`.

Also, what is the difference between `@acrule` and `@rule`?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 18, 2021, 2:51pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/6 "2021-02-18T14:51:06Z")

</div>

> [@Janis\_Erdmanis](#):
>
> Also, what is the difference between `@acrule` and `@rule` ?

Commutativity IIRC. It’s all explained in a bit of detail:

[https://juliasymbolics.github.io/SymbolicUtils.jl/api/#rewriters](https://juliasymbolics.github.io/SymbolicUtils.jl/api/#rewriters)

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 18, 2021, 2:51pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/7 "2021-02-18T14:51:47Z")

</div>

Open an issue for any documentation you feel is missing so @shashi will see it.

---

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [February 18, 2021, 11:26pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/8 "2021-02-18T23:26:30Z")

</div>

Looking into the library and trying to implement Pauli matrix algebra, I realised that rule before applied seems to sort its arguments under multiplications. For instance, I can not get a rule to apply on the following code:

```julia
abstract type SU2 end
@syms ηx::SU2 ηy::SU2 ηz::SU2
(@rule ηy*ηx => -im*ηz)(ηy*ηx)==nothing

```

which returns nothing. Instead, it applies the wrong rule:

```julia
(@rule ηx*ηy => im*ηz)(ηy*ηx)

```

Ahh, in fact, it sorts all multiplications. Is there any way to create noncommuting symbols under multiplication?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 18, 2021, 11:50pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/9 "2021-02-18T23:50:43Z")

</div>

open an issue.

---

<div class="post-metadata">

**Author:** ![shashi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shashi/32/1824_2.png) [@shashi](https://discourse.julialang.org/u/shashi)\
**Post date:** [February 19, 2021, 2:21pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/10 "2021-02-19T14:21:20Z")

</div>

Replied with the solution here [Symbols gets sorted even for user types · Issue #206 · JuliaSymbolics/SymbolicUtils.jl · GitHub](https://github.com/JuliaSymbolics/SymbolicUtils.jl/issues/206#issuecomment-782014746)

---

<div class="post-metadata">

**Author:** ![Janis\_Erdmanis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/janis_erdmanis/32/10869_2.png) [@Janis\_Erdmanis](https://discourse.julialang.org/u/Janis_Erdmanis)\
**Post date:** [February 19, 2021, 8:05pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/11 "2021-02-19T20:05:43Z")

</div>

So I tried to work around the issue by defining a \times method for noncommutative terms. For a moment, I try to implement only Pauli operator algebra and forget at the moment about the set of operators \rm{Op}. I can get substitution rules to work in some situation, whereas in others, it does fail. I came up with the following code to define simplification rules for operators \eta\_{x,y,z}:

```julia
using SymbolicUtils
using SymbolicUtils: Sym, Mul, Term, Symbolic, Add

abstract type SU2 end

@syms ηx::SU2 ηy::SU2 ηz::SU2 α::Real β::Real γ::Real

×(x::Symbolic, y::Symbolic) = Term(*, [x, y])

function ×(x::Symbolic, y::Term) 
	if y.f==*
		Term(*, [x, y.arguments...])
	else
		Term(*, [x, y])
	end
end

function ×(x::Term, y::Symbolic) 
	if x.f==*
		Term(*, [x.arguments..., y])
	else
		Term(*, [x, y])
	end
end

×(x::Add, y::Symbolic) = Term(*, [x, y])

srules = [
    @rule ηx*ηy => im*ηz
    @rule ηy*ηz => im*ηx
    @rule ηz*ηx => im*ηy
    @rule ηy*ηx => -im*ηz
    @rule ηz*ηy => -im*ηx
    @rule ηx*ηz => -im*ηy
	
	@rule ηx^2 => 1
    @rule ηy^2 => 1
    @rule ηz^2 => 1
	
    @rule ηx*ηy*~x => im*ηz*~x
    @rule ηy*ηz*~x => im*ηx*~x
    @rule ηz*ηx*~x => im*ηy*~x
    @rule ηy*ηx*~x => -im*ηz*~x
    @rule ηz*ηy*~x => -im*ηx*~x
    @rule ηx*ηz*~x => -im*ηy*~x
    
    @rule ~x*ηx*ηy => ~x*im*ηz
    @rule ~x*ηy*ηz => ~x*im*ηx
    @rule ~x*ηz*ηx => ~x*im*ηy
    @rule ~x*ηy*ηx => ~x * (-im)*ηz
    @rule ~x*ηz*ηy => ~x * -im*ηx
    @rule ~x*ηx*ηz => ~x * -im*ηy
	
	@rule (~x + ~y)*~z => ~x*~z + ~y*~z
	@rule ~z*(~x + ~y) => ~z*~x + ~z*~y
    
]

```

Note I repeated the rules with `~x` as otherwise these rules were not substituted.

Here are some tests I used to evaluate the rules:

```julia
simplify(ηx×ηy×ηz + ηz×ηx, RuleSet(srules)) # Success

```

```julia
simplify(ηx×ηy×ηz×ηy, RuleSet(srules)) # Failure

```

```julia
simplify((ηz×ηy + ηz)×ηz, RuleSet(srules)) # Success/Failure

```

```julia
simplify(α×ηx×ηy×ηz + β×ηz×ηx, RuleSet(srules)) # Works only for the second term

```

```julia
simplify(ηx×ηy×ηz×α + ηz×ηx×β, RuleSet(srules)) # Works only for the second term

```

```julia
simplify((α×ηx + β×ηz×ηx)×(γ×ηy + ηz), RuleSet(srules)) # Failure

```

---

<div class="post-metadata">

**Author:** ![shashi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shashi/32/1824_2.png) [@shashi](https://discourse.julialang.org/u/shashi)\
**Post date:** [February 27, 2021, 5:47pm UTC](https://discourse.julialang.org/t/symbolic-rewriting-expanding-and-collecting/55503/12 "2021-02-27T17:47:42Z")

</div>

- There is a missing x(::Term, ::Term) method which may create ambiguity.
- `*(x::Symbolic{SU2}, y::Symbolic{SU2}) = Term(*, [x, y])` might be necessary because you are using `*` in the RHS of your rules. You may consider this or use `×` even in the rules.
