ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 08 Sep 2016 07:44:51 +0200Replacing mathematical functions of expressions with different mathematical functions of the same expressionhttps://ask.sagemath.org/question/34767/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.Wed, 07 Sep 2016 18:16:13 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/Comment by kcrisman for <p>Hello!</p>
<p>I am trying to replace hyperbolic trig with it's expanded form. As a concrete example I would like to replace</p>
<pre><code>arcsinh(z) = ln( z + sqrt(z^2 + 1) )
</code></pre>
<p>Now I can do this if I knew that it was actually arcsinh(z) using subs, specifically using the command;</p>
<pre><code>test = arcsinh(z)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>The problem is that this seems to work only if it's an exact string match. Meaning if I tried;</p>
<pre><code>test = arcsinh(1/3*x + 1/3)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>I get </p>
<pre><code>test2 = arcsinh(1/3*x + 1/3)
</code></pre>
<p>Is there a way to replace anything of the form </p>
<pre><code>arcsinh(stuff) -> log (stuff + sqrt((stuff)^2 + 1))
</code></pre>
<p>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. </p>
<p>To give a concrete example, I would like to have something along the following:</p>
<pre><code>a = random(1,1000)
b = random(1,1000)
f = a*arcsinh(b*x + a^2) - b
f2 = f.magicsimplifyfunction()
</code></pre>
<p>and get out </p>
<pre><code>f2 = a*log (b*x + a^2 + sqrt((b*x + a^2)^2 + 1)) - b
</code></pre>
<p>Where the magicsimplifyfunction is the function that will work on any such f, not tailored to that specific f.</p>
<p>Thanks!</p>
<p>Edit for clarity:</p>
<p>I need a solution that doesn't require me to know the argument of arcsinh beforehand. So the magicsimplyfunction would work something like this:</p>
<pre><code>f = 5*arcsinh(3*x + 1) - 2*e^x + 6*x*arcsinh(x^2)
</code></pre>
<p>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:</p>
<pre><code>f = 5*arcsinh(z1) - 2*e^x + 6*x*arcsinh(z2)
z1 = 3*x + 1
z2 = x^2
</code></pre>
<p>Then I would apply subs_expr to get the following:</p>
<pre><code>f = 5*(log(z1 + sqrt(z1^2 + 1))) - 2*e^x +6*x*(log(z2 + sqrt(z2^2 + 1)))
</code></pre>
<p>Then compose back in (or more accurately use another subs_expr) z1 and z2 to finally get</p>
<pre><code>f = 5*(log(3*x+1 + sqrt((3*x+1)^2 + 1))) - 2*e^x +6*x*(log(x^2 + sqrt(x^4 + 1)))
</code></pre>
<p>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.</p>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34768#post-id-34768You may find https://ask.sagemath.org/question/29349/substitute-expressions-with-cos-and-sin/ useful... there are also many Maxima functions that help, which are accessible using `.maxima_methods()`, I think.Wed, 07 Sep 2016 19:50:42 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34768#post-id-34768Comment by Jason021 for <p>Hello!</p>
<p>I am trying to replace hyperbolic trig with it's expanded form. As a concrete example I would like to replace</p>
<pre><code>arcsinh(z) = ln( z + sqrt(z^2 + 1) )
</code></pre>
<p>Now I can do this if I knew that it was actually arcsinh(z) using subs, specifically using the command;</p>
<pre><code>test = arcsinh(z)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>The problem is that this seems to work only if it's an exact string match. Meaning if I tried;</p>
<pre><code>test = arcsinh(1/3*x + 1/3)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>I get </p>
<pre><code>test2 = arcsinh(1/3*x + 1/3)
</code></pre>
<p>Is there a way to replace anything of the form </p>
<pre><code>arcsinh(stuff) -> log (stuff + sqrt((stuff)^2 + 1))
</code></pre>
<p>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. </p>
<p>To give a concrete example, I would like to have something along the following:</p>
<pre><code>a = random(1,1000)
b = random(1,1000)
f = a*arcsinh(b*x + a^2) - b
f2 = f.magicsimplifyfunction()
</code></pre>
<p>and get out </p>
<pre><code>f2 = a*log (b*x + a^2 + sqrt((b*x + a^2)^2 + 1)) - b
</code></pre>
<p>Where the magicsimplifyfunction is the function that will work on any such f, not tailored to that specific f.</p>
<p>Thanks!</p>
<p>Edit for clarity:</p>
<p>I need a solution that doesn't require me to know the argument of arcsinh beforehand. So the magicsimplyfunction would work something like this:</p>
<pre><code>f = 5*arcsinh(3*x + 1) - 2*e^x + 6*x*arcsinh(x^2)
</code></pre>
<p>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:</p>
<pre><code>f = 5*arcsinh(z1) - 2*e^x + 6*x*arcsinh(z2)
z1 = 3*x + 1
z2 = x^2
</code></pre>
<p>Then I would apply subs_expr to get the following:</p>
<pre><code>f = 5*(log(z1 + sqrt(z1^2 + 1))) - 2*e^x +6*x*(log(z2 + sqrt(z2^2 + 1)))
</code></pre>
<p>Then compose back in (or more accurately use another subs_expr) z1 and z2 to finally get</p>
<pre><code>f = 5*(log(3*x+1 + sqrt((3*x+1)^2 + 1))) - 2*e^x +6*x*(log(x^2 + sqrt(x^4 + 1)))
</code></pre>
<p>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.</p>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34770#post-id-34770Unless 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!Wed, 07 Sep 2016 20:43:50 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34770#post-id-34770Answer by FrédéricC for <p>Hello!</p>
<p>I am trying to replace hyperbolic trig with it's expanded form. As a concrete example I would like to replace</p>
<pre><code>arcsinh(z) = ln( z + sqrt(z^2 + 1) )
</code></pre>
<p>Now I can do this if I knew that it was actually arcsinh(z) using subs, specifically using the command;</p>
<pre><code>test = arcsinh(z)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>The problem is that this seems to work only if it's an exact string match. Meaning if I tried;</p>
<pre><code>test = arcsinh(1/3*x + 1/3)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>I get </p>
<pre><code>test2 = arcsinh(1/3*x + 1/3)
</code></pre>
<p>Is there a way to replace anything of the form </p>
<pre><code>arcsinh(stuff) -> log (stuff + sqrt((stuff)^2 + 1))
</code></pre>
<p>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. </p>
<p>To give a concrete example, I would like to have something along the following:</p>
<pre><code>a = random(1,1000)
b = random(1,1000)
f = a*arcsinh(b*x + a^2) - b
f2 = f.magicsimplifyfunction()
</code></pre>
<p>and get out </p>
<pre><code>f2 = a*log (b*x + a^2 + sqrt((b*x + a^2)^2 + 1)) - b
</code></pre>
<p>Where the magicsimplifyfunction is the function that will work on any such f, not tailored to that specific f.</p>
<p>Thanks!</p>
<p>Edit for clarity:</p>
<p>I need a solution that doesn't require me to know the argument of arcsinh beforehand. So the magicsimplyfunction would work something like this:</p>
<pre><code>f = 5*arcsinh(3*x + 1) - 2*e^x + 6*x*arcsinh(x^2)
</code></pre>
<p>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:</p>
<pre><code>f = 5*arcsinh(z1) - 2*e^x + 6*x*arcsinh(z2)
z1 = 3*x + 1
z2 = x^2
</code></pre>
<p>Then I would apply subs_expr to get the following:</p>
<pre><code>f = 5*(log(z1 + sqrt(z1^2 + 1))) - 2*e^x +6*x*(log(z2 + sqrt(z2^2 + 1)))
</code></pre>
<p>Then compose back in (or more accurately use another subs_expr) z1 and z2 to finally get</p>
<pre><code>f = 5*(log(3*x+1 + sqrt((3*x+1)^2 + 1))) - 2*e^x +6*x*(log(x^2 + sqrt(x^4 + 1)))
</code></pre>
<p>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.</p>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?answer=34769#post-id-34769There 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)
Wed, 07 Sep 2016 20:33:01 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?answer=34769#post-id-34769Comment by kcrisman for <p>There are so-called wild-cards, for exactly this purpose:</p>
<pre><code>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)
</code></pre>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34773#post-id-34773My guess (only a guess) is that Pynac (our internal symbolics) treats these differently. E.g. something like https://trac.sagemath.org/ticket/20134 ?Wed, 07 Sep 2016 23:32:21 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34773#post-id-34773Comment by Jason021 for <p>There are so-called wild-cards, for exactly this purpose:</p>
<pre><code>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)
</code></pre>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34771#post-id-34771Yep, that's exactly what I needed, thanks!Wed, 07 Sep 2016 20:55:55 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34771#post-id-34771Comment by Jason021 for <p>There are so-called wild-cards, for exactly this purpose:</p>
<pre><code>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)
</code></pre>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34772#post-id-34772I 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?Wed, 07 Sep 2016 22:28:08 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34772#post-id-34772Comment by Jason021 for <p>There are so-called wild-cards, for exactly this purpose:</p>
<pre><code>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)
</code></pre>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34774#post-id-34774Ah, 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!Thu, 08 Sep 2016 02:08:20 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34774#post-id-34774Comment by nbruin for <p>There are so-called wild-cards, for exactly this purpose:</p>
<pre><code>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)
</code></pre>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34777#post-id-34777It's nice if you can work around it, but it's still a bug. Reported here:
https://trac.sagemath.org/ticket/21444Thu, 08 Sep 2016 07:44:51 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?comment=34777#post-id-34777Answer by nbruin for <p>Hello!</p>
<p>I am trying to replace hyperbolic trig with it's expanded form. As a concrete example I would like to replace</p>
<pre><code>arcsinh(z) = ln( z + sqrt(z^2 + 1) )
</code></pre>
<p>Now I can do this if I knew that it was actually arcsinh(z) using subs, specifically using the command;</p>
<pre><code>test = arcsinh(z)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>The problem is that this seems to work only if it's an exact string match. Meaning if I tried;</p>
<pre><code>test = arcsinh(1/3*x + 1/3)
test2 = test.subs_expr(arcsinh(z) == (log (z + sqrt((z^2 + 1))) )
</code></pre>
<p>I get </p>
<pre><code>test2 = arcsinh(1/3*x + 1/3)
</code></pre>
<p>Is there a way to replace anything of the form </p>
<pre><code>arcsinh(stuff) -> log (stuff + sqrt((stuff)^2 + 1))
</code></pre>
<p>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. </p>
<p>To give a concrete example, I would like to have something along the following:</p>
<pre><code>a = random(1,1000)
b = random(1,1000)
f = a*arcsinh(b*x + a^2) - b
f2 = f.magicsimplifyfunction()
</code></pre>
<p>and get out </p>
<pre><code>f2 = a*log (b*x + a^2 + sqrt((b*x + a^2)^2 + 1)) - b
</code></pre>
<p>Where the magicsimplifyfunction is the function that will work on any such f, not tailored to that specific f.</p>
<p>Thanks!</p>
<p>Edit for clarity:</p>
<p>I need a solution that doesn't require me to know the argument of arcsinh beforehand. So the magicsimplyfunction would work something like this:</p>
<pre><code>f = 5*arcsinh(3*x + 1) - 2*e^x + 6*x*arcsinh(x^2)
</code></pre>
<p>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:</p>
<pre><code>f = 5*arcsinh(z1) - 2*e^x + 6*x*arcsinh(z2)
z1 = 3*x + 1
z2 = x^2
</code></pre>
<p>Then I would apply subs_expr to get the following:</p>
<pre><code>f = 5*(log(z1 + sqrt(z1^2 + 1))) - 2*e^x +6*x*(log(z2 + sqrt(z2^2 + 1)))
</code></pre>
<p>Then compose back in (or more accurately use another subs_expr) z1 and z2 to finally get</p>
<pre><code>f = 5*(log(3*x+1 + sqrt((3*x+1)^2 + 1))) - 2*e^x +6*x*(log(x^2 + sqrt(x^4 + 1)))
</code></pre>
<p>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.</p>
https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?answer=34776#post-id-34776For 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)Thu, 08 Sep 2016 07:44:19 +0200https://ask.sagemath.org/question/34767/replacing-mathematical-functions-of-expressions-with-different-mathematical-functions-of-the-same-expression/?answer=34776#post-id-34776