# Replacement rule for functions of two variables

In Mathematica when I use the substitutions rule (/.) If I have two variables {NN,H} each variables has 5 values and i want to substitute about the first variable of NN corresponding to the first one of H and second one of NN corresponding to the second one of H .... How can I do that please?

nn={10,5,9,20,15}

hh={1,5,3,6,2}


I want to substitute about each n with it's corresponding h in the following equation by the values of nn with it's corresponding hh from above

W=n^2+25(h^3-n*h+2*n^4)-h^2


I have tried on it as :

Do[Print[W/.{{n->nn[[i]]},{h->hh[[j]]}}],{{i,nn[[1]],nn[[5]],1},{j,hh[[1]],hh[[5]],1}}]

• Please include Mathematica code and in order to make the example minimal, reduce the 157 values to maybe 5 values. Thanks.
– Syed
Commented Apr 6, 2022 at 6:53
• BTW, two unrelated things: 1. Instead of 900*10^-9 write 900*^-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 the System namespace, and you got away using it as a variable only because Table[,,,{x,...}] implicitly scopes x lexically, like Block[{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 with Need[] et al. Use e.g. bigN instead of N for your names. Commented Apr 6, 2022 at 7:39
• That's much better, but please use the same names in both text and code. You have n, N, NN, h and H. Are n and h lists? Are they of the same length? Do you want to compute W for each pair n[[i]] and h[[i]] in parallel lists n and h, or for each possible combination of n[[i]] and h[[j]]? Please be a little bit more explicit. Commented Apr 6, 2022 at 7:45
• W /. Transpose[Thread /@ {n -> nn, h -> hh}] Commented Apr 6, 2022 at 7:53
• @LouisB: W /. {n -> nn, h -> hh} :) Commented Apr 6, 2022 at 9:27

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]]]]]


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}

• @Rabbit thanks much for spotting the typo! Fixed. Commented Apr 6, 2022 at 15:58

Do you just want MapThread?:

e.g.

MapThread[#1^2 + 25 (#2^3 - #1*#2 + 2*#1^4) - #2^2 &, {{10, 5, 9, 20,
15}, {1, 5, 3, 6, 2}}]
`

yields:

{499874, 33750, 328122, 8002764, 2530921}