I don’t know why this rule isn’t part of the standard set (probably because of some floating point shenanigans with complex numbers), but if you truly desire to simplify like that, here’s how to do that. You just have to add that rewriting rule and make it available to simplify:
julia> using Symbolics, SymbolicUtils
julia> r = @rule sqrt(~x)^2 => ~x
sqrt(~x) ^ 2 => ~x
julia> sqrt_2 = Symbolics.Term(sqrt, 2)
sqrt(2)
julia> simplify(sqrt_2^2, RuleSet([r]))
2
# also works with other numbers here, though again,
# in real applications beware of floating point shenanigans
julia> sqrt_2 = Symbolics.Term(sqrt, 1325)
sqrt(1325)
julia> simplify(sqrt_2^2, RuleSet([r]))
1325
I encourage you to check out the excellent documentation of SymbolicUtils and how those rules work (and how you can define your own!).
Another option would be checking out Metatheory.jl (check out a talk introducing it from this years JuliaCon here), which is basically very fast term rewriting/simplification (also has support for Symbolics.jl). Not 100% sure whether they have that rewriting rule defined by default though.
First, let me thank everyone which posted on this thread. Just for the record, here is a slightly more complex example (I agree it is quite trivial in this present form, but it might apply to more complex situations)
julia> using Symbolic
SymbolicUtils Symbolics
julia> using SymbolicUtils, Symbolics
julia> r = @rule sqrt((~x)^2) => abs(~x)
sqrt((~x) ^ 2) => abs(~x)
julia> @variables x
1-element Vector{Num}:
x
julia> sqr_minus_2 = substitute(x^2, Dict(x=>-2), fold=false)
(-2)^2
julia> simplify(sqrt(sqr_minus_2), RuleSet([r]))
2
I’m not an expert in terms of Symbolics.jl or CAS, but from my understanding, substitute should always be the last step, no? I.e. first simplify the expression given as far as possible, under all known Rules/legal transforms, substitute a variable and continue with evaluation.
As far as I understand from your questions, you basically want to avoid seeing “ugly” results/results containing literal floating point values?
You’re right. substitute is, as far as I understand, a “trick” to define sqrt(2) (or in the present case, (-2)^2) as an unevaluated symbol.
Note that we need to be able to define sqrt(2) as a symbol, because we use a matrix representation of second- and fourth- rank, tensors with minor symmetries which use the sqrt(2) weighting.
And we really need that sqrt(2)² should simplify as 2.
May not be exactly what you’re looking for, since I have a Matrix of symbolic variables that I simplify via broadcasting. Afterwards I can just substitute:
The last example collapses into direct values since under the given rules (+ default rules), the numerical value is equivalent to the uncomputed symbolic value. The full floating point value is still there by the way, it’s just not printed:
julia> ans[1,2] |> dump
Num
val: Float64 2.82842712474619
Again, I’m not a CAS expert, I’m just messing around with broadcasting and what I can find in the docs of Symbolics.jl
That rule alone won’t be enough to make the “ugly” powers go away and bring it into the form you think of, but then again I have to stress that I’m not an expert in CAS I may be missing something with writing rules though and matching those non-variable powers for some pattern and extracting something else from them may be possible, so me not knowing how to do this should not be taking as an indicator that Symbolics.jl can’t do it.
I intended for the y to be 2 so it should be an expression in \sqrt{2} rather than \sqrt{y}. In that case all even powers of \sqrt{2} reduce to rational. Something like \sqrt{y}^3 does not though because it would simplify as y\sqrt{y} and you’d be left with polynomials in y and some \sqrt{y} factors.
To correct the above the expression below should be writeable in the form a + b \sqrt{2}: