# Replacing mathematical functions of expressions with different mathematical functions of the same expression

Hello!

I am trying to replace hyperbolic trig with it's expanded form. As a concrete example I would like to replace

arcsinh(z) = ln( z + sqrt(z^2 + 1) )


Now I can do this if I knew that it was actually arcsinh(z) using subs, specifically using the command;

test = arcsinh(z)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )


The problem is that this seems to work only if it's an exact string match. Meaning if I tried;

test = arcsinh(1/3*x + 1/3)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )


I get

test2 = arcsinh(1/3*x + 1/3)


Is there a way to replace anything of the form

arcsinh(stuff) -> log (stuff + sqrt((stuff)^2 + 1))


Or does sage have this built in somewhere? I want to ideally make a sage function that I can pass a (randomly generated) mathematical expression to and have it expand the hyperbolic pieces for me. Thus I won't know the argument of the hyperbolic beforehand most of the time.

To give a concrete example, I would like to have something along the following:

a = random(1,1000)
b = random(1,1000)
f = a*arcsinh(b*x + a^2) - b
f2 = f.magicsimplifyfunction()


and get out

f2 = a*log (b*x + a^2 + sqrt((b*x + a^2)^2 + 1)) - b


Where the magicsimplifyfunction is the function that will work on any such f, not tailored to that specific f.

Thanks!

Edit for clarity:

I need a solution that doesn't require me to know the argument of arcsinh beforehand. So the magicsimplyfunction would work something like this:

f = 5*arcsinh(3*x + 1) - 2*e^x + 6*x*arcsinh(x^2)


Applying the simplify function would then "capture" the arguments 3*x+1 and x^2 as dummy variable z1 and z2 respectively and replace them so it would look like the following:

f = 5*arcsinh(z1) - 2*e^x + 6*x*arcsinh(z2)
z1 = 3*x + 1
z2 = x^2


Then I would apply subs_expr to get the following:

f = 5*(log(z1 + sqrt(z1^2 + 1))) - 2*e^x +6*x*(log(z2 + sqrt(z2^2 + 1)))


Then compose back in (or more accurately use another subs_expr) z1 and z2 to finally get

f = 5*(log(3*x+1 + sqrt((3*x+1)^2 + 1))) - 2*e^x +6*x*(log(x^2 + sqrt(x^4 + 1)))


The important thing here is nowhere in the process of executing the "magicsimplifyfunction" command did I specify 3x+1 or x^2. Because in most cases I won't know that's the argument before I am trying to expand it.

edit retag close merge delete

You may find https://ask.sagemath.org/question/293... useful... there are also many Maxima functions that help, which are accessible using .maxima_methods(), I think.

( 2016-09-07 12:50:42 -0500 )edit
1

Unless I am being dumb (which is definitely possible) both those solutions seem to require that I know the argument of arcsinh before I replace it. Which I don't.

What I need is some way to capture the argument of arcsinh (which is one term in a larger function, say f(x) ) assign it a dummy variable, then use subs to replace that with the expanded form using the dummy variable, and then compose back in the original argument. But I have no idea how to capture the original argument. Especially if there is more than one arcsinh with different arguments in the same equation that I would like to replace.

Edit: Yep, I'm being dumb. Situation normal. Wildcards were it, thanks kcrisman!

( 2016-09-07 13:43:50 -0500 )edit

Sort by » oldest newest most voted

There are so-called wild-cards, for exactly this purpose:

sage: test2 = arcsinh(1/3*x + 1/3)
sage: w0 = SR.wild(0)
sage: test2.substitute(arcsinh(w0) == log(w0))
log(1/3*x + 1/3)

more

Yep, that's exactly what I needed, thanks!

( 2016-09-07 13:55:55 -0500 )edit

I ran into an oddity, which is that the above method works great for sinh, cosh, tanh, arcsinh, arccosh, arctanh, arcsech, arccsch, and arccoth. But sech, coth, and csch get rejected for some reason. Even something as trivial as test1 = test2.substitute(coth(w0) == 5) fails. (I also tried the formal definition, that also failed). It's baffling because you can literally take the tanh code and just flip the fraction in the definition. Works for tanh. Fails for coth. Any idea what gives?

( 2016-09-07 15:28:08 -0500 )edit

My guess (only a guess) is that Pynac (our internal symbolics) treats these differently. E.g. something like https://trac.sagemath.org/ticket/20134 ?

( 2016-09-07 16:32:21 -0500 )edit

Ah, that's probably a good bet, seems like in the line (in that link):

performance: GiNaC functions for coth/sech/csch/acoth/asech/acsch (R. Stephan, A. Thakkar)

That seems to target exactly the functions I have issue with, so whatever happened in there is probably the problem. Oh well, I can work around it I think, thanks for the help!

( 2016-09-07 19:08:20 -0500 )edit

It's nice if you can work around it, but it's still a bug. Reported here:

https://trac.sagemath.org/ticket/21444

( 2016-09-08 00:44:51 -0500 )edit

For the special case where you want to replace exactly a function there is the special substitute_function:

sage: tanh(1/3*x+1/3).substitute_function(tanh,log)
log(1/3*x + 1/3)
sage: coth(1/3*x+1/3).substitute_function(coth,log)
log(1/3*x + 1/3)

more