# Why is DSolve different when the equation is built programmatically?

Here is a simple differential equation.

mwe=y[x]/.First@DSolve [{y'[x]==x-2*x*y[x],y[0]==0},y[x],x]


I get the answer $$\frac{1}{2}-\frac{e^{-x^2}}{2}$$

If I build up the same equation in a simple program, I get a different answer:

lsolve[r_,q_,a_,eta_]=y[x]/.First@DSolve[{y'[x]==r-q*y[x],y[a]==eta},y[x],x];
nwe=lsolve[x,2*x,0,0]


After simplifying, I get the answer $$\frac{1}{2}-\frac{e^{-2x^2}}{2}$$. Where did the extra factor of $$2$$ in the exponent come from? And how can I make it go away?

You attempt to solve the ODE at the time of definition of lsolve. At this point, q does not depend on x. You really want to use SetDelayed here:

lsolve[r_, q_, a_, eta_] :=
y[x] /. First@DSolve[{y'[x] == r - q*y[x], y[a] == eta}, y[x], x];
nwe = lsolve[x, 2*x, 0, 0] // Simplify


1/2 - E^-x^2/2

• Thanks, I'm glad I asked. Even though my version was syntactically correct, it would have been nice if Mathematica produced a warning! – Joe Corneli Feb 12 at 15:41
• How should Mathematica be able to detect that this does not align with your expectations? Both syntaxes f[x_] = ... and f[x_] := ... have the applications, e.g., the former can be considered as a shorthand for f[x_] := Evaluate[...]. This is usefull whenever a symbolic compuation can already performed at the time of definition so that it need not be redone every time f is called. – Henrik Schumacher Feb 12 at 17:17
• As you said in the answer: "At this point, q does not depend on x." I think Mathematica should be able to tell that I was building an expression that does depend on x and then generate a warning (but certainly not an error) very much along the lines of what you told me. Otherwise everyone who doesn't know about := will end up asking a question similar to mine. How to preempt that and automate your answer? :-) – Joe Corneli Feb 13 at 13:18
• When an assignment is made with =, Mathematica can only set the left hand side to the value of the right hand side at the time of assignment. Evaluate y[x]/.First@DSolve[{y'[x]==r-q*y[x],y[a]==eta},y[x],x] (just in case: in a fresh kernel) and you will see that the result is (E^(-q x) (E^(a q) eta q - E^(a q) r + E^(q x) r))/q. Because Mathematica solves the ODE at this point in time and because q is independent of x. Of course, you may tell Mathematica that q should depend on x by using q[x] instead of q, but I don't think you will like the result either. – Henrik Schumacher Feb 13 at 13:24
• I don't understand what you mean by "automation". The difference between = and := lies in the time of execution of the right hand side. If you want that the ODE is solved only after a precise value of q is supplied, you have to use :=. And yes, there are a lot of questions on the subtle differences of = and := on this site. And I have to admit that was also something that was quite miraculous to me when I started to use the language. It helps a bit to recall that Mathematica, in its core, is nothing else but a term rewriting system. – Henrik Schumacher Feb 13 at 13:28