7
$\begingroup$

With reference to the answer by @Bill to the question posted here, I am trying to understand the following three lines

  u = RandomReal[{0, 1}, {20, 5}]
  v = Map[({x, y, z, a, b} = #; {x, y, z, a, b, 1 - a - b}) &, u]
  w = Take[Select[v, ({x, y, z, a, b, c} = #;  x^2 + y^2 + z^2 <= 1 && x + y - 1 <= z <= -x + y + 1 && z >= -x - y - 1) &], 3]

Clearly u generates $20 \times 5$ array of random (real) numbers between 0 and 1. But I do not understand how Map[({x, y, z, a, b} = #; {x, y, z, a, b, 1 - a - b}) &, u] is working. Both v and w involve something like ({}=#;{})&. What does this operation do?

$\endgroup$
2
  • $\begingroup$ Map[function,listOfData] is going to "do" that function to each element in that list of data and give back a list of results. In this case the function assigns values to x,y,z,a,b from the five items in each element of the data. Then it creates a new 6 item list made up of the first 5 items and the calculated value for c. And then the third line will select all the items that satisfy the conditions and then Take will take just the first 3 of those. (That was my code answering your question, by the way) If you need a longer more detailed answer I can try to do that. $\endgroup$
    – Bill
    Commented Aug 11, 2022 at 21:00
  • $\begingroup$ You might find the function traceview2 in this answer interesting when trying to understand the evaluation sequence of a code. I tried it with the problem you gave by surrounding the whole code like TraceView2[line1;line2;line3]. It might take some time learning how to navigate through the cells. $\endgroup$ Commented Aug 12, 2022 at 0:32

1 Answer 1

7
$\begingroup$

Effectively, {a,b}=... sets both a and b simultaneously to the corresponding elements of the right side (see Set). So for example:

{a, b} = {1, 2};

a
(* 1 *)

b
(* 2 *)

Now, in your example, we can look at what the function (the (...)&, see also Function) gets as argument using Echo:

u = RandomReal[{0, 1}, {3, 5}];
v = Map[({x, y, z, a, b} = Echo@#; {x, y, z, a, b, 1 - a - b}) &, u]

(* {0.524485,0.374012,0.209276,0.447658,0.534618} *)
(* {0.945336,0.0270697,0.206729,0.00877572,0.881564} *)
(* {0.725822,0.263445,0.160514,0.247397,0.798175} *)
(* {{0.524485, 0.374012, 0.209276, 0.447658, 0.534618, 
  0.0177245}, {0.945336, 0.0270697, 0.206729, 0.00877572, 0.881564, 
  0.10966}, {0.725822, 0.263445, 0.160514, 0.247397, 
  0.798175, -0.0455723}} *)

So it just gets one row from the 20x5 matrix, as expected. This now means that {x,y,z,a,b} get set to those 5 values. The second part is then the result of the function, so using the just set values for a,b,x,y,z, we compute the list {x,y,z,a,b,1-a-b}. This is then returned from the function (see also CompoundExpression).

That being said, I would have rewritten the line as follows:

v = Apply[Function[{x, y, z, a, b}, {x, y, z, a, b, 1 - a - b}], u, {1}];

This applies (see Apply) the function taking 5 arguments (called x,y,z,a,b) to each row of the matrix, and then computes the same expression as before. I just find it a lot more explicit in what's going on, and it doesn't needlessly modify global variables.

The third line follows the same logic, so we can use a similar strategy to rewrite it for improved readability:

w = Take[Select[v, Apply@Function[{x, y, z, a, b, c}, x^2 + y^2 + z^2 <= 1 && x + y - 1 <= z <= -x + y + 1 && z >= -x - y - 1]], 3]

Notice here that I used the operator form of Apply. This effectively converts the function Function[{x,y,z,a,b,c},...] which takes 6 arguments into a function that takes a list of length 6 as a single argument. This is required since Select will pass the lists of length 6 as a single argument to the filter criterion. The Apply then effectively splits this list into separate arguments.

$\endgroup$
2
  • $\begingroup$ Thanks @Lukas Lang, how can I write ListPlot[Map[({x,y,z,a,b,c}=#;{f[x,y,z,a,b,c], Sqrt[x^2+y^2+z^2]})&,w]] in simpler form as you wrote those v and w? $\endgroup$
    – seeker
    Commented Aug 12, 2022 at 14:37
  • $\begingroup$ @seeker ListPlot[Map[Apply@Function[{x,y,z,a,b,c}, {f[...],...}], w]] or equivalently ListPlot[Apply[Function[{x,y,z,a,b,c},{f[...],...}],w,{1}]] $\endgroup$
    – Lukas Lang
    Commented Aug 12, 2022 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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