Group Abstract Group Abstract

Message Boards Message Boards

A problem with List and Vector

GROUPS:
First, a=1;b=2;c=3; {a,b}+c will be {a+c,b+c}, i.e.{4,5}. This is the Distributive property of List.
Second, a={1,1}; b={1,2}; a+b will be {1+1, 1+2} i.e. {2, 3}. This is Plus between Vectors.
But the problem comes when I try to combine these two features.
a = {1, 1}; b = {1, 2}; c = {1, 2};
{a + c, b + c}
{a, b} + c
Result:
{{2, 3}, {2, 4}} (* Right *)
{{2, 2}, {3, 4}} (* Wrong *)
it seems that Mathematica interprets {a, b} as a matrix here.
How can I fix this problem?
I can fix this simple problem by Plus[#, c]&/@{a,b}
But I want a universal solution. Anyone can help?
POSTED BY: Moon Liu
Answer
9 months ago
I see no problem at all. It is all consistent behavior. It is based on element by element operation.

When you write
{a, b} + {x, y}
Then the first element "a" is added to the first element "x". Then the second element "b" is added to the second element "y".
{a + x, b + y}
This you first case, which you say is right. (simply let a=1,b=1,x=1,y=2.

Now lets look at the second case, where now "a" happend to be a list of 2 elements. No problem. The same thing will happen
{{a1, a2}, {b1, b2}} + {x, y}
Mathematica will now do the same thing. It will add "x" to the first element which happend to be {a1, a2}.  Giving
{a1 + x, a2 + x}
which I am sure you agree is correct. Next it go to the next element, and adds "y" to {b1, b2} giving {b1 + y, b2 + y} so you end up with
{{a1 + x, a2 + x}, {b1 + y, b2 + y}}
Replace a1=1, a2=1,b1=1,b2=2,x=1,x=2 and you get the second case.

And if you had 3 elements in the list, the same thing will happen. Each term is added to each other term, one by one.
{{a1, a2, a2}, {b1, b2, b3}} + {x, y}
(*   {    {a1 + x, a2 + x, a2 + x}    ,      {b1 + y, b2 + y, b3 + y}    }  *)
POSTED BY: Nasser
Answer
9 months ago
Thanks for your reply. You're right.
{{a1, a2}, {b1, b2}} + {x, y} == {{a1 + x, a2 + x}, {b1 + y, b2 + y}}
and this is indeed a consistent behavior.
However, in my case, a different task is concerned.
{{a1, a2}, {b1, b2}} [op] {x, y} == {{a1 + x, a2 + y}, {b1 + x, b2 + y}}
How can I deal with it? Which is the right ?

More precisely, in the first caseMathematica regards {a1, a2} and x in the same level.
In my case, however, I want {a1, a2} and {x, y} in the same level.

The following code may illustrate my problem
 OffsetPoint[a_, b_] := a + b;
 a = {1, 1}; b = {1, 2}; c = {1, 2};
 A = OffsetPoint[a, c]
 B = OffsetPoint[b, c]
 {A, B} = OffsetPoint[{a, b}, c]; (* I just want to simplify my code here *)
 A
 B
 (* Result: *)
 {2, 3}
{2, 4}
{2, 2}(* But I got wrong answer here *)
{3, 4}
POSTED BY: Moon Liu
Answer
9 months ago
Not sure if this is exactly what you're looking for, but you can use Thread:

a = {1, 1}; b = {1, 2}; c = {1, 2};
Thread[{a, b} + c]
Answer
9 months ago
Thanks for your reply. I've tried Thread, but it seems not to be the answer.
a = {a1, a2}; b = {b1, b2}; c = {c1, c2};

Thread[{a, b} + c]
(*
Result:
{{a1 + c1, b1 + c2}, {a2 + c1, b2 + c2}}
But I want {{a1 + c1, a2 + c2}, {b1 + c1, b2 + c2}}
*)

Actually the closest answer I've tried is Table.
 a = {a1, a2}; b = {b1, b2}; c = {c1, c2};
 ans1 = Table[Plus[x, y], {x, {a}}, {y, {c}}]   (* First discrepancy: apparently listed input {a,b} needs curly braces, but the simply input "a" ought not to need them. *)
 ans2 = Table[Plus[x, y], {x, {a, b}}, {y, {c}}]
 (*
 Result:
 {{{a1 + c1, a2 + c2}}}
 {{{a1 + c1, a2 + c2}}, {{b1 + c1, b2 + c2}}}
 One step further, Flatten is needed to get the right answer.
 *)
Flatten[ans1, 2] (* Second discrepency: flatten levels differ *)
Flatten[ans2, 1]
(*
Result:
{a1 + c1, a2 + c2}
{{a1 + c1, a2 + c2}, {b1 + c1, b2 + c2}}
*)
The reason why I don't see Table as the best answer is that, as you can see, I'm not satisfied with the discrepancy between simple input and Listed input.

I think my purpose is simple. I just want {a, b} + c always equals {a + c, b + c}. But this relation doesn't hold if a, b and c are vectors. TAT
POSTED BY: Moon Liu
Answer
9 months ago
 Clear["`*"];
 
 a = {1, 1}; b = {3, 2}; ref1 = {1, 2}; ref2 = {3, 2};
 OffsetPoint[a_, b_] := a + b;
 OffsetPointEx[a_, b_] := Module[{bool1, bool2, para1, para2, ans},
    para1 = a; para2 = b;
    bool1 = If[Depth[a] == 2, 1, 0];
    bool2 = If[Depth[b] == 2, 1, 0];
    If[bool1 == 1, para1 = {a}]; (* fix the first discrepancy *)
   If[bool2 == 1, para2 = {b}];
   ans = Table[Plus[x, y], {y, para2}, {x, para1}]; (* Notice the sequence here *)
   Flatten[ans, bool1 + bool2] (* fix the second discrepancy *)
   ];
oA = OffsetPoint[a, ref1];
oB = OffsetPoint[b, ref1];
oC = OffsetPoint[a, ref2];
oD = OffsetPoint[b, ref2];
{{oA, oB}, {oC, oD}}
OffsetPointEx[a, ref1]
OffsetPointEx[{a, b}, ref1]
OffsetPointEx[{a, b}, {ref1, ref2}]
OffsetPointEx[{a, b}, #] & /@ {ref1, ref2}
(*
Result:
{{{2, 3}, {4, 4}}, {{4, 3}, {6, 4}}}
{2, 3}
{{2, 3}, {4, 4}}
{{{2, 3}, {4, 4}}, {{4, 3}, {6, 4}}}
{{{2, 3}, {4, 4}}, {{4, 3}, {6, 4}}}
*)
I wrote this. It's right but really complicated and unpractical!
POSTED BY: Moon Liu
Answer
9 months ago
Well! Maybe Mathematica doesn't  provide the "best" way to deal with this problem. It's the user's job to come up with solution of it.
My solution: 1) MapThread; 2) Table
 Clear["`*"];
 
 a = {a1, a2}; b = {b1, b2}; ref1 = {x1, y1}; ref2 = {x2, y2};
 oA1 = Plus[a, ref1];
 oA2 = Plus[a, ref2];
 oB1 = Plus[b, ref1];
 oB2 = Plus[b, ref2];
 {{oA1, oA2}, {oB1, oB2}}
 MapThread[Plus, {{{a, a}, {b, b}}, {{ref1, ref2}, {ref1, ref2}}}]
Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]
(*
Result:
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
*)
These are my provisional solutions. For the moment, Table is the best choice.

By the way, MapThread also has its merit.
{oA1, oA2, oB1, oB2} = MapThread[Plus, {{a, a, b, b}, {ref1, ref2, ref1, ref2}}]
(*
Result:
{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}, {b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}
*)
You don't need to Flatten the result and four points are directly assigned to variables.
With Table, you have to use Flatten or more curly braces.
{oA1, oA2, oB1, oB2} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]~Flatten~1
{{oA1, oA2}, {oB1, oB2}} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]
POSTED BY: Moon Liu
Answer
9 months ago
I think I see what you are trying to do now. Generally I would just use this:
(# + c) & /@ {a, b}
For your more expanded version, you can use this:
Plus @@@ Tuples[{{a, b}, {ref1, ref2}}]
Or 'Outer', which is the function version of 'Table' in this case:
Flatten[Outer[Plus, {a, b}, {ref1, ref2}, 1], 1]
Answer
9 months ago
Wow! Thanks you very very much! These are exactly what I want!
 a = {ax, ay}; b = {bx, by}; ref1 = {x1, y1}; ref2 = {x2, y2};
 
 Plus @@@ Tuples[{{a, b}, {ref1, ref2}}]
 Outer[Plus, {a, b}, {ref1, ref2}, 1]~Flatten~1
 (* Result:
 {{ax + x1, ay + y1}, {ax + x2, ay + y2}, {bx + x1, by + y1}, {bx + x2,
  by + y2}}
 {{ax + x1, ay + y1}, {ax + x2, ay + y2}, {bx + x1, by + y1}, {bx + x2,
  by + y2}}
*)
The combination of @@@ and Tuples is much simpler than Table. It will greatly simplify my code! emoticon
Thanks again!
POSTED BY: Moon Liu
Answer
9 months ago