Let's start simply:
nn = {10, 20, 30, 40, 50};
hh = {0, 1, 2, 3, 4};
w = n + 2 h;
1. The correct iterator syntax for Do
and other iterating constructs in MMA is {i, start, end, step}
to evaluate the iterated form for i
= start
, i
=start + step
, i = start + 2 step
, ... until i <= end
is no longer true. You have values, not indexes in the iterator; this is a mistake.
Commonly used shorthands for this form of the iterator are:
{i, start, end} is same as {i, start, end, 1}
{i, end} is same as {i, 1, end, 1}
Also, two or more iterators are meant to do nested iteration, the second iterating its all values for each value of the first. You can nest as many as required in most constructs. In your approach, you'll get a surprising result of 25 lines printed, not 5, because two iterators define a cross product of their ranges:
Do[Print[w /. {n -> nn[[i]], h -> hh[[j]]}], {i, 5}, {j, 5}];
10
12
14
... 20 more lines ...
56
58
Since your lists are parallel, use just one iterator:
Do[Print[w /. {n -> nn[[i]], h -> hh[[i]]}], {i, 5}];
10
22
34
46
58
Now the result is as expected.
2. Prefer constructs that return results to imperative constructs, like Do[Print[...]]
. Imperative forms are useful only in narrow circumstances. When using Table[]
instead, you can assign its result to a variable and reuse it.
In:= Table[w /. {n -> nn[[i]], h -> hh[[i]]}, {i, 5}]
Out= {10, 22, 34, 46, 58}
You can always Print[]
it later if you want, once per line or per print cell, depending on a frontend and the stream where Print output is sent:
In:= Table[w /. {n -> nn[[i]], h -> hh[[i]]}, {i, 5}]
Out= {10, 22, 34, 46, 58}
In:= Print /@ %
(/@
is an operator form of Map
, and the %
refers to a last output.)
Another nice display construct is Column[]
, which puts a column of aligned results into a single output cell:
Table[w /. {n -> nn[[i]], h -> hh[[i]]}, {i, 5}] // Column
3. The most powerful approach is to use the fact that all operators in your expression for W
are Listable
. Listable function take lists, operate on each element, and return a list of results. You do not need any iterating form at all!
In:= {10, 20} + {1, 2}
Out= {11, 22}
In:= w /. {n -> nn, h -> hh}
Out= {10, 22, 34, 46, 58}
MMA applies the expression to each list element. All operators that you are using in the expression assigned to W
, namely Plus
, Times
and Power
, are Listable.
In:= ww = n^2 + 25 (h^3 - n*h + 2*n^4) - h^2;
ww /. {n -> nn, h -> hh}
Out= {500100, 7999924, 40499596, 127999266, 312499084}
If in doubt, look at the FullForm
of an expression:
In:= ww // FullForm
Out= Plus[Times[-1,Power[h,2]],Power[n,2],Times[25,Plus[Power[h,3],Times[-1,h,n],Times[2,Power[n,4]]]]]
4. Define functions.
The ReplaceAll operator (/.
) may be tricky. A cleaner technique is to make ww
a function. Functions lexically scope their input variables, so there is less room for an error, and fewer global variables. This does the same as 3. above, but with a function:
In:= ww[n_, h_] := n^2 + 25 (h^3 - n*h + 2*n^4) - h^2;
ww[nn, hh]
Out= {500100, 7999924, 40499596, 127999266, 312499084}
Neither n
and h
"escape" outside, nor they are affected by external definitions of the same variables. Examples of other scoping constructs are Table
, Do
, For
and other iteration forms which scope their iterator variables, and Block
, which scopes any symbol you want. Look how the function is unaffected by n
being defined outside of it:
In:= n = "Strawberry";
ww[n_, h_] := n^2 + 25 (h^3 - n*h + 2*n^4) - h^2;
ww[nn, hh]
n =.
Out= {500100, 7999924, 40499596, 127999266, 312499084}
900*10^-9
write900*^-9
for the scientific form input; 2. Don't use variables starting with an uppercase letter, they are reserved. In particular,N
is a function defined in theSystem`
namespace, and you got away using it as a variable only becauseTable[,,,{x,...}]
implicitly scopesx
lexically, likeBlock[{x},..]
. You'll run into all sorts of amazing errors if you reuse MMA-defined symbols, and it's an open set, changing with versions and namespaces you import withNeed[]
et al. Use e.g.bigN
instead ofN
for your names. $\endgroup$n
,N
,NN
,h
andH
. Aren
andh
lists? Are they of the same length? Do you want to computeW
for each pairn[[i]]
andh[[i]]
in parallel listsn
andh
, or for each possible combination ofn[[i]]
andh[[j]]
? Please be a little bit more explicit. $\endgroup$W /. Transpose[Thread /@ {n -> nn, h -> hh}]
$\endgroup$W /. {n -> nn, h -> hh}
:) $\endgroup$