# Good coding for a sequence of derivatives

People on this site keep telling me that good MMa practice avoids the use of loops.

The code below calculates the same Table of derivatives two different ways, and the one with the Do loops is much faster. I think the first, slower version is calculating the nth derivative from scratch without using the (n-1)th derivative as a starting point.

Derivative[q_, 1][y][x, v] = D[(D[y[x, v], {x, 2}] + D[y[x, v], x]^2), {x, q}]/2;
ord = 9;
Print[Timing[dgdv1 = Table[D[y[x, v], {v, i}], {i, 0, ord - 1}];]];
dgdv2 = Flatten[{y[x, v], Table[0, {i, 2, ord}]}];
Print[Timing[Do[dgdv2[[i]] = D[dgdv2[[i - 1]], v], {i, 2, ord}];]];


(*{3.931225,Null}

{2.449216,Null} *)

So how can one efficiently calculate the first several derivatives of g[x,v] wrt v without using a loop?
Bonus Question: Is there some even faster way to do this calculation?

OP's EDIT: Some commentors below were confused by the first line of my code, in which I define a derivative relationship for g[x,v]. It's not really relevant to the computation speed issue this Question is about, but here is a link for people who want to learn about defining derivatives.

• Derivative is already defined, you code has syntax problems. Commented Oct 14, 2015 at 14:18
• With NestList NestList[D[#, x] &, y[x], 10] Commented Oct 14, 2015 at 14:20
• @rhermans No, that's how you define derivatives for functions. Commented Oct 14, 2015 at 15:58
• @Jerry Guern - I am pretty much lost on the first statement and how it affects subsequent statements. Could you kindly explain the first statement and how it affects D[y[x,v], {v, i}]? Thank you Commented Oct 15, 2015 at 23:44
• @JackLaVigne The first line of my code implements a diff eq for $g[x,v]$ discussed here. I didn't discuss the meaning of it here because it's outside the scope of the question about performance tuning. Commented Oct 16, 2015 at 1:09

ord = 9;

Timing[d1 = Table[D[y[x, v], {v, i}], {i, 0, ord - 1}];][[1]]

(*  2.06537  *)


Rather than using Table, mapping onto a Range is often more efficient

Timing[
d12 = D[y[x, v], {v, #}] & /@
Range[0, ord - 1];][[1]]

(*  2.03747  *)


For a fair timing comparison, the initialization of the array should be included in the timing

Timing[
d2 = Flatten[{y[x, v], Table[0, {i, 2, ord}]}];
Do[d2[[i]] = D[d2[[i - 1]], v],
{i, 2, ord}];][[1]]

(*  1.70694  *)


With symbolic operations it can sometimes be faster to Simplify intermediate steps

d22 = Flatten[{y[x, v], Table[0, {i, 2, ord}]}];
Timing[
Do[d22[[i]] = Simplify[D[d22[[i - 1]], v]],
{i, 2, ord}];][[1]]

(*  0.307888  *)


However, for this type of problem NestList is faster (and "more Mathematica-like")

Timing[d3 = NestList[D[#, v] &, y[x, v], ord - 1];][[1]]

(*  1.58817  *)


Again using Simplify

Timing[d32 = NestList[Simplify[D[#, v]] &, y[x, v], ord - 1];][[1]]

(*  0.060246  *)


Verifying that all approaches return the same results

d1 == d12 == d2 == d22 == d3 == d32 // Simplify

(*  True  *)

• This was great, thanks. I posted a comparison of the two methods in an Answer below. With Expand performed on each derivative, the two methods had similar Timing. Commented Oct 14, 2015 at 17:35

From the OP: This is not an Answer, just an extended comment on @BobHanlon's Answer above, which I Accepted. I tried both methods on a longer run and included the Table initialization in the Timing, and I found that the methods were very similar in kernel time, but which was faster varied in different runs:

Derivative[q_, 1][y][x, v] =
D[(D[y[x, v], {x, 2}] + D[y[x, v], x]^2), {x, q}]/2;
ord = 16;
Print[Timing[
dgdv2 = Flatten[{y[x, v], Table[0, {i, 2, ord}]}];
Do[dgdv2[[i]] = Expand[D[dgdv2[[i - 1]], v]], {i, 2, ord}];]];
Print[Timing[dgdv3 = NestList[Expand[D[#, v]] &, y[x, v], ord - 1];]];
dgdv2 == dgdv3


Output from 3 runs:

(* {25.584164,Null} {25.006960,Null} True

{24.226955,Null} {24.336156,Null} True

{24.211355,Null} {24.601358,Null} True *)

• Your use of Print is unnecessary if you don't suppress the output with the final semi-colon. expr will give the same output as Print[expr]; Commented Oct 14, 2015 at 22:23