# Why is held expression evaluated?

Context: I'm studying non-linear dynamics. As part of a bigger problem, I'd like to generate lists of the form {{deq, ic1}, {deq, ic2}, ...}, where deq is a differential equation and ic are initial conditions.

EDIT: (Use r instead of t for the tuples as per @Kuba's suggestion *)

ClearAll["Global*"];
deq = x''[t] == x[t] - x[t]^3 + x[t]^2 + Cos[t];
r = Tuples[{Hold@deq, {{x[0] == 0, x'[0] == 0}, {x[0] == 0, x'[0] == 1}}}]
NDSolve[First@r, {x, x'}, {t, 0, 1000}]


I have the following related questions:

1. Why do I need to Hold[] deq at the first place ? If I don't use it, Tuples[] will "break" deq in == and combine all the {lhs, rhs} with all the ic's. It's due to the fact that deq isn't list which is what Tuples[] expects. See @Kuba's answer.
2. Why when later on I pass the result of to NDSolve[], Hold@deq is evaluated without me releasing it first ? I checked the documentation of Hold[] and it says that this should happen only when the held expression is of the form f[args] and UpValues have been defined for f. I don't mind that it does, but I'm trying to understand the logic.
3. How would using Unevaluated@deq differ compared to Hold@deq ?

Ad 0. First of all, t in deq is not scoped so if you are assigning Tuples to t, the mess will occur.

Ad 1. You don't need Hold. From the documentation of Tuples:

Tuples[{list_1, list_2, ...}] generates a list of all possible tuples whose i-th element is from list_i.

There is no list in deq so Equal is splitted. The proper syntax is:

Tuples[{{deq}, {{x[0] == 0, x'[0] == 0}, {x[0] == 0, x'[0] == 1}}}]


Ad 2. Hold is not released, it just isn't there.

Again, referring to the quote above, since there is no list Tuples is taking elements from the first head, which is Hold, so it takes deq outside and couple with elements from initial conditions list.

Take a look:

all = Tuples[{Hold[deq], {{x[0] == 0, x'[0] == 0}, {x[0] == 0, x'[0] == 1}}}];
NDSolve[First@all, x[t], {t, 0, 1000}]

{{x[t]->InterpolatingFunction[{{0.,383.709}},<>][t]}}

all = Tuples[{{Hold@deq}, {{x[0] == 0, x'[0] == 0}, {x[0] == 0, x'[0] == 1}}}];
NDSolve[First@all, x[t], {t, 0, 1000}]

NDSolve[{Hold[deq],{x[0]==0,(x^\[Prime])[0]==0}},x[t],{t,0,1000}]


Ad 3. i think this question may be skipped in context of the previous answers.

• Thanks @Kuba! I will fix the code to not use 't' for Tuples[]`. Also thanks for the hint on how to properly use the latter. Pretty lame PEBKAC. That answers 1. What about 2+3 ? Commented Jan 4, 2014 at 22:41
• @Zet ok, see my edit.
– Kuba
Commented Jan 4, 2014 at 22:55
• Ok, now I get it. The whole question is an epic pebkac, but I won't delete it just so that you get the bonus points you earned. Thanks! Commented Jan 4, 2014 at 23:03
• @Zet Incidentally you wouldn't be able to delete the question anyway because of the existence of a positively-voted answer. Also, while you may see this as a case of PEBKAC (I love that) it is nevertheless the kind of mistake that is easy to make with Mathematica and this Q&A may quite likely have value to others. The power that makes Mathematica fun for experienced users also makes for some real head-scratchers! Try to remember that because "everything is an expression" many list functions will happily operate upon or destructure expressions with arbitrary heads. Commented Jan 5, 2014 at 9:09
• @Mr.Wizard & Zet well said, also, not only new users may find such behaviour inconsistent. In case of wrong syntax they may expect error or output=input. It's not the case here even though there is no info about working with any head in usage documentation. Only in Generalisations and Extensions section, but I feel it is not enough and so poorly made (in terms of logic and consistency) documentation (in general) is one of the big problems when working with MMA. The more that Wolfram is trying to sell it as user friendly software.
– Kuba
Commented Jan 5, 2014 at 9:30