Ask Your Question

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

asked 2016-09-07 18:16:13 +0200

Jason021 gravatar image

updated 2016-09-07 20:51:55 +0200


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.


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 flag offensive close merge delete


You may find useful... there are also many Maxima functions that help, which are accessible using .maxima_methods(), I think.

kcrisman gravatar imagekcrisman ( 2016-09-07 19:50:42 +0200 )edit

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!

Jason021 gravatar imageJason021 ( 2016-09-07 20:43:50 +0200 )edit

2 Answers

Sort by » oldest newest most voted

answered 2016-09-07 20:33:01 +0200

FrédéricC gravatar image

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)
edit flag offensive delete link more


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

Jason021 gravatar imageJason021 ( 2016-09-07 20:55:55 +0200 )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?

Jason021 gravatar imageJason021 ( 2016-09-07 22:28:08 +0200 )edit

My guess (only a guess) is that Pynac (our internal symbolics) treats these differently. E.g. something like ?

kcrisman gravatar imagekcrisman ( 2016-09-07 23:32:21 +0200 )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!

Jason021 gravatar imageJason021 ( 2016-09-08 02:08:20 +0200 )edit

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

nbruin gravatar imagenbruin ( 2016-09-08 07:44:51 +0200 )edit

answered 2016-09-08 07:44:19 +0200

nbruin gravatar image

updated 2016-09-08 07:46:40 +0200

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)
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2016-09-07 18:16:13 +0200

Seen: 1,338 times

Last updated: Sep 08 '16