# 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 == 100e^(100C + 100x)/(e^(100C + 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?

edit retag close merge delete

Sort by » oldest newest most voted

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.

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.

more

Thanks! 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.

( 2015-12-15 13:54:18 +0100 )edit

Note 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.

( 2015-12-15 17:11:33 +0100 )edit

Yes, 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?)

( 2015-12-15 19:10:30 +0100 )edit

To 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 yis 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.

( 2015-12-16 09:48:29 +0100 )edit

I 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...

( 2015-12-17 09:26:43 +0100 )edit