Comment #1 on issue 3148 by [email protected]: Too many constants from
dsolve()
http://code.google.com/p/sympy/issues/detail?id=3148
In particular, there are at least two issues:
- In the more complex 1st order methods, such as separable and homogeneous
coefficients, where f(x) can appear in any form and hence the solution can
take literally any form when f(x) is solved for, constants are simplified
and then renumbered. If a constant is split into two places after solving,
it is simplified and renumbered independently, resulting in two new
constants that are actually just one (because they depend on each other).
For example, consider the example from the docstring of
ode_1st_homogeneous_coeff_best:
In [99]: dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x), f(x),
hint='1st_homogeneous_coeff_best', simplify=False)
Out[99]:
⎛ 2 ⎞
⎜ 3⋅x ⎟
log⎜───── + 1⎟
⎜ 2 ⎟
⎛f(x)⎞ ⎝f (x) ⎠
log⎜────⎟ + ────────────── = 0
⎝ C₁ ⎠ 3
We can solve this for f(x) (using the work-around from issue 3149):
In [110]: solve(logcombine(dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x),
f(x), hint='1st_homogeneous_coeff_best', simplify=False), force=True), f(x))
⎡ _______________________
⎢ ╱ __________
⎢ 2 ╱ 3 ╱ 6
⎢ x ╱ C₁ ╱ C₁ 6
⎢───────────────────────────── - 3 ╱ ─── + ╱ ─── + x ,
──────────────
⎢ _______________________ ╲╱ 2 ╲╱ 4
⎢ ╱ __________
⎢ ╱ 3 ╱ 6 ⎛ ___
⎢ ╱ C₁ ╱ C₁ 6 ⎜ 1 ╲╱ 3
⋅ⅈ
⎢3 ╱ ─── + ╱ ─── + x ⎜- ─ -
───────
⎣╲╱ 2 ╲╱ 4 ⎝ 2 2
______________________
╱
__________
2 ⎛ ___ ⎞ ╱ 3 ╱ 6
x ⎜ 1 ╲╱ 3 ⋅ⅈ⎟ ╱ C₁ ╱ C₁
6
─────────────────────────────── - ⎜- ─ - ───────⎟⋅3 ╱ ─── + ╱ ─── + x
_______________________ ⎝ 2 2 ⎠ ╲╱ 2 ╲╱ 4
╱ __________
⎞ ╱ 3 ╱ 6
⎟ ╱ C₁ ╱ C₁ 6
⎟⋅3 ╱ ─── + ╱ ─── + x
⎠ ╲╱ 2 ╲╱ 4
_
_____
╱
2 ⎛ ___ ⎞ ╱
3
x ⎜ 1 ╲╱ 3 ⋅ⅈ⎟ ╱ C₁
, ───────────────────────────────────────────── - ⎜- ─ + ───────⎟⋅3 ╱
───
_______________________ ⎝ 2 2 ⎠ ╲╱ 2
╱ __________
⎛ ___ ⎞ ╱ 3 ╱ 6
⎜ 1 ╲╱ 3 ⋅ⅈ⎟ ╱ C₁ ╱ C₁ 6
⎜- ─ + ───────⎟⋅3 ╱ ─── + ╱ ─── + x
⎝ 2 2 ⎠ ╲╱ 2 ╲╱ 4
__________________⎤
__________ ⎥
╱ 6 ⎥
╱ C₁ 6 ⎥
+ ╱ ─── + x ⎥
╲╱ 4 ⎥
⎥
⎥
⎥
⎥
⎦
Now, here is the solution from dsolve(simplify=True):
In [111]: dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x), f(x),
hint='1st_homogeneous_coeff_best',
simplify=True)⎡ ___________________
⎢ 2 ╱ _________
⎢ x 3 ╱ ╱ 6
⎢f(x) = ─────────────────────── - ╲╱ C₃ + ╲╱ C₄ + x , f(x) =
────────────
⎢ ___________________
⎢ ╱ _________ ⎛
___
⎢ 3 ╱ ╱ 6 ⎜ 1 ╲╱
3
⎢ ╲╱ C₁ + ╲╱ C₂ + x ⎜- ─ -
─────
⎣ ⎝ 2
2
___________________
2 ⎛ ___ ⎞ ╱ _________
x ⎜1 ╲╱ 3 ⋅ⅈ⎟ 3 ╱ ╱ 6
─────────────────────────── + ⎜─ + ───────⎟⋅╲╱ C₁ + ╲╱ C₂ + x , f(x) =
──
___________________ ⎝2 2 ⎠
⎞ ╱ _________
⎛
⋅ⅈ⎟ 3 ╱ ╱ 6
⎜
──⎟⋅╲╱ C₃ + ╲╱ C₄ + x
⎜-
⎠
⎝
___________________⎤
2 ⎛ ___ ⎞ ╱
_________ ⎥
x ⎜1 ╲╱ 3 ⋅ⅈ⎟ 3 ╱ ╱
6 ⎥
───────────────────────────────────── + ⎜─ - ───────⎟⋅╲╱ C₁ + ╲╱ C₂ +
x ⎥
___________________ ⎝2 2
⎠ ⎥
___ ⎞ ╱
_________ ⎥
1 ╲╱ 3 ⋅ⅈ⎟ 3 ╱ ╱
6 ⎥
─ + ───────⎟⋅╲╱ C₃ + ╲╱ C₄ +
x ⎥
Notice that each instance of C1**3 and C1**6 have been labeled as a new
constant. For one thing, we could at least be smarter about it and only
relabel two constants, one for C1**3 and one for C1**6. But better, we
should just have one constant, C1 (for C1**3), and call the other one C1**2
(for C1**6). This will require a bit of smarter heuristics to find the
simplest form to do this as, but it will result in much less confusing and
misleading results.
- The nth order constant coefficients solver is not smart enough to
correctly handle symbolic roots to the characteristic polynomial. For
example:
In [116]: k = Symbol('k')
In [117]: dsolve(f(x).diff(x, x) + k*f(x), f(x))
⎛ ____⎞
⎛ ⎛ │ ⎛ ____⎞│⎞ ⎛ ⎛ ____⎞⎞⎞ x⋅re⎝-╲╱ -k ⎠ ⎛
f(x) = ⎝C₁⋅sin⎝x⋅│im⎝-╲╱ -k ⎠│⎠ + C₂⋅cos⎝x⋅im⎝-╲╱ -k ⎠⎠⎠⋅ℯ +
⎝C₃⋅
⎛ ____⎞
⎛ │ ⎛ ____⎞│⎞ ⎛ ⎛ ____⎞⎞⎞ x⋅re⎝╲╱ -k ⎠
sin⎝x⋅│im⎝╲╱ -k ⎠│⎠ + C₄⋅cos⎝x⋅im⎝╲╱ -k ⎠⎠⎠⋅ℯ
There are four constants here, because it generates four terms. But there
are only two linearly independent solutions. I think the solution here
would be to either rewrite the constants by default so that they show the
dependence that comes from converting the "actual" solution of
exp(+/-sqrt(-k)*x) into sines and cosines, or just return that in the first
place if we cannot get out an explicit imaginary part (i think the latter
solution is better).
--
You received this message because you are subscribed to the Google Groups
"sympy-issues" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy-issues?hl=en.