4
$\begingroup$

Consider first the following vector-valued function of a real variable:

   s[t_] := {Sin[t], Cos[t]}

Then this works as expected:

   s'[t]
(* {Cos[t], -Sin[t]} *)

Why does the following use of prime to take derivative not also work?

   soln[t_] := {x[t], y[t]} /. 
  First@ DSolve[{Derivative[1][x][t] == y[t], 
     Derivative[1][y][t] == -x[t], x[0] == 0, y[0] == 1}, {x[t], 
     y[t]}, t]

   soln[t]
(* {Sin[t], Cos[t]} *)

   soln'[t]
(* During evaluation of In[89]:= ReplaceAll::reps: {First[{}]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing.
D[{x[t], y[t]} /. First[{}], t]*)

Note that the following does work:

   D[soln[t], t]
(* {Cos[t], -Sin[t]} *)
$\endgroup$
2
  • 2
    $\begingroup$ soln[t] := ... should be soln[t_] := ... (notice the undescore after the t). $\endgroup$
    – Victor K.
    Commented Mar 22, 2020 at 19:02
  • $\begingroup$ The missing underscore was purely a typo, now fixed in the original post. $\endgroup$
    – murray
    Commented Mar 23, 2020 at 15:18

4 Answers 4

4
$\begingroup$

I thought this was just about order of operations, and it is largely that, but there is an added twist I'll get to.

First, let me note you've defined soln using SetDelayed. I think that is a mistake because it means DSolve is reevaluated every single time you evaluate soln. If that's slow, soln will be very slow. In fact, I'd define soln as follows

soln[t_] = DSolveValue[Derivative[1][x][t] == y[t], Derivative[1][y][t] == -x[t], x[0] == 0, y[0] == 1}, {x[t], y[t]}, t]

Now, as for your mystery. When you evaluate soln'[t], this is interpreted as

Derivative[1][soln][t]

Okay, what's the derivative of soln? It's going to be computed as

D[soln[someVar], someVar]

Well, that looks very innocent, but the question is what is someVar? It depends on the version exactly what temporary expression Derivative uses, but critically this temporary variable is going into DSolve, not the solution, beacuse you've used SetDelayed to define soln. Moreover, the temporary expression is something that will prevent DSolve from evaluating successfully. In V12.1, DSolve returns an empty list, which means First[DSolve[...]] won't evaluate, which means /. won't evaluate, and you get the output above. And if you think about, trying to run DSolve, which solves things about derivatives, while in the process of actually computing a derivative, is going to problematic at best.

When you use D[soln[t],t], since D isn't a holding function, soln[t] evaluates to {Sin[t], Cos[t]} before D ever sees it, and you're fine.

Finally, had you defined soln using Set, then someVar would have been substituted into {Sin[t], Cos[t]} rather than the original DSolve expression, and everything would also have been fine. This is another reason why it is typically better to use Set when you are substituting output from a solver into an expression.

$\endgroup$
6
$\begingroup$

Let me try to clarify the mystery here. The way you defined soln[t], without the underscore, means that the delayed expansion will only work when you use symbol t as the argument:

soln[u]
(* soln[u] - it returns unevaluated *)

When you type D[soln[t],t], you are just lucky that the first argument evaluates to {Sin[t], Cos[t]}, which gets differentiated. If you try any other letter, e.g.

D[soln[u],u]
(* Derivative[1][soln][u] *)

it returns unchanged.

$\endgroup$
5
$\begingroup$

Besides the underscore, the problem is the SetDelayed := .

{soln[t_] = {x[t], y[t]} /. 
First@DSolve[{Derivative[1][x][t] == y[t], 
  Derivative[1][y][t] == -x[t], x[0] == 0, y[0] == 1}, {x[t], 
  y[t]}, t],
soln[t],
soln'[t]}

(*   {{Sin[t], Cos[t]}, {Sin[t], Cos[t]}, {Cos[t], -Sin[t]}}   *)

Let me say, many user here think, SetDelayed is the best way to define nearly everything. The opposite is true. Use it as less as absolutly necessary.

$\endgroup$
2
  • 1
    $\begingroup$ SetDelayed is the best way to define nearly everything. The opposite is true. Use it as less as absolutly necessary. main problem with using set for function definitions is as shown in possible issues under Set. If one has global symbol already has value, then it will fail. ClearAll[x];x = 5;f[x_] = x^2;f[2] this gives 25 instead of expected 4. Using SetDelayed solves these problems. So for me := is just more safe to use as general otherwise one needs to make sure symbols used in definition of Set are cleared before. $\endgroup$
    – Nasser
    Commented Mar 22, 2020 at 19:40
  • 1
    $\begingroup$ I think, there are a lot of possibilities to avoid global symbol definition, e.g. With , Module , ReplaceAll ... And there is undocumented agreement, to reserve symbls like x,y,z, t,u,v ...for varialble definition. With SetDelayed a lot of errors are reported, because the effect of following operators was not taken into account. $\endgroup$
    – Akku14
    Commented Mar 22, 2020 at 21:15
5
$\begingroup$

This works in Mathematica 12.0

Remove[soln, t, x, y]

soln[tau_] := DSolveValue[ {
   Derivative[1][x][t] == y[t], 
   Derivative[1][y][t] == -x[t], 
   x[0] == 0, y[0] == 1 }, 
   { x[tau], y[tau] }, t]

soln[t]
(*  {Sin[t], Cos[t]}  *)

soln'[t]
(*  {Cos[t], -Sin[t]}  *)

Don't know why your example doesn't work.

$\endgroup$
2
  • 2
    $\begingroup$ The solution by LouisB also works if you use `x $\endgroup$
    – murray
    Commented Mar 23, 2020 at 0:26
  • 1
    $\begingroup$ This works because it distinguishes the variable of soln (tau) from the variable used to specify the DE, so DSolveValue can still evaluate--it subsitutes the temporary expression for tau in at the end. See my answer... $\endgroup$ Commented Mar 24, 2020 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.