# Some straightforward square root fractions are not simplified

I'm a Sage beginner who's trying to apply it to a set of equations I'm working on. In that process, I came across an issue where SageMath 9.4 is not simplifying some very straightforward square root fractions in my expressions. Let me show you a minimal example:

x = var('x')
sqrt(1-x)/(1-x)


$$-\frac{\sqrt{-x + 1}}{x - 1}$$

What I was expecting to get, of course, is $1 / \sqrt{1 - x}$. Calling simplify() or full_simplify() on the expression doesn't make a difference; I still get the same thing out. I experimented with other square root fractions as well to see if this issue recurs:

sqrt(x)/x


$$1/\sqrt{x}$$

sqrt(1+x)/(1+x)


$$1/\sqrt{1+x}$$

sqrt(x-1)/(x-1)


$$1/\sqrt{x-1}$$

So in other words, Sage automatically simplifies all of the other expressions I tried in exactly the way that I would expect. To try out things a bit further, I tried to see if it helps to apply Sympy:

( sqrt(1-x)/(1-x) )._sympy_().simplify()


$$1/\sqrt{1-x}$$

That works. (The simplify() argument is essential here; otherwise, the fraction is not automatically simplified.)

So, is there some subtle finesse here that I'm not understanding, or did I stumble across a bug in Sage's simplification algorithms?

edit retag close merge delete

Sort by » oldest newest most voted

Sagemath formatting routine is somewhat asinine in radical-involving fraction handling, due to internal representation of expressions. Contemplate :

sage: 1/sqrt(2)
1/2*sqrt(2)


It turns out that, in this case, Sage denotes a division by a multiplication :

sage: (1/sqrt(2)).operator()
<function mul_vararg at 0x7fd16a1949d0>
sage: (1/sqrt(2)).operands()
[sqrt(2), 1/2]


On the other hand, if :

sage: (sqrt(x+1)/(x+1)).operator()
<built-in function pow>
sage: (sqrt(x+1)/(x+1)).operands()
[x + 1, -1/2]


the internal representation is different in your initial case :

sage: (sqrt(1-x)/(1-x)).operator()
<function mul_vararg at 0x7fd16a1949d0>
sage: (sqrt(1-x)/(1-x)).operands()
[1/(x - 1), sqrt(-x + 1), -1]


And; BTW, Sympy's internal representation is different :

sage: (sqrt(1-x)/(1-x))._sympy_().simplify()
1/sqrt(1 - x)
sage: (sqrt(1-x)/(1-x))._sympy_().simplify().func
<class 'sympy.core.power.Pow'>
sage: (sqrt(1-x)/(1-x))._sympy_().simplify().args
(1 - x, -1/2)


but this internal representation is lost when reverting to Sage :

sage: (sqrt(1-x)/(1-x))._sympy_()._sage_()
-sqrt(-x + 1)/(x - 1)
sage: (sqrt(1-x)/(1-x))._sympy_()._sage_().operator()
<function mul_vararg at 0x7fd16a1949d0>
sage: (sqrt(1-x)/(1-x))._sympy_()._sage_().operands()
[1/(x - 1), sqrt(-x + 1), -1]


EDIT : FWIW, the internal representation used by Mathematica is yet another :

sage: mathematica("M=Sqrt[1-x]/(1-x)")
1/Sqrt[1 - x]
sage: mathematica("Table[M[[u]], {u, Range[0,(Length[M])]}]")
{Power, 1 - x, -1/2}


HTH,

more

Thanks! The takeaway message, the way I see it as a Sage beginner, is that it can always be useful to check with Sympy if it can help with further simplification if we see Sage results that look overly complex.