# can't make an obvious simplification

These two functions are inverses, and when I print them, simplifying the first composition to x is obvious. And Sage resolves the second composition to x easily, But Sage simplify or simplify_full doesn't work on the first, which simplifies to x just on inspection, and a boolean test claims they aren't equal. Is there a way to simplify such an obvious function? The cube root of a cube should simplify easily.

a(x)=(2*x-3)^(1/3)+4
b(x)=((x-4)^3+3)/2
print(a(b(x)))
print(b(a(x)))


((x - 4)^3)^(1/3) + 4

x

h(x)=a(b(x))
print(h(x).simplify_full())


(x^3 - 12x^2 + 48x - 64)^(1/3) + 4

bool(((x - 4)^3)^(1/3) + 4 == x)


False

edit retag close merge delete

I understand I'm dealing with symbolic values, but why does b(x) simplify automatically but a(x) does not?

( 2020-11-22 04:41:56 +0100 )edit

Sort by » oldest newest most voted

Hello, @cybervigilante! The problem is that the cube root operation (actually any integer root) does not represent a single value, but many at a time. For example, consider this simple case

ans = (-8) ^ (-1/3)


One naturally would expect the value of ans to be -2, but if you write N(ans), you will get 1.00000000000000 + 1.73205080756888*I. In fact, there are three possible values for ans, i.e. ans = -2, ans = 1.00000000000000 + 1.73205080756888*I and ans = 1.00000000000000 - 1.73205080756888*I. These are the solutions to the equation $x^3 + 8 = 0$ en the set of complex numbers $\mathbb{C}$.

Sage is a mathematical software, and it tries to be as useful as possible. In your particular case, this implies giving one complex value for the cube root (since the real value can be mentally computed.) This is working against your intentions in your code: Sage doesn't know if $x$ is a complex or real variable,so it makes the most useful/general assumption: $x$ is complex. (Notice that, on the contrary, elevating to the third power does give a unique value.) As a consequence, in $\mathbb{C}$, you have $(x^{1/3})^3 = x$, but $(x^3)^{1/3}$ not necessarily being equal to $x$.

Now, consider your chunk of code:

a(x) = (2*x - 3) ^ (1/3) + 4
b(x) = ((x - 4) ^ 3 + 3) / 2
print(a(b(x)))
print(b(a(x)))


In this case, you have $$b(a(x)) = ((a(x) - 4) ^ 3 + 3) / 2 = (((2x - 3) ^ {1/3} + 4 - 4)^3 + 3) / 2 = (((2x - 3) ^ {1/3})^3 + 3) / 2.$$ Since elevating to the third power gives a unique answer, regardless of whether the base is real or complex, you can basically simplify the cube root with the third power, so $b(a(x)) = (((2x - 3) + 3) / 2 = (2x - 3 + 3) / 2 = (2x)/2 = x$, as Sage has printed. However, in the other case, you have $$a(b(x)) = (2a(x) - 3) ^ {1/3} + 4 = (2(((x - 4) ^ 3 + 3) / 2) - 3)^{1/3} + 4$$ $$~~~~= (((x - 4) ^ 3 + 3) - 3)^{1/3} + 4 = ((x - 4) ^ 3)^{1/3} + 4.$$ Now, this is where you will have problems. As mentioned above, the cube root has not a unique value, so Sage won't simplify the third power with the cube root, because, in that case, it should (randomly) choose one the three possibilities, which is a terrible mistake.

All of that being said, I believe you do want to work with reals in this particular case of the code in your question. (In contrast to the case of complex numbers, in the set of real numbers, $\mathbb{R}$, it IS A PROPERTY that $(x^3)^{1/3} = x$.) In order to do that, declare $x$ to be explicitly a real symbolic variable, as follows:

x = var('x', domain='real')
a(x) = (2*x - 3) ^ (1/3) + 4
b(x) = ((x - 4) ^ 3 + 3) / 2
print(a(b(x)))
print(b(a(x)))


In that case, both compositions give the result x.

I hope this helps!

more

You may try :

sage: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:a(x)=(2*x-3)^(1/3)+4
:b(x)=((x-4)^3+3)/2
:--
sage: b(a(x))
x
sage: a(b(x))
((x - 4)^3)^(1/3) + 4
x


But beware : such "obvious" simplifications are not always legitimate (think of negative powers or negative exponends...).

more

Thanks. The docs on domains and rings are kind of inscrutable and scattered for beginners, but that's clear enough.

( 2020-12-01 21:16:55 +0100 )edit