Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given

expr = u == a1 + a2 x + a3 y;

and

uRep = {u1, u2, u3};
xyRep = {{x1, y1}, {x2, y2}, {x3, y3}};

I'd like to generate 3 equations

{u1 == a1 + a2 x1 + a3 y1, 
 u2 == a1 + a2 x2 + a3 y2, 
 u3 == a1 + a2 x3 + a3 y3}

By replacing u with u1,u2,u3 at a time, and at same time, replace x with x1,x2,x3 and the same for y

Currently I do this using MapThread with explicit Function like this:

MapThread[Function[{z1, z2}, eq1 /. {u -> z1, x -> z2[[1]], y -> z2[[2]]}], {uRep, xyRep}]

But I was wondering what the syntax would be do it using pure function. I tried

MapThread[eq1 /. {u -> #1[[1]], x -> #2[[1]], y -> #2[[2]]} &, {uRepl, xyRepl}]
  eq1 /. {u -> #1[[1]], x -> #2[[1]], y -> #2[[2]]} & @@@ {uRepl, xyRepl}

and few others. They all produce errors due to wrong slot # mapping.

I am happy with the Function solution, but was wondering what the syntax will be using pure function. (I looked at many related questions, but could not find solution to apply for this case, I am sure I missed something)

share|improve this question
    
Nasser, as a matter of personal curiosity may I know why you did not Accept my answer. To my eye it is the nicest way, and I would like to know why you do not like it. I ask this sincerely. –  Mr.Wizard Jun 6 at 5:56
    
@Mr.Wizard all the answers were great and I +1 them all and would have accepted them all if I could. When all answers are good and I do not know which to accept, I normally accept the one which people have voted most to at the time. That is all. if there are two answers with same votes and both equally good, I flip a coin. Thanks again for your excellent answers as always. –  Nasser Jun 6 at 23:34
    
You are welcome, as always. Thanks for satisfying my curiosity. –  Mr.Wizard Jun 7 at 2:49
add comment

4 Answers 4

up vote 4 down vote accepted
MapThread[ expr /. {u -> #1, x -> #2[[1]], y -> #2[[2]]} &, {uRep, xyRep}] 

works as expected. So do

(expr /. {u -> #1, x -> #2[[1]], y -> #2[[2]]}) & @@@  Transpose[{uRep, xyRep}]

and

(expr /. Thread[{u, x, y} -> ##]) & /@ (Flatten /@ Transpose[{uRep, xyRep}])

All three give

{u1 == a1 + a2 x1 + a3 y1, u2 == a1 + a2 x2 + a3 y2, u3 == a1 + a2 x3 + a3 y3}
share|improve this answer
    
ah! I was close. I was doing #1[[1]] all along for the first argument instead of just #1, since I also used #2[[...]] for the other argument! I did not notice [[...]] is not needed for the first one (now I know what the error meant :) –  Nasser Jun 4 at 2:16
    
@Nasser, the error message should have given a hint :) –  kguler Jun 4 at 2:17
    
That is why I think the Function method was more clear. Arguments are defined using normal symbols, and in fixed location and position, so less chance of making a syntax error, and it looks more natural than using pure function with its # this and #1 that. I am trying to learn to use Function[...] more now than pure functions, even though it takes few more keystrokes to write it. –  Nasser Jun 4 at 2:27
add comment

May this would be easier

list = MapThread[Prepend, {xyRep, uRep}];
#1 == a1 + a2 #2 + a3 #3 & @@@ list

(*
{u1 == a1 + a2 x1 + a3 y1, u2 == a1 + a2 x2 + a3 y2, 
 u3 == a1 + a2 x3 + a3 y3}
*)
share|improve this answer
add comment

I propose destructuring:

MapThread[
  {##} /. {u_, {x_, y_}} -> expr &,
  {uRep, xyRep}
]
{u1 == a1 + a2 x1 + a3 y1, u2 == a1 + a2 x2 + a3 y2, u3 == a1 + a2 x3 + a3 y3}

Note the express use of Rule rather than the normal RuleDelayed, which allows expr to evaluate.

If expr will be input in the form given I feel this is the cleanest approach.

See also: Is there any way to define pure functions with optional arguments?

share|improve this answer
add comment

Here are two more ways;

uRep = {u1, u2, u3};
xyRep = {{x1, y1}, {x2, y2}, {x3, y3}};

f = #1 == a1 + a2 #2 + a3 #3 &;

MapThread[f[#1, #2[[1]], #2[[2]]] &, {uRep, xyRep}]

MapThread[f, {uRep, Sequence @@ Transpose[xyRep]}]

Both of the MapThread expressions give

{u1 == a1 + a2 x1 + a3 y1, u2 == a1 + a2 x2 + a3 y2, u3 == a1 + a2 x3 + a3 y3}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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