I'm working with Julia
's Symbolics.jl
and I'm trying to compare two symbolic matrices.
However, since Symbolics.isequal
function checks for structural- instead of mathematical-equivalence it is necessary that every entry of the matrix is in its expanded form. Otherwise isequal will always return false.
To ensure this I made the function tidyMatrix!(M)
, here's a minimal (non-working) example:
using Symbolics
# Function to expand every symbolic entry in matrix M
function tidyMatrix!(M)
for i in size(M, 1), j in size(M, 2)
M[i,j] = expand(M[i,j])
end
end
@variables x
M1 = [2(exp(x) + 1) 0; 0 0]
M2 = [2*exp(x)+2 0; 0 0]
tidyMatrix!(M1)
tidyMatrix!(M2)
println("Symbolic isequal: ", Symbolics.isequal(M1, M2)) # Always returns false
But tidyfunction!
never manages to expand the entries in M1
.
Which is especially weird since the expand function is working as expected on single entries, like here:
using Symbolics
# Function to expand every symbolic entry in matrix M
function tidyMatrix!(M)
for i in size(M, 1), j in size(M, 2)
M[i,j] = expand(M[i,j])
end
end
@variables x
M1 = [2(exp(x) + 1)] # only use one entry
M2 = [2*exp(x)+2]
tidyMatrix!(M1)
tidyMatrix!(M2)
println("Symbolic isequal: ", Symbolics.isequal(M1, M2)) # Now it works
I know I could just check for numerical equality, but after I've sunken hours into indentifying this bug I just need to know why the expand
function breaks assoon as I use it elementwise in a matrix.
Appendix:
If you swap the expand
function for similar functions like simplify
, simplify(..., expand=true)
it still doesn't make tidyfunction
work.
Your ranges are written incorrectly. You want for i in 1:size(M, 1), j in 1:size(M, 2)
. When iterating over a scalar (which is what size
returns), it's treated as a 0-dimensional array containing just itself. So you only expanded the bottom right entry of the array (which is why it worked in the one-element case).
Actually if you really want to be correct, you shouldn't use the range 1:n
but rather let the array tell you its own indices (in case you use something like an OffsetArray
):
function tidyMatrix!(M)
for i in eachindex(M)
M[i] = expand(M[i])
end
end