# How to modify the elements of a list in a loop?

I have a list with points coordinates. And I'm trying to traverse it and perform some matrix operations on each point. But I have a problem with storing modified points in the initial list instead of the original points.

Here is the complete entry point example:

(* the matrix of the linear operator of rotation around OX axis *)
rx = {
{1, 0, 0, 0},
{0, Cos[ax], -Sin[ax], 0},
{0, Sin[ax], Cos[ax], 0},
{0, 0, 0, 1}
};

(* translation matrices *)
t1 = {
{1, 0, 0, -j},
{0, 1, 0, -k},
{0, 0, 1, -l},
{0, 0, 0, 1}
};
t2 = {
{1, 0, 0, j},
{0, 1, 0, k},
{0, 0, 1, l},
{0, 0, 0, 1}
};

(* projection onto OXY plane *)
f = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 1}
};

points = {
{{100},{0},{0},{1}},
{{155},{0},{0},{1}}
};

ax = Pi/4;
j = 100;
k = 100;
l = 0;


And this is my solution to it, which I try to improve

For[i1 = 1, i1 < 3, i1++, {
item = t1 . Part[points, i1];
item = rx . item;
item = t2 .item;
item = f . item;
xP = N[Part[item, 1]];
yP = N[Part[item, 2]];
zP = N[Part[item, 3]];
homogP = N[Part[item, 4]];
Print[{xP, yP, zP, homogP}];
}];


the output is:

{{100.},{29.2893},{0.},{1.}}

{{155.},{29.2893},{0.},{1.}}


And this seems to be correct.

But if I change the For loop with the solution inspired by Alexei Boulbich

Map[{t1.#, rx.#, t2.#, f.#, N[#]} &, points];
Print[points];


I get this:

{{{100},{0},{0},{1}},{{155},{0},{0},{1}}}


That is the original list without any operations applied.

• Please give an example of the input and output that you expect. Commented Aug 16, 2014 at 21:13
• @Mr.Wizard I reworded the question
– d.k
Commented Aug 18, 2014 at 16:02
• Alexei Boulbich's code is just Map[{t1.#, rx.#, t2.#, f.#, N[#]} &, points] -- no semicolon, no Print. Commented Aug 18, 2014 at 16:11
• @MichaelE2 if I remove f#, N[#], semicolon and print in order to use the exact version of Alexei's answer, it still does not give the correct result.
– d.k
Commented Aug 18, 2014 at 16:27
• @user5693 Why doesn't your update state that, then? Print[points]; will print the original list because the list points is not modified (by either Alexei's code or yours). (Yeah, I forgot to remove the f.# etc. Oops.) Commented Aug 18, 2014 at 16:59

From your updated example this does what you desire:

N[f.t2.rx.t1.#] & /@ points

{
{{100.}, {29.2893}, {0.}, {1.}},
{{155.}, {29.2893}, {0.}, {1.}}
}


You can eliminate some redundancy by precomputing the fixed part of that operation:

m = f.t2.rx.t1;

N[m.#] & /@ points

{
{{100.}, {29.2893}, {0.}, {1.}},
{{155.}, {29.2893}, {0.}, {1.}}
}


Try this:

Map[{t1.#, rx.#, t2.#} &, points]


or like this:

Map[{t1, rx, t2}.# &, points]


which is the same.

For example, if

points = {{a1, a2, a3}, {b1, b2, b3}};


and

 t1 = {x, 0, 0};
rx = {0, y, 0};
t2 = {0, 0, z};


the operation yields:

    Map[{t1.#, rx.#, t2.#} &, points]
(*   {{a1 x, a2 y, a3 z}, {b1 x, b2 y, b3 z}}    *)


as one should expect.

• it yields some strange result. The result consists of a list with inner list which contains 36 lists, which I can assume are the results of each matrix apply, that is 12 points of the first matrix product,12 of the second one and 12 of the last. Am I correct?
– d.k
Commented Aug 16, 2014 at 19:32
• I think the OP wants to apply each transformation in turn to each point, i.e. points.Transpose[t2.rx.t1]. It's hard to tell though, when the only thing we have to go on is some code which does something else entirely. Commented Aug 17, 2014 at 15:02
• @user5693 Well, what I did is essentially the same you have written in your example, but yielding the output. The possible source of misunderstanding is (as it has been mentioned by Mr. Wizard) that you gave no examples of your data, parameters and expected output. In particular, I assumed rx, t1 and t2 to be vectors. Are they not? Then your result will, of course, differ from expected one. Commented Aug 18, 2014 at 7:50
• @AlexeiBoulbitch, I've just expanded the question
– d.k
Commented Aug 18, 2014 at 15:48