SymPy dsolve with a parameter gives a wrong answer when the parameter is zero
My Code
I have a program that calculates the solutions to a 2nd-order differential equation, like in the code snippet below:
import sympy as sp
print('sympy version:', sp.__version__)
t = sp.symbols('t', real=True, nonnegative=True)
n = sp.symbols('n', integer=True, nonnegative=True)
f = sp.symbols('f', cls=sp.Function)
diff_eq = sp.Eq(f(t).diff(t, 2) + n**2*f(t), 0)
print('general solution:', sp.dsolve(diff_eq, f(t)))
print('solution at n=0 (pre-subs):', sp.dsolve(diff_eq.subs(n, 0), f(t)))
print('solution at n=0 (post-subs):', sp.dsolve(diff_eq, f(t)).subs(n, 0))
Results:
sympy version: 1.3
general solution: Eq(f(t), C1*sin(n*t) + C2*cos(n*t))
solution at n=0 (pre-subs): Eq(f(t), C1 + C2*t)
solution at n=0 (post-subs): Eq(f(t), C2)
My Problem
The solution form for a general n
does not seem to accurately describe the specific solution form for n=0
. Specifically, using dsolve
first and subs(n, 0)
second produces different results than using subs(n, 0)
first and dsolve
second, even though the two should be logically equivalent.
Can somebody explain the reason for the discrepancy in my results? Am I doing something wrong, or is this a bug?
python sympy
add a comment |
My Code
I have a program that calculates the solutions to a 2nd-order differential equation, like in the code snippet below:
import sympy as sp
print('sympy version:', sp.__version__)
t = sp.symbols('t', real=True, nonnegative=True)
n = sp.symbols('n', integer=True, nonnegative=True)
f = sp.symbols('f', cls=sp.Function)
diff_eq = sp.Eq(f(t).diff(t, 2) + n**2*f(t), 0)
print('general solution:', sp.dsolve(diff_eq, f(t)))
print('solution at n=0 (pre-subs):', sp.dsolve(diff_eq.subs(n, 0), f(t)))
print('solution at n=0 (post-subs):', sp.dsolve(diff_eq, f(t)).subs(n, 0))
Results:
sympy version: 1.3
general solution: Eq(f(t), C1*sin(n*t) + C2*cos(n*t))
solution at n=0 (pre-subs): Eq(f(t), C1 + C2*t)
solution at n=0 (post-subs): Eq(f(t), C2)
My Problem
The solution form for a general n
does not seem to accurately describe the specific solution form for n=0
. Specifically, using dsolve
first and subs(n, 0)
second produces different results than using subs(n, 0)
first and dsolve
second, even though the two should be logically equivalent.
Can somebody explain the reason for the discrepancy in my results? Am I doing something wrong, or is this a bug?
python sympy
add a comment |
My Code
I have a program that calculates the solutions to a 2nd-order differential equation, like in the code snippet below:
import sympy as sp
print('sympy version:', sp.__version__)
t = sp.symbols('t', real=True, nonnegative=True)
n = sp.symbols('n', integer=True, nonnegative=True)
f = sp.symbols('f', cls=sp.Function)
diff_eq = sp.Eq(f(t).diff(t, 2) + n**2*f(t), 0)
print('general solution:', sp.dsolve(diff_eq, f(t)))
print('solution at n=0 (pre-subs):', sp.dsolve(diff_eq.subs(n, 0), f(t)))
print('solution at n=0 (post-subs):', sp.dsolve(diff_eq, f(t)).subs(n, 0))
Results:
sympy version: 1.3
general solution: Eq(f(t), C1*sin(n*t) + C2*cos(n*t))
solution at n=0 (pre-subs): Eq(f(t), C1 + C2*t)
solution at n=0 (post-subs): Eq(f(t), C2)
My Problem
The solution form for a general n
does not seem to accurately describe the specific solution form for n=0
. Specifically, using dsolve
first and subs(n, 0)
second produces different results than using subs(n, 0)
first and dsolve
second, even though the two should be logically equivalent.
Can somebody explain the reason for the discrepancy in my results? Am I doing something wrong, or is this a bug?
python sympy
My Code
I have a program that calculates the solutions to a 2nd-order differential equation, like in the code snippet below:
import sympy as sp
print('sympy version:', sp.__version__)
t = sp.symbols('t', real=True, nonnegative=True)
n = sp.symbols('n', integer=True, nonnegative=True)
f = sp.symbols('f', cls=sp.Function)
diff_eq = sp.Eq(f(t).diff(t, 2) + n**2*f(t), 0)
print('general solution:', sp.dsolve(diff_eq, f(t)))
print('solution at n=0 (pre-subs):', sp.dsolve(diff_eq.subs(n, 0), f(t)))
print('solution at n=0 (post-subs):', sp.dsolve(diff_eq, f(t)).subs(n, 0))
Results:
sympy version: 1.3
general solution: Eq(f(t), C1*sin(n*t) + C2*cos(n*t))
solution at n=0 (pre-subs): Eq(f(t), C1 + C2*t)
solution at n=0 (post-subs): Eq(f(t), C2)
My Problem
The solution form for a general n
does not seem to accurately describe the specific solution form for n=0
. Specifically, using dsolve
first and subs(n, 0)
second produces different results than using subs(n, 0)
first and dsolve
second, even though the two should be logically equivalent.
Can somebody explain the reason for the discrepancy in my results? Am I doing something wrong, or is this a bug?
python sympy
python sympy
edited Nov 15 '18 at 1:18
user6655984
asked Nov 14 '18 at 7:28
CrepeGoatCrepeGoat
893914
893914
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It can be considered a bug in dsolve
logic: it finds two eigenvalues n
and -n
and treats them as different without considering the special case n=0
when they are equal. Ideally it would output a Piecewise like the following code does.
sol_nonzero = sp.dsolve(diff_eq, f(t)).rhs
sol_zero = sp.dsolve(diff_eq.subs(n, 0), f(t)).rhs
sol_complete = sp.Piecewise((sol_nonzero, sp.Ne(n, 0)), (sol_zero, True))
print('general solution:', sol_complete)
print('solution at n=0:', sol_complete.subs(n, 0))
This prints
general solution: Piecewise((C1*sin(n*t) + C2*cos(n*t), Ne(n, 0)), (C1 + C2*t, True))
solution at n=0: C1 + C2*t
A more familiar mathematical form is provided by sp.pprint(sol_complete)
.
⎧C₁⋅sin(n⋅t) + C₂⋅cos(n⋅t) for n ≠ 0
⎨
⎩ C₁ + C₂⋅t otherwise
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295065%2fsympy-dsolve-with-a-parameter-gives-a-wrong-answer-when-the-parameter-is-zero%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It can be considered a bug in dsolve
logic: it finds two eigenvalues n
and -n
and treats them as different without considering the special case n=0
when they are equal. Ideally it would output a Piecewise like the following code does.
sol_nonzero = sp.dsolve(diff_eq, f(t)).rhs
sol_zero = sp.dsolve(diff_eq.subs(n, 0), f(t)).rhs
sol_complete = sp.Piecewise((sol_nonzero, sp.Ne(n, 0)), (sol_zero, True))
print('general solution:', sol_complete)
print('solution at n=0:', sol_complete.subs(n, 0))
This prints
general solution: Piecewise((C1*sin(n*t) + C2*cos(n*t), Ne(n, 0)), (C1 + C2*t, True))
solution at n=0: C1 + C2*t
A more familiar mathematical form is provided by sp.pprint(sol_complete)
.
⎧C₁⋅sin(n⋅t) + C₂⋅cos(n⋅t) for n ≠ 0
⎨
⎩ C₁ + C₂⋅t otherwise
add a comment |
It can be considered a bug in dsolve
logic: it finds two eigenvalues n
and -n
and treats them as different without considering the special case n=0
when they are equal. Ideally it would output a Piecewise like the following code does.
sol_nonzero = sp.dsolve(diff_eq, f(t)).rhs
sol_zero = sp.dsolve(diff_eq.subs(n, 0), f(t)).rhs
sol_complete = sp.Piecewise((sol_nonzero, sp.Ne(n, 0)), (sol_zero, True))
print('general solution:', sol_complete)
print('solution at n=0:', sol_complete.subs(n, 0))
This prints
general solution: Piecewise((C1*sin(n*t) + C2*cos(n*t), Ne(n, 0)), (C1 + C2*t, True))
solution at n=0: C1 + C2*t
A more familiar mathematical form is provided by sp.pprint(sol_complete)
.
⎧C₁⋅sin(n⋅t) + C₂⋅cos(n⋅t) for n ≠ 0
⎨
⎩ C₁ + C₂⋅t otherwise
add a comment |
It can be considered a bug in dsolve
logic: it finds two eigenvalues n
and -n
and treats them as different without considering the special case n=0
when they are equal. Ideally it would output a Piecewise like the following code does.
sol_nonzero = sp.dsolve(diff_eq, f(t)).rhs
sol_zero = sp.dsolve(diff_eq.subs(n, 0), f(t)).rhs
sol_complete = sp.Piecewise((sol_nonzero, sp.Ne(n, 0)), (sol_zero, True))
print('general solution:', sol_complete)
print('solution at n=0:', sol_complete.subs(n, 0))
This prints
general solution: Piecewise((C1*sin(n*t) + C2*cos(n*t), Ne(n, 0)), (C1 + C2*t, True))
solution at n=0: C1 + C2*t
A more familiar mathematical form is provided by sp.pprint(sol_complete)
.
⎧C₁⋅sin(n⋅t) + C₂⋅cos(n⋅t) for n ≠ 0
⎨
⎩ C₁ + C₂⋅t otherwise
It can be considered a bug in dsolve
logic: it finds two eigenvalues n
and -n
and treats them as different without considering the special case n=0
when they are equal. Ideally it would output a Piecewise like the following code does.
sol_nonzero = sp.dsolve(diff_eq, f(t)).rhs
sol_zero = sp.dsolve(diff_eq.subs(n, 0), f(t)).rhs
sol_complete = sp.Piecewise((sol_nonzero, sp.Ne(n, 0)), (sol_zero, True))
print('general solution:', sol_complete)
print('solution at n=0:', sol_complete.subs(n, 0))
This prints
general solution: Piecewise((C1*sin(n*t) + C2*cos(n*t), Ne(n, 0)), (C1 + C2*t, True))
solution at n=0: C1 + C2*t
A more familiar mathematical form is provided by sp.pprint(sol_complete)
.
⎧C₁⋅sin(n⋅t) + C₂⋅cos(n⋅t) for n ≠ 0
⎨
⎩ C₁ + C₂⋅t otherwise
answered Nov 15 '18 at 1:26
user6655984
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295065%2fsympy-dsolve-with-a-parameter-gives-a-wrong-answer-when-the-parameter-is-zero%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown