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.Fri, 18 Dec 2015 10:41:06 +0100logistic differential equationhttps://ask.sagemath.org/question/31383/logistic-differential-equation/Using:
y = function('y', x)
desolve(diff(y,x) == y*(100-y), y)
results in
-1/100*log(y(x) - 100) + 1/100*log(y(x)) == _C + x
This is correct but not very helpful. I found out that "manually" feeding the answer above to solve() changing _C to a defined variable and the function y(x) for a variable and using the argument to_poly_solve=True gives the expected result: y == 100*e^(100*C + 100*x)/(e^(100*C + 100*x) - 1)
But I cannot get it to work in one calculation like this:
y = function('y', x)
de = diff(y,x) == y*(100-y)
sol=desolve(de,y)
print("Not so nice:")
sol
print("Better:")
solve(sol, y, to_poly_solve=True)
Would like to know:
a) Is there a way to get desolve or similar solver to return the y= answer directly?
b) If not a) how do I make the desolve -> solve calculation without manually rewriting the solution?
Mon, 07 Dec 2015 19:08:10 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/Answer by slelievre for <p>Using:</p>
<pre><code>y = function('y', x)
desolve(diff(y,x) == y*(100-y), y)
</code></pre>
<p>results in</p>
<pre><code>-1/100*log(y(x) - 100) + 1/100*log(y(x)) == _C + x
</code></pre>
<p>This is correct but not very helpful. I found out that "manually" feeding the answer above to solve() changing _C to a defined variable and the function y(x) for a variable and using the argument to_poly_solve=True gives the expected result: y == 100<em>e^(100</em>C + 100<em>x)/(e^(100</em>C + 100*x) - 1)</p>
<p>But I cannot get it to work in one calculation like this:</p>
<pre><code>y = function('y', x)
de = diff(y,x) == y*(100-y)
sol=desolve(de,y)
print("Not so nice:")
sol
print("Better:")
solve(sol, y, to_poly_solve=True)
</code></pre>
<p>Would like to know:</p>
<p>a) Is there a way to get desolve or similar solver to return the y= answer directly?</p>
<p>b) If not a) how do I make the desolve -> solve calculation without manually rewriting the solution?</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?answer=31577#post-id-31577The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.
sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:
sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
I'd still be interested in a cleaner solution.
Tue, 15 Dec 2015 08:54:24 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?answer=31577#post-id-31577Comment by slelievre for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31587#post-id-31587Note that you get the warning only once per Sage session. I edited my answer to say so and to add a workaround to the deprecated substitution.Tue, 15 Dec 2015 17:11:33 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31587#post-id-31587Comment by AndersM for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31580#post-id-31580Thanks!
I have now been searching for how to rewrite without getting the "DeprecationWarning: Substitution using function-call syntax and unnamed arguments ..." warning from sol.substitute({y(x):z})
But without finding the answer.Tue, 15 Dec 2015 13:54:18 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31580#post-id-31580Comment by AndersM for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31590#post-id-31590Yes, Thanks again. I will use your answer.
I think there should be a straight-forward way to go from a solution of a differential equation to using that solution in further calculations. But there seems not to be that way (yet?)Tue, 15 Dec 2015 19:10:30 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31590#post-id-31590Comment by nbruin for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31602#post-id-31602To avoid the deprecation problems:
sage: yx = function('y')(x)
sage: de = diff(yx, x) == yx*(100 - yx)
sage: sol = desolve(de, yx)
sage: z = SR.var('z')
sage: solz = sol.substitute({yx:z})
sage: solz.solve(z, to_poly_solve=True)
Note that `yx` is the expression `y(x)` and that `y` is a function. They are different objects (the documentation of desolve is itself confused about that). After the merger of http://trac.sagemath.org/ticket/17447 this will slightly improve.Wed, 16 Dec 2015 09:48:29 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31602#post-id-31602Comment by AndersM for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31644#post-id-31644I hope it will improve! Something like substitute(old variable or function, new variable or function) would be much easier to remember and makes a lot more sense than knowing that you have to rewrite y(x) as yx and use python dictionary notation...Thu, 17 Dec 2015 09:26:43 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31644#post-id-31644Comment by nbruin for <p>The following works for now, but the substitution used below is deprecated,
so it outputs a deprecation warning (once per session) and more importantly
it might not work in a future version of Sage. Maybe someone can give
a more future-proof solution.</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = sol.substitute({y(x):z}) # deprecated
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>To work around the deprecation warning, one could do the replacement
in the string representation of the expression and then read the string
again into an expression. Not very elegant, but here goes:</p>
<pre><code>sage: y = function('y', x)
sage: de = diff(y, x) == y*(100 - y)
sage: sol = desolve(de, y)
sage: z = SR.var('z')
sage: solz = SR(str(sol.lhs()).replace('y(x)', 'z')) == sol.rhs()
sage: solz
-1/100*log(z - 100) + 1/100*log(z) == _C + x
sage: solz.solve(z, to_poly_solve=True)
[z == 100*e^(100*_C + 100*x)/(e^(100*_C + 100*x) - 1)]
</code></pre>
<p>I'd still be interested in a cleaner solution.</p>
https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31673#post-id-31673I think you missed the point. This works fine too:
sage: function('y')
y
sage: de = diff(y(x), x) == y(x)*(100 - y(x))
sage: sol = desolve(de, y(x))
sage: var('z')
z
sage: solz = sol.subs({y(x):z})
sage: solz.solve(z, to_poly_solve=True)
You cannot write `sol.subs(y(x)=z)` because the Python parser will complain. That will never change. It's the price we pay for building on Python.
You're not substituting functions. You are replacing the subexpression `y(x)` by the expression `z`. A function substitution looks like:
sage: (y(x)).substitute_function(y,sin)
sin(x)
(it may seem like a pedantic difference, but it reflects how Sage represents the expressions internally)Fri, 18 Dec 2015 10:41:06 +0100https://ask.sagemath.org/question/31383/logistic-differential-equation/?comment=31673#post-id-31673