# Can Symbolics.jl simplify subexpressions?

I have been trying out Symbolics.jl for a few projects recently. Initially I was excited but have run into a few issues that are road blocks. Some are probably asking too much this early in development - `(A::SparseMatrixCSC{Num, Int64})^(1/2)` doesn’t work (I get the" non-boolean (Num) used in a boolean context" error referenced in the docs) - but more surprising to me is I couldn’t get `simplify` to work below the first level of an expression. I’m coming from Mathematica for symbolic math, and this was really disappointing (and I am hoping user error). As an MWE,

``````using Symbolics

@variables y
t1 = sqrt(y^2)
t2 = abs(sqrt(y^2))
sqrtrule = @rule sqrt((~x)^2) => ~x

s1 = simplify(t1, sqrtrule)
s2 = simplify(t2, sqrtrule)
``````

In this example, (a common simplification for a real positive variable) I get ` s1=y`, but `s2=abs(sqrt(y^2))`.
Symbolics is (rightfully) giving me some gigantic expressions during my computations, and this is one example of the kind of pattern embedded in the result that I would like to simplify before generating a function… how can I do this?

Thanks.

Square root of a sparse matrix is hard to do numerically. Did you mean `.^`?

You need to add a `Postwalk` to that I think?

Did you run `simplify` or were you using your own rule set?

Thanks for the reply. Point by point…

1. Nope, I meant the square root of the matrix. I guessed that would be hard / unsupported, and can probably cut of the symbolic part before that (and do it numerically later).
2. I also tried making the rule a post walk, but maybe I didn’t do it right? Doing
``````simplify(t2, SymbolicUtils.Postwalk(sqrtrule))
``````

also does nothing.
3. I tried plain simplify first, but it didn’t do anything to my expression. Coming from Mathematica for symbolics (Julia for numerics for a while now), I had hoped to specify some assumptions about variable domains, but that doesn’t appear to be supported yet. Baring that I tried passing my own simplification for this simple case, but even that didn’t do anything (and hence my post).

Thoughts?

I think you need the matrix log to define that. Yeah, I don’t think you’ll get a good general symbolic solution there?

Yeah, open an issue. This is a question for @shashi

Variable domains are not implemented yet, though we’re getting there: Added the ability to pass known SymPy symbols to symbolics_to_sympy function by owiecc · Pull Request #351 · JuliaSy

Ok, thanks for the reply. I opened an issue at Symbolics.jl (maybe it should be at SymbolicUtils?).

1 Like

That’s good, thanks.

For anyone that comes across this, I thought I would share the answer I got from shashi to the issue. In short, if you want a rewrite rule that operates below the top level of an expression it does need to be a Prewalk/Postwalk, BUT those require a rewriter with passthrough behavior (by default rewriters return `nothing` if there is no change). If combining multiple rules, `Chain` has this behavior, and for just one rule you can wrap it in `PassThrough`. So, for the example above,

``````simplify(t2, Rewriters.Prewalk(Rewriters.PassThrough(sqrtrule)))
``````

gives the desired behavior.

2 Likes