MGM.02  2D Matrix Action
 BASICS

Needs["LinearAlgebra`MatrixManipulation`"];
Needs["Graphics`Colors`"];
Off[General::spell];
Off[General::spell1];
Off[ParametricPlot3D::ppcom];
Off[ParametricPlot::ppcom];
Off[Plot::plnr];
SetOptions[Limit,Analytic->True];
$Pre = Chop;

CMView = {2.7, 1.6, 1.2};

Vector Drawer

\(\(\( (*\ \(\(:\)\(Date : \ \ Copyright\ 2001\)\), \ 
      Math\ Everywhere, \ \(\(Inc\)\(.\)\)\ 
*) \)\(
\)\( (*
Original\ Conception\ to\ create\ a\ vector\ drawer\ is\ due\ to\ Bill\ Davis . 
Current\ code\ is\ by\ Bruce\ \(\(Carpenter\)\(.\)\)
*) \)\(
\)\( (*\ \ \(\(\(:\)\(Drawbacks : \ \ Since\ the\ vectors\ are\ drawn\ out\ of\)\)\ 

      \ \ \ \ \ context\), \ 
      the\ shapes\ of\ the\ arrowheads\ are\ only\ 
\ \ \ \ \ correct\ with\ AspectRatio\ set\ to\ \(\(Automatic\)\(.\)\)
*) \)\)\)

BeginPackage["Vector3D`","Graphics`Colors`"];

Axes3D::usage = "Axes3D[a, b] creates a Graphics3D object of cartesian axes with x, y, and z running from -a/3 to a, and with axes labels b units beyond the tips of the axes.  Axes3D[a] is Axes3D[a, a/8].";

Perpend::usage = "Perpend[a] returns a unit vector which is perpendicular to the vector a.";

Arrow::usage = "Arrow[a] produces a 2 or 3 dimensional vector from the origin to a. Arrow[a, Tail -> tail] gives a vector from tail to a.";
	
Vector::usage = "Vector[a, b] gives a 2D or 3D vector from a to b.";

ArrowHead::usage = "ArrowHead[a, vec] produces an arrowhead with its tip placed at the point a, pointing in the direction of the vector vec.";

Tail::usage = "Tail -> point puts the tail of the vector at point.";

Norm::usage = "Norm[vec] returns the Euclidean length of vec.";

Normalize::usage = "Normalize[vec] returns a unit vector in the direction of vec, provided vec is nonzero.";

Aperture::usage = "Aperture is the ratio of the radius of the base to the length of the head of a vector.";

TipSize::usage = "TipSize specifies an absolute size for the inner tip length of the head of a vector.";

TipRatio::usage = "TipRatio is the ratio of the inner length of the arrowhead to the length of the shaft of a vector.";

HeadRatio::usage = "HeadRatio is the ratio of the outer length of the arrowhead to the length of the shaft of a vector.";

HeadSize::usage = "HeadSize specifies an absolute size for the head of a vector.";

ScaleFactor::usage = "ScaleFactor specifies the amount to scale a vector in length and may be either a number or a pure function.";

ZeroVectorPointSize::usage = "ZeroVectorPointSize is the size of the point used to represent a zero vector.";

Options[Vector] = Options[Arrow] = Options[ArrowHead] =
{HeadRatio -> 0.18, TipRatio -> 0.14, Aperture -> 0.3, ScaleFactor -> 1, HeadType -> Polygon, ShaftQ -> True, EdgesQ -> True, VectorColor -> RGBColor[0,0,1], ShaftWidth -> 0.005, ZeroVectorPointSize -> 0.01};
		
Begin["`Private`"];

SetOptions[ParametricPlot,AspectRatio -> Automatic];
SetOptions[Plot,AspectRatio -> Automatic];
SetOptions[Graphics,AspectRatio -> Automatic];

Axes3D[u_,v_] := 
      Graphics3D[{
            {Blue,Line[{{-u/3,0,0},{u,0,0}}]},
                    Text["x",{u + v,0,0}],
            {Blue,Line[{{0,-u/3,0},{0,u,0}}]},
                    Text["y",{0, u + v,0}],
            {Blue,Line[{{0,0,-u/3},{0,0,u}}]},
                    Text["z",{0,0,u + v}]}]; 
Axes3D[u_] := Axes3D[u,u/8];
				
Norm[a_?VectorQ] := N[Sqrt[a.a]];

Normalize[a_?VectorQ] := If[a.a == 0, a, a/Norm[a]];

Perpend[a_?VectorQ] := Normalize[{a[[2]],-a[[1]]}]/;Length[a]==2;

Perpend[a_?VectorQ]:=
    Normalize[If[a[[1]]==0,{1,0,0},{a[[2]],-a[[1]],0}]]/;
      Length[a]==3;
      
Base3D = Table[{Cos[2 k Pi/8.], Sin[2 k Pi/8.]},{k,0,8}]; 

Vector[from_?VectorQ, to_?VectorQ, opts___] := Module[
   {sq, sw, ht, hs, hr, tr, ap, sf, vc, zvps, diff = to - from, tip},
   {sq, sw, ht, hs, hr, ts, tr, ap, sf, vc, zvps} = {ShaftQ, ShaftWidth, HeadType, HeadSize, HeadRatio, TipSize, TipRatio, Aperture, ScaleFactor, VectorColor, ZeroVectorPointSize} /. {opts} /. Options[Vector];
   If[from==to, Return[Graphics[{PointSize[zvps],vc,Point[from]}]]];
   diff = If[NumberQ[N[sf]], sf diff, sf[diff]];
   tip = from + diff;
   If[NumberQ[hs], hr = hs/Norm[diff]; tr = 0.75 hr];
   If[NumberQ[ts], tr = ts/Norm[diff]];
   Graphics[{If[sq,{vc,Thickness[sw],Line[{from,tip - tr diff}]},{}],
      With[{trans = ap hr Norm[diff] Perpend[diff]},
      {vc, Thickness[sw], ht[{tip,
                   (tip - hr diff + trans),
                   (tip - tr diff),
                   (tip - hr diff - trans),tip}]}]}]
] /; Length[from]==Length[to]==2

Vector[from_?VectorQ, to_?VectorQ, opts___] := Module[
   {sq, eq, sw, hs, hr, tr,ap, sf, vc, zvps, diff = to - from, tip},
   {sq, eq, sw, hs, hr, ap, sf, vc, zvps} = {ShaftQ, EdgesQ, ShaftWidth, HeadSize, HeadRatio, Aperture, ScaleFactor, VectorColor, ZeroVectorPointSize} /. {opts} /. Options[Vector];
   If[from==to, Return[Graphics3D[{PointSize[zvps],vc,Point[from]}]]];
   diff = If[NumberQ[N[sf]], sf diff, sf[diff]];
   tip = from + diff;
   If[NumberQ[hs], hr = hs/Norm[diff]];
   tr = hr/2;
   Graphics3D[{If[sq,{vc,Thickness[sw],Line[{from,tip-tr diff}]},{}], If[eq, {}, EdgeForm[]], {SurfaceColor[vc],
      With[{temp = Perpend[diff]},
      Polygon[Append[#,tip]]& /@ Partition[(tip - hr diff + #)&/@((ap hr Norm[diff] Base3D) . {temp,Normalize[Cross[temp,diff]]}),2,1]]}}]
] /; Length[from]==Length[to]==3


Arrow[a_, Tail->b_, opts___] := Vector[b,a+b,opts]

Arrow[a_, opts___] := Vector[Table[0,{Length[a]}],a,opts]

ArrowHead[a_, b_, opts___] := Vector[a-b,a,ShaftQ->False,opts];

End[];

EndPackage[];
Null

Graphics`Colors`GosiaGreen = 
        RGBColor[0,  0.392187,  0];

ThreeAxes[u,v]

ThreeAxes[u_, v_] := 
        Graphics3D[{{Blue, Line[{{-u, 0, 0}, {u, 0, 0}}]}, 
            Text["x", {u + v, 0, 0}], {Blue, 
              Line[{{0, -u, 0}, {0, u, 0}}]}, 
            Text["y", {0, u + v, 0}], {Blue, 
              Line[{{0, 0, 0}, {0, 0, u}}]}, 
            Text["z", {0, 0, u + v}]}];
ThreeAxes[u_] := ThreeAxes[u, (u/8)];
ThreeAxes::"usage" = "ThreeAxes[a,b] makes a standard cartesian \
axis graphics object with x, y, and z running from -a to a, and with axis \
labels b units beyond the tips of the axes.  ThreeAxes[a] is \
ThreeAxes[a,a/8].";

B.1)  2D matrix hits via rows and via columns:
              A.{x, y}={row1.{x, y},row2.{x, y}}
and
              A.{x, y}=x column1 + y column2
give you the same results

B.1.a.i) Rows

Here is a sample 2D matrix:

A= (({{1.6, 0.4}, {1.5, 2.9}}));
MatrixForm[A]

What do folks mean when they talk about the horizontal rows of A?

Look at A again:

A= (({{1.6, 0.4}, {1.5, 2.9}}));
MatrixForm[
      A]

Folks say that the first horizontal row of A is
         row1 = {1.6, 0.4}
and the second horizontal row of A is
          row2 = {1.5, 2.9}
Mathematica can fish them out for you:

row1 = A[[1]]

row2 = A[[2]]

B.1.a.ii) Columns

Here is a new sample 2D matrix:

A=(({{-1.7, 1.4}, {0.6, -4.8}}));
MatrixForm[A]

What do folks mean when they talk about the vertical columns of A?

Look at A again:

A=(({{-1.7, 1.4}, {0.6, -4.8}}));
MatrixForm[A]

Folks say that the first vertical column of A is
         column1 = {-1.7, 0.6}
and the second horizontal vertical column of A is
          column2 = {1.4, -4.8}
Mathematica can fish them out for you:

column1  =  Transpose[A][[1]]

column2  =  Transpose[A][[2]]

B.1.a.iii) Matrix hits  via rows and via columns:
              A.{x, y}={row1.{x, y},row2.{x, y}}
and
              A.{x, y}=x column1 + y column2
give you the same result

Here is a new sample 2D matrix:

A=(({{1.5, 3.}, {0.6, -1.7}}));
MatrixForm[A]

Here is Mathematica's calculation of what you get when you hit A on a cleared point {x,y}

Clear[x, y];
A . {x, y}

Explain what happened in terms of the rows and columns of A.

Rows:

Look at A again:

A=(({{1.5, 3.}, {0.6, -1.7}}));
MatrixForm[A]

To see how to get A.{x,y} in terms of rows,look at A.{x,y} again:

A . {x, y}

Fish out the horizontal rows of A:

row1  =  A[[1]]

row2  =  A[[2]]

In terms of rows, A.{x,y} is given by

A.{x, y}={row1.{x, y},row2.{x, y}}

A.{x, y} == {(row1.{x, y}),(row2.{x, y})}

Columns:

To see how to get A.{x,y} in terms of columns, look at A

MatrixForm[A]

Look at A.{x,y} again:

A . {x, y}

Fish out the vertical columns of A:

column1  =  Transpose[A][[1]]

column2  =  Transpose[A][[2]]

In terms of columns, A.{x,y} is given by
     A.{x, y}=x column1 + y column2:

A.{x, y}==x column1 + y column2

B.1.b) Hitting a matrix on the unit circle

What do folks like to do with matrix hits?

Folks like to hit matrices on curves.
A sample:
Here's the unit circle centered at {0.0}:

Clear[x, y, 
        t];
{x[t_], y[t_]} = {Cos[t], Sin[t]};
{tlow, thigh} = {-π, π};

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], Indigo}},AspectRatio -> Automatic,AxesLabel -> {"x", "y"},PlotLabel -> "Before the hit"];

Here's a matrix A:

A =(({{0.5, 0.9}, {-0.3, 0.4}}));
MatrixForm[A]

When you hit a point {x[t],y[t]} on the unit circle with A you get:

A . {x[t], y[t]}

See how  A.{x[t],y[t]} plots out:

hitcurveplot = ParametricPlot[A . {x[t], y[t]},{t, tlow, thigh},
PlotStyle -> {{Thickness[0.01], GosiaGreen}},AspectRatio -> Automatic,
AxesLabel -> {"x", "y"},PlotLabel -> "After the hit with A"];

After you hit the unit circle with A, you get a tilted ellipse.
Try it for random matrices A:

A =(({{Random[Real, {-1, 1}], Random[
                    Real, {-1, 1}]}, {Random[Real, {-1, 1}], Random[
                    Real, {-1, 1}]}}));
hitcurveplot = ParametricPlot[A . {x[t], y[t]},{t, tlow, thigh},
PlotStyle -> {{Thickness[0.01], GosiaGreen}},AspectRatio -> Automatic,
AxesLabel -> {"x", "y"},PlotLabel -> "After the hit with random matrix A"];
"Here A is" MatrixForm[A]

You get an ellipse every time.

B.2) Matrix Action movies: 
                  
Hitting with a 2D matrix on curves and assessing the result

B.2.a.i) Hitting a curve with a matrix

Here's an ordinary sine wave plotted in true scale:

Clear[x, y, t];
{x[t_], y[t_]} = {t, 3 Sin[2 t]};
\(\({tlow, thigh} = {\(-π\), π};\)
\)
curveplot = 
        ParametricPlot[{x[t], y[t]}, {t, tlow, thigh}, 
          PlotStyle -> {{Thickness[0.01], CadmiumOrange}}, 
          AspectRatio -> Automatic, 
          AxesLabel -> {"x", "y"}, 
          PlotLabel -> "Before the hit"];

Hit every point on this curve with the 2D matrix 
       A = (({{0.5`, 0.9`}, {-0.8`, 1.0}})) 
and plot the result. 
Describe what you see.

When you hit a point {x[t], y[t]} on the plotted curve you get:

A=  (({{0.5, 0.9}, {-0.8, 1.0}})) ;
A . {x[t], y[t]}

When you hit every point {x[t], y[t]} on the plotted curve and plot the result you get:

A=  (({{0.5, 0.9}, {-0.8, 1.0}})) ;
hitcurveplot = ParametricPlot[A.{x[t], y[t]},{t, tlow, thigh},
PlotStyle -> {{Thickness[0.01], NavyBlue}},AspectRatio -> Automatic,
AxesLabel -> {"x", "y"},PlotLabel -> "After the matrix hit"];

See both one after the other:

ranger  =  5;
Show[curveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];
Show[hitcurveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];

At this stage, it's hard to describe in precise terms what the hit by A did. But in general terms, you can say that the hit by A simultaneously deformed the curve a bit and then rotated it quite a bit.

B.2.a.ii) Hitting the unit circle with a matrix

Here's the unit circle plotted in true scale:

Clear[x, y, 
        t];
{x[t_], y[t_]} = {Cos[t], Sin[t]};
{tlow, thigh} = {0, 2 π};

ranger = 2;
curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], CadmiumOrange}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                  ranger}},AspectRatio -> Automatic,AxesLabel -> {"x", "y"},PlotLabel -> "Before the hit"];

Hit this every point on this curve with the 2D matrix 
       A = (({{0.4, -0.7`}, {0.7, 1.30000000000000004`}}))
and plot the result. 
Describe what you see.

When you hit a point {x[t],y[t]} on the plotted curve you get:

A=(({{0.4, -0.7}, {0.7, 1.3}}));
A . {x[t], y[t]}

When you hit every point {x[t],y[t]} on the plotted curve and plot the result you get:

hitcurveplot=ParametricPlot[A . {x[t], y[t]},{t, tlow, thigh},
		PlotStyle -> {{Thickness[0.01], 
                  GosiaGreen}},AspectRatio -> Automatic,PlotRange -> {{-ranger, ranger}, {-ranger, 
                  ranger}},AxesLabel -> {"x", "y"},PlotLabel -> "After the matrix hit"];

An ellipse!

See both one after the other:

ranger  =  2;
Show[curveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];
Show[hitcurveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];

At this stage, it's hard to describe precisely what the hit by A did. 
But in general terms, you can say that hit by A simultaneously deformed the curve and maybe A rotated it too.

B.2.a.iii) Matrix action movies

Look at the two plots from part i):

ranger  =  2;
Show[curveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];
Show[hitcurveplot, 
        PlotRange -> {{-ranger, ranger}, {-ranger, 
              ranger}}];

Surely the hit by A deformed the circle, but how can you get a feeling for whether A also rotated the circle?

Color code the points and watch where they go this way:

Clear[x, y, 
        t];
{tlow, thigh} = {0, 2 π};
ranger = 
        2;
{x[t_], y[t_]} = {Cos[t], Sin[t]};

pointcolor[t_] = 
        RGBColor[0.5 (Cos[t] + 1), 0.5 (Sin[t] + 1), 0];
jump = ((thigh - tlow)/12);

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], Blue}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                    ranger}},AxesLabel -> {"x", "y"},PlotLabel -> "Before the hit",DisplayFunction -> Identity];

pointplot = 
          Table[Graphics[{pointcolor[t], PointSize[0.035], 
                Point[{x[t], y[t]}]}], {t, tlow, thigh - jump, jump}];

Show[curveplot, pointplot, 
        DisplayFunction -> $DisplayFunction];

To see what happens after the hit by A, copy paste and edit the plotting instructions above, replacing all
       {x[t],y[t]}'s with A.{x[t],y[t]}:

hitcurveplot=ParametricPlot[A . {x[t], y[t]},{t, tlow, thigh},
		PlotStyle -> {{Thickness[0.01], 
                    GosiaGreen}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                    ranger}},AxesLabel -> {"x", "y"},PlotLabel -> "After the matrix hit",DisplayFunction -> Identity];

hitpointplot = 
          Table[Graphics[{pointcolor[t], PointSize[0.035], 
                Point[A . {x[t], y[t]}]}], {t, tlow, thigh - jump, jump}];

Show[hitcurveplot, hitpointplot, 
        DisplayFunction -> $DisplayFunction];

The following graphic tries to explain what the color coding means:

\(\(actionarrows = 
        Table[Arrow[A . {x[t], y[t]} - {x[t], y[t]}, 
            Tail -> {x[t], y[t]}, VectorColor -> pointcolor[t], 
            HeadSize -> 0.25], {t, tlow, thigh - jump, 
            jump}];\)
\)
Show[curveplot, hitcurveplot, pointplot, hitpointplot, actionarrows, 
        PlotLabel -> "Action plot", 
        DisplayFunction -> $DisplayFunction];

In this plot, each arrow points from a point 
          {x[t],y[t]} 
on the circle to the point 
          A.{x[t],y[t]}
that results from hitting {x[t],y[t]} with A.
As you can see, there is a strong hint of a rotation, but there is also a big stretch and squeeze.
Here's a review:

\(\(Show[curveplot, pointplot, 
        DisplayFunction -> $DisplayFunction];\)
\)
\(\(Show[curveplot, pointplot, actionarrows, 
        PlotLabel -> "Action plot", 
        DisplayFunction -> $DisplayFunction];\)
\)
Show[hitcurveplot, hitpointplot, 
        DisplayFunction -> $DisplayFunction];

Matrix action.

B.2.a.iv) Another matrix action movie

Go with this 2D matrix:
                A = (({{1.77`, 0.85`}, {-1.79`, 0.9`}})).

Make an action movie and analyze what a hit with this matrix does to the unit circle.

Copy, paste and edit to make an action movie:

A=  (({{1.77, 0.85}, {-1.79, 0.9}}));
Clear[x, y, 
        t];
{tlow, thigh} = {0, 2 π};
ranger = 
        2.3;
{x[t_], y[t_]} = {Cos[t], Sin[t]};

pointcolor[t_] = 
        RGBColor[0.5 (Cos[t] + 1), 0.5 (Sin[t] + 1), 0];
jump = ((thigh - tlow)/16);

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], Blue}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                    ranger}},AxesLabel -> {"x", "y"},PlotLabel -> "Before the hit",DisplayFunction -> Identity];

pointplot = 
          Table[Graphics[{pointcolor[t], PointSize[0.035], 
                Point[{x[t], y[t]}]}], {t, tlow, thigh - jump, jump}];

hitcurveplot=ParametricPlot[A . {x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], GosiaGreen}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                    ranger}},AxesLabel -> {"x", "y"},PlotLabel -> "After the hit",DisplayFunction -> Identity];

hitpointplot = 
          Table[
            Graphics[{pointcolor[t], PointSize[0.035], 
                Point[A . {x[t], y[t]}]}], {t, tlow, thigh - jump, jump}];

actionarrows = 
          Table[Arrow[A . {x[t], y[t]} - {x[t], y[t]}, 
              Tail -> {x[t], y[t]}, VectorColor -> pointcolor[t], 
              HeadSize -> 0.25], {t, tlow, thigh - jump, jump}];

Show[curveplot, pointplot, 
          DisplayFunction -> $DisplayFunction];

Show[curveplot, pointplot, actionarrows, 
          PlotLabel -> "Action plot", 
          DisplayFunction -> $DisplayFunction];

Show[hitcurveplot, hitpointplot, 
        DisplayFunction -> $DisplayFunction];

There is a huge hint of simultaneous rotation and there is an equally huge hint of a big stretch, bigger in one direction than another.

B.2.a.v) Matrix Action movie code

Shorten up the code needed to make a matrix action movie.

Here is a modest attempt; you might be able to do better.
First enter the matrix A and the parametrization for {x[t],y[t]} and run:

A =(({{Random[Real, {-1, 1}], Random[
                    Real, {-1, 1}]}, {Random[Real, {-1, 1}], Random[
                    Real, {-1, 1}]}}));
Clear[x, y, t, hitplotter, hitpointplotter, pointcolor, 
        actionarrows, matrix2D];
{tlow, thigh} = {0, 2 π};

ranger = 3;
{x[t_], y[t_]} = {Cos[t], Sin[t]};

pointcolor[t_] = 
        RGBColor[0.5 (Cos[t] + 1), 0.5 (Sin[t] + 1), 0.4];
jump = ((thigh - tlow)/12);

hitplotter[matrix2D_]:=ParametricPlot[matrix2D . {x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{Thickness[0.01], GosiaGreen}},PlotRange -> {{-ranger, ranger}, {-ranger, 
                    ranger}},AxesLabel -> {"x", "y"},DisplayFunction -> Identity];

hitpointplotter[matrix2D_]:=Table[
            Graphics[{pointcolor[t], PointSize[0.035], 
                Point[matrix2D . {x[t], y[t]}]}], {t, tlow, thigh - jump, 
              jump}];

actionarrows[matrix2D_]:=Table[Arrow[matrix2D . {x[t], y[t]} - {x[t], y[t]},Tail -> {x[t], y[t]},VectorColor -> pointcolor[t],HeadSize -> 0.25],{t, tlow, thigh - jump, jump}];

before=Show[hitplotter[IdentityMatrix[2]],hitpointplotter[IdentityMatrix[2]],PlotLabel -> "Before",DisplayFunction -> $DisplayFunction];

Show[before,actionarrows[A],PlotLabel -> "Action plot",DisplayFunction -> $DisplayFunction];

Show[hitplotter[A],hitpointplotter[A],PlotLabel -> "After the hit",DisplayFunction -> $DisplayFunction];

You can change the matrix A:

A=(({{2.3, -1.1}, {-1.1, 1.0}}));

before = 
          Show[hitplotter[IdentityMatrix[2]], 
            hitpointplotter[IdentityMatrix[2]], 
            PlotLabel -> "Before", 
            DisplayFunction -> $DisplayFunction];

arrows  = 
          Show[before, actionarrows[A], PlotLabel -> "Action plot", 
            DisplayFunction -> $DisplayFunction];

after  = 
        Show[hitplotter[A], hitpointplotter[A], 
          PlotLabel -> "After the hit", 
          DisplayFunction -> $DisplayFunction];

Play.

B.3)  Making your own 2D matrices: 
The identity matrix (({{1, 0}, {0, 1}}))  and the xy-stretchers (({{xstretch, 0}, {0, ystretch}}))

B.3.a) The 2D identity matrix  (({{1, 0}, {0, 1}}))

Here's the 2D identity matrix:

MatrixForm[IdentityMatrix[2]]

(({{1, 0}, {0, 1}}))

Why do nearly all folks like to call this matrix by the name "identity matrix?"

Folks like to call this matrix by the name identity matrix because when you hit {x,y} with this matrix, absolutely nothing new happens:

Clear[x, y];
IdentityMatrix[2] . {x, y}

Hitting with the identity matrix is just like multiplying by 1.
This happens because
            (({{1, 0}, {0, 1}})).{x,y} = x{1,0} + y{0,1} = {x,0} + {0,y} = {x,y}.

B.3.b.i) Diagonal matrices: The xy-stretcher matrices  (({{xstretch, 0}, {0, ystretch}}))

Here's a cleared 2D diagonal matrix:

\(Clear[a, d]; 
DiagonalMatrix[{a, d}]\)

MatrixForm[DiagonalMatrix[{a, d}]]

Nearly all folks like to call this matrix by the name "diagonal matrix because all its non-zero entries lie on what the same folks call the main diagonal.
Why do some folks (especially clued-in eager folks such as you) also like to call 2D diagonal matrices by the name xy-stretchers?

Here's a 2D diagonal matrix: and an action movie showing what it does to the unit circle:

xstretch = 3.0;
ystretch = 2.0;
A = 
        DiagonalMatrix[{xstretch, ystretch}];
MatrixForm[A]

And here's an action movie showing what a hit with A does to the unit circle:

Clear[x, y, t, hitplotter, hitpointplotter, pointcolor, actionarrows, 
        matrix2D];
\(\({tlow, thigh} = {0, 2\ π};\)
\)
ranger = 3;
{x[t_], y[t_]} = {Cos[t], Sin[t]};
pointcolor[t_] = 
        RGBColor[0.5 (Cos[t] + 1), 0.5 (Sin[t] + 1), 
          0];
\(\(jump = \(thigh - tlow\)\/12;\)
\)
\(\(hitplotter[matrix2D_] := 
        ParametricPlot[matrix2D . {x[t], y[t]}, {t, tlow, thigh}, 
          PlotStyle -> {{Thickness[0.01], Blue}}, 
          PlotRange -> {{\(-ranger\), ranger}, {\(-ranger\), ranger}}, 
          AxesLabel -> {"x", "y"}, 
          DisplayFunction -> Identity];\)
\)
\(\(hitpointplotter[matrix2D_] := 
        Table[Graphics[{pointcolor[t], PointSize[0.035], 
              Point[matrix2D . {x[t], y[t]}]}], {t, tlow, thigh - jump, 
            jump}];\)
\)
\(\(actionarrows[matrix2D_] := 
        Table[Arrow[matrix2D . {x[t], y[t]} - {x[t], y[t]}, 
            Tail -> {x[t], y[t]}, VectorColor -> pointcolor[t], 
            HeadSize -> 0.25], {t, tlow, thigh - jump, 
            jump}];\)
\)
\(\(before = 
        Show[hitplotter[IdentityMatrix[2]], 
          hitpointplotter[IdentityMatrix[2]], PlotLabel -> "Before", 
          DisplayFunction -> $DisplayFunction];\)
\)
\(\(Show[before, actionarrows[A], PlotLabel -> "Action plot", 
        DisplayFunction -> $DisplayFunction];\)
\)
Show[hitplotter[A], hitpointplotter[A], 
        PlotLabel -> "After the hit", 
        DisplayFunction -> $DisplayFunction];

When you hit the unit circle with:

MatrixForm[A]

you stretched out all measurements 
        along the x-axis by a factor of xstretch = 3
and all measurements 
        along the y-axis by a factor of ystretch = 2.
        
That's why it's hard to resist the urge to call diagonal matrices like this one by the name "xystretchers.".

Check it out for cleared stretch factors:

Clear[xstretch, ystretch];
A = 
        DiagonalMatrix[{xstretch, ystretch}];
MatrixForm[A]

Clear[x, y];
A . {x, y}

This happens because

(({{xstretch, 0}, {0, ystretch}})).{x,y} = x{xstretch,0} + y{0,ystretch}
                                                   = { xstretch  x, 0} +y {0,ystretch y} 
                                                    = {xstretch  x  , ystretch y}.

B.3.b.ii) Making your own xy-stretchers

Make an xy-stretcher matrix that stretches by a factor of 1.5 in the direction of the x-axis and shrinks by a factor of 0.4 direction of the y-axis.
Show off your answer with an action movie.

The matrix you want is:

{xstretch, ystretch} = {1.5, 0.4};
A = DiagonalMatrix[{xstretch, ystretch}];
MatrixForm[A]

Check what it does to {x,y}:

A . {x, y}

Hits with A stretch by a factor of 1.5 in the direction of the x-axis and shrinks by a factor of 0.4 in the direction of the y-axis.
Just what it was made to do.
See this matrix do its work:

ranger = Max[{xstretch, ystretch, 1}]
Clear[x, y, t];
\(\({tlow, thigh} = {0, 2\ π};\)
\)
{x[t_], y[t_]} = {Cos[t], Sin[t]};
\(\(before = 
        Show[hitplotter[IdentityMatrix[2]], 
          hitpointplotter[IdentityMatrix[2]], PlotLabel -> "Before", 
          DisplayFunction -> $DisplayFunction];\)
\)
\(\(Show[before, actionarrows[A], PlotLabel -> "Action plot", 
        DisplayFunction -> $DisplayFunction];\)
\)
Show[hitplotter[A], hitpointplotter[A], 
        PlotLabel -> "After the hit", 
        DisplayFunction -> $DisplayFunction];

In this case, one of the stretching factors is actually a shrinking factor.
Play with your own choices of xstretch and ystretch.

B.4) Making your own 2D matrices: 
Using perpendicular frames to make matrices for hanging, aligning and rotating.
To align, you load the perpendicular frame into the rows
                aligner  =  (({{perpframe[1]→}, {perpframe[2]→}}) ).
To hang, you load the perpendicular frame into the columns
                 hanger = (({{perpframe[1]
, perpframe[2]}, {↓, ↓}})).
To rotate, you hang on right hand perpendicular frame

B.4.a.i) Making  aligner matrices to align on the x and y axes

Here's an ellipse hung on a perpendicular frame:

s = 0.34;
Clear[perpframe];
{perpframe[1], 
            perpframe[2]} = {{Cos[s], Sin[s]}, {Cos[s + (π/2)], 
              Sin[s + (π/2)]}};

Clear[x, y, t];
{x[t_], y[t_]} = 
          1.5 Cos[t] perpframe[1] + 0.9 Sin[t] perpframe[2];

ranger = 1.5;
{tlow, thigh} = {0, ((9 π)/8)};

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{CadmiumOrange, Thickness[0.01]}},DisplayFunction -> Identity];

frameplot = {Table[
              Arrow[perpframe[k], Tail -> {0, 0}, 
                VectorColor -> Indigo, HeadSize -> 0.2], {k, 1, 
                2}], Graphics[Text["perpframe[1]", 0.6 perpframe[1]]], 
            Graphics[Text["perpframe[2]", 0.6 perpframe[2]]]};

before = 
        Show[frameplot, curveplot, 
          PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
          Axes -> True, AxesLabel -> {"x", "y"}, 
          PlotLabel -> "Before"];

Now make a matrix (called aligner) 
               aligner = (({{perpframe[1]→}, {perpframe[2]→}})) 
with
        perpframe[1] in the first horizontal row
 and 
        perpframe[2] in the second horizontal row.
   
Here's how you do it:

aligner  =  {perpframe[1], perpframe[2]};
MatrixForm[aligner]

Compare

perpframe[1]
perpframe[2]

Sure enough, 
         perpframe[1] is in the first horizontal row of aligner
and 
         perpframe[2] is in the second horizontal row of aligner.
Now see what happens when you hit this matrix on all points {x[t],y[t]} of the plotted curve:

hitcurveplot = ParametricPlot[aligner . {x[t], y[t]},{t, tlow, thigh},
PlotStyle -> {{GosiaGreen,  Thickness[0.01]}},DisplayFunction -> Identity];

xyunitvectors  =  {Arrow[{1, 0}, Tail -> {0, 0}, 
              VectorColor -> Indigo, 
              HeadSize -> 0.2], 
Arrow[{0, 1}, 
              Tail -> {0, 0}, VectorColor -> Indigo, 
              HeadSize -> 0.2]};


\(after\  = \ 
        Show[xyunitvectors\ , 
\ \ \ \ \ \ \ \ \ \ \ \ \ hitcurveplot, 
\ \ \ \ \ \ \ \ \ \ \ \ \ PlotRange -> {{\(-ranger\), ranger}, {\(-ranger\), 
                ranger}}, 
\ \ \ \ \ \ \ \ \ \ \ \ \ Axes -> True, 
          AxesLabel -> {"x", "y"}, 
\ \ \ \ \ \ \ \ \ \ \ \ \ PlotLabel -> "Aligned on xy-axes"];\)

Review both plots:

Show[before];
Show[after];

The hit with aligner aligns the curve on the x and y axes with 
    {1, 0} pointing out the positive x-axis playing the former role of perpframe[1]
and with 
     {0, 1} pointing out the positive y-axis playing the former role of perpframe[2]
Explain why this was guaranteed to happen no matter what perpendicular frame you start with.

The  matrix (called aligner) 
               aligner = (({{perpframe[1]→}, {perpframe[2]→}})) 
was made with
        perpframe[1] in the first horizontal row
 and 
        perpframe[2] in the second horizontal row.

According to B.1) when you hit {x[t], y[t]} with

aligner = (({{perpframe[1]→}, {perpframe[2]→}}))

you get

aligner .{x[t],y[t} =    (({{perpframe[1]→}, {perpframe[2]→}})).{x[t], y[t]}

=  {({x[t], y[t]}. perpframe[1]),({x[t], y[t]}. perpframe[2])}

These are the coordinates of {x[t],y[t]} relative to the perpendicular frame.

And, according to the last lesson, this exactly what you what you plot to take a curve {x[t], y[t]} and align it on the x and y -axes with  
      {1, 0} pointing out the positive x-axis playing the former role of perpframe[1]
and with 
     {0, 1} pointing out the positive y-axis playing the former role of perpframe[2].
See it happen for some random perpendicular frames and random curves:

s = 
        Random[Real, {-(π/2), (π/2)}];
Clear[
        perpframe];
{perpframe[1], 
            perpframe[2]} = {{Cos[s], Sin[s]}, {Cos[s + (π/2)], 
              Sin[s + (π/2)]}};

Clear[x, y, t];
{x[t_], y[t_]} =  
        0.8  (Cos[t]  - 1) Cos[Random[Integer, {1, 3}] t] 
            perpframe[1] + 
          0.7  Sin[Random[Integer, {1, 5}] t]^3 perpframe[
              2];
ranger = 2;
{tlow, thigh} = {0, 2 π};

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{CadmiumOrange, Thickness[0.01]}},DisplayFunction -> Identity];

frameplot = {Table[
              Arrow[perpframe[k], Tail -> {0, 0}, 
                VectorColor -> Indigo, HeadSize -> 0.2], {k, 1, 
                2}], Graphics[Text["perpframe[1]", 0.6 perpframe[1]]], 
            Graphics[Text["perpframe[2]", 0.6 perpframe[2]]]};

before = 
          Show[frameplot, curveplot, 
            PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
            Axes -> True, AxesLabel -> {"x", "y"}, 
            PlotLabel -> "Before"];

aligner = {perpframe[1], perpframe[2]};
hitcurveplot=ParametricPlot[aligner . {x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{GosiaGreen, Thickness[0.01]}},DisplayFunction -> Identity];
xyunitvectors  =  {Arrow[{1, 0}, Tail -> {0, 0}, 
              VectorColor -> Indigo, 
              HeadSize -> 0.2], 
Arrow[{0, 1}, 
              Tail -> {0, 0}, VectorColor -> Indigo, 
              HeadSize -> 0.2]};

after = 
        Show[xyunitvectors, hitcurveplot, 
          PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
          Axes -> True, AxesLabel -> {"x", "y"}, 
          PlotLabel -> "Aligned on xy-axes"];

Rerun a couple of times, always noticing that the long axis of the curve lines up on the x-axis.
That's because the long axis of the original curve lined up on perpframe[1].

B.4.b) Making  hanger matrices to hang curves on perpendicular frames

Here's a curve  shown with a perpendicular frame:

Clear[x, y, t];
{x[t_], y[t_]} = {0.8 (1  -  Cos[t]) Cos[t], 
          0.9 Sin[t]^5};
ranger = 2;
\(\({tlow, thigh} = {0, 2\ π};\)
\)
\(\(curveplot = 
        ParametricPlot[{x[t], y[t]}, {t, tlow, thigh}, 
          PlotStyle -> {{CadmiumOrange, Thickness[0.01]}}, 
          DisplayFunction -> Identity];\)
\)
s = -0.5;
Clear[perpframe];
\(\({perpframe[1], 
          perpframe[2]} = {{Cos[s], Sin[s]}, {Cos[s + π\/2], 
            Sin[s + π\/2]}};\)
\)
\(\(frameplot = {Table[
            Arrow[perpframe[k], Tail -> {0, 0}, 
              VectorColor -> Indigo, HeadSize -> 0.2], {k, 1, 2}], 
          Graphics[Text["perpframe[1]", 0.6\ perpframe[1]]], 
          Graphics[
            Text["perpframe[2]", 0.6\ perpframe[2]]]};\)
\)
before = 
        Show[frameplot, curveplot, 
          PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
          Axes -> True, AxesLabel -> {"x", "y"}, 
          PlotLabel -> "Before"];

Now make a matrix (called hanger) 
          hanger = (({{perpframe[1]
, perpframe[2]}, {↓, ↓}})) 
with
        perpframe[1] in the first vertical column
 and 
        perpframe[2] in the second  vertical column.
   
Here's how you do it:

hanger = Transpose[ {perpframe[1], perpframe[2]}];
MatrixForm[
      hanger]

Compare

perpframe[1]
perpframe[2]

Sure enough, 
         perpframe[1] is in the first vertical column of hanger
and 
         perpframe[2] is in the  second vertical column of hanger.
         
Now see what happens when you hit this hanger matrix on all points {x[t],y[t]} of the plotted curve:

hitcurveplot = ParametricPlot[hanger . {x[t], y[t]},{t, tlow, thigh},
PlotStyle -> {{GosiaGreen,  Thickness[0.01]}},DisplayFunction -> Identity];

\(after\  = \ 
        Show[frameplot, 
\ \ \ \ \ \ \ \ \ \ \ \ \ hitcurveplot, 
\ \ \ \ \ \ \ \ \ \ \ \ \ PlotRange -> {{\(-ranger\), ranger}, {\(-ranger\), 
                ranger}}, 
\ \ \ \ \ \ \ \ \ \ \ \ \ Axes -> True, 
          AxesLabel -> {"x", "y"}, 
\ \ \ \ \ \ \ \ \ \ \ \ \ PlotLabel -> "Hung on plotted frame"];\)

Review both plots:

Show[before];
Show[after];

The hit with hanger hangs the ellipse on the plotted perpendicular frame with 
     perpframe[1] playing the former role of {1, 0} pointing out the positive x-axis 
and with 
    perpframe[2] playing the former role {0, 1} pointing out the positive y-axis.
Explain why this was guaranteed to happen no matter what perpendicular frame you started with.

The  matrix (called hanger) 
               hanger = (({{prepframe[1]
, perpframe[2]}, {↓, ↓}}))
was made with
        perpframe[1] in the first vertical column
 and 
        perpframe[2] in the second vertical column

According to B.1) when you hit {x[t], y[t]} with

hanger = (({{prepframe[1]
, perpframe[2]}, {↓, ↓}}))

you get

hanger.{x[t],y[t} =    (({{prepframe[1]
, perpframe[2]}, {↓, ↓}})) .{x[t], y[t]}

=  x[t]  perpframe[1] + y[t] perpframe[2].

and this is  exactly the formula used in the last lesson to take a curve {x[t], y[t]} and hang it on   
               {perpframe[1], perpframe[2]}
with
    perpframe[1] playing the former role of {1, 0}pointing out the positive x-axis 
and with 
    perpframe[2] playing the former role {0, 1} pointing out the positive y-axis.
    
    See it happen for some random perpendicular frames and random curves:

s = 
        Random[Real, {-(π/2), (π/2)}];
Clear[
        perpframe];
{perpframe[1], 
          perpframe[2]} = {{Cos[s], Sin[s]}, {Cos[s + (π/2)], 
            Sin[s + (π/2)]}};
hanger  =  Transpose[ {perpframe[1], perpframe[2]}]; 

Clear[x, y, 
        t];
{x[t_], 
          y[t_]} =  {0.8  (Cos[t]  - 1) Cos[
              Random[Integer, {1, 3}] t], 
          0.7  Sin[0.7  Random[Integer, {1, 3}] t]};
ranger = 
        2;
{tlow, thigh} = {0, 2 π};

curveplot=ParametricPlot[{x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{CadmiumOrange, Thickness[0.01]}},DisplayFunction -> Identity];

frameplot = {Table[
              Arrow[perpframe[k], Tail -> {0, 0}, 
                VectorColor -> Indigo, HeadSize -> 0.2], {k, 1, 
                2}], Graphics[Text["perpframe[1]", 0.6 perpframe[1]]], 
            Graphics[Text["perpframe[2]", 0.6 perpframe[2]]]};

before = 
          Show[frameplot, curveplot, 
            PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
            Axes -> True, AxesLabel -> {"x", "y"}, 
            PlotLabel -> "Before"];

aligner = {perpframe[1], perpframe[2]};
hitcurveplot=ParametricPlot[hanger . {x[t], y[t]},{t, tlow, thigh},PlotStyle -> {{GosiaGreen, Thickness[0.01]}},DisplayFunction -> Identity];

after = 
        Show[frameplot, hitcurveplot, 
          PlotRange -> {{-ranger, ranger}, {-ranger, ranger}}, 
          Axes -> True, AxesLabel -> {"x", "y"}, 
          PlotLabel -> "Hung on perp frame"];

Rerun a couple of times, always noticing that the long axis of the ellipse lines up with perpframe[1].
That's because the long axis of the original ellipse lined up on the x-axis.

B.5)  Matrix multiplication: 
A hit with A.B is the same a hit with B followed by a hit with A .
To get the first column of A.B , you hit A on the first column of B. 
To get the second column of A.B , you hit A on the second column of B. 
Why you shouldn't expect that A.B = B.A

B.5.a.i) A hit with A.B is the same a hit with B followed by a hit with A

Here is a cleared 2D matrix:

Clear[a, b, c, d];
A=(({{a, b}, {c, d}}));
MatrixForm[A]

Here's another cleared 2D matrix:

Clear[r, s, t, v];
B=(({{r, s}, {t, v}}));
MatrixForm[B]

Here is Mathematica's calculation of A times B:

MatrixForm[A . B]

Maybe not what you expected.
Why do almost all folks agree that this is the right way to multiply matrices?

Folks all across the world have agreed on this way of matrix multiplication so that a hit with A.B is the same as a hit with B followed by a hit with A.
Watch it happen:

Clear[x, y];
hitbyB=B . {x, y}

hitbyBfollowedbyhitbyA=Expand[A.hitbyB]

hitbyAB=Expand[(A . B).{x, y}]

Expand[(A . B).{x, y}]==Expand[A.(B.{x, y})]

B.5.a.ii) What matrix multiplication is good for

What's matrix multiplication good for?

You can do two hits at once. By multiplying A.B and then hitting, you get the same result as hitting by B and then hitting by A.

Sometimes you see what A.B does in terms of what A and B do.
To see more on this, go in to part iii)

B.5.a.iii) To get the first column of A.B, you hit A on the first column of B.
                 To get the second column of A.B, you hit A on the second column of B

Given two 2D matrices A and B, explain how to calculate A.B by hitting A on the columns of B.

To get the first column of A.B, you hit A on the first column of B. 
To get the second column of A.B, you hit A on the second column of B.

Try this out on these cleared 2D matrices A and B:

Clear[a, b, c, d, r, s, t, v];
A=(({{a, b}, {c, d}}));
B=(({{r, s}, {t, v}}));

"A is" MatrixForm[A]

\("B is"\ MatrixForm[B]\)

The first vertical column of B is

Clear[Bcol];
Bcol[1]  =  {r, t}

The second vertical column of B is

Bcol[2]  =  {s, v}

Here's what you get when you hit A on the first column of B:

A.Bcol[1]

That;s the same as the vector that's in first column of A.B:

MatrixForm[A . B]

Here's what you get when you hit A on the second column of B:

A.Bcol[2]

That's the same as the vector that is in the second column of A.B:

MatrixForm[A . B]

This confirms this rule:
To get the first column of A.B, you hit A on the first column of B. 
To get the second column of A.B, you hit A on the second column of B.

B.5.a.iv) The action of A.B in terms of the action of B and the action of A

Here's a hanger matrix:

s = 0.6;
{perpframe[1], perpframe[2]} = 
        N[{{Cos[s], Sin[s]}, {Cos[s + (π/2)], 
              Sin[s + (π/2)]}}];
hanger = Transpose[{perpframe[1], perpframe[2]}];
MatrixForm[
      A]

Here's an xystretcher matrix

xstretch  =  2.0;
ystretch =  0.8;
xystretcher = DiagonalMatrix[{xstretch, ystretch}];
MatrixForm[xystretcher]

Put A = hanger and B = xystretcher and calculate A.B:

A = hanger; 
B  =  xystretcher;
MatrixForm[A . B]

Predict what a hit with A.B does to the unit circle centered at {0,0} and test out your prediction with an action movie.

Because hits with B stretch along the x and y axes, a hit with B will stretch the unit circle into and ellipse.
When you follow the hit by B with a hit with the hanger matrix A, you gotta get a tilted ellipse. 

Try it out:

Clear[x, y, t, hitplotter, hitpointplotter, pointcolor, actionarrows, 
        matrix2D];
{tlow, thigh} = {0, 2 π};
ranger = Max[{xstretch, ystretch}];
\(\({x[t_], y[t_]} = {Cos[t], Sin[t]};\)
\)
\(\(pointcolor[t_] = 
        RGBColor[0.5\ \((Cos[t] + 1)\), 0.5\ \((Sin[t] + 1)\), 
          0];\)
\)
\(\(jump = \(thigh - tlow\)\/12;\)
\)
\(\(hitplotter[matrix2D_] := 
        ParametricPlot[matrix2D . {x[t], y[t]}, {t, tlow, thigh}, 
          PlotStyle -> {{Thickness[0.01], Blue}}, 
          PlotRange -> {{\(-ranger\), ranger}, {\(-ranger\), ranger}}, 
          AxesLabel -> {"x", "y"}, 
          DisplayFunction -> Identity];\)
\)
\(\(hitpointplotter[matrix2D_] := 
        Table[Graphics[{pointcolor[t], PointSize[0.035], 
              Point[matrix2D . {x[t], y[t]}]}], {t, tlow, thigh - jump, 
            jump}];\)
\)
\(\(actionarrows[matrix2D_] := 
        Table[Arrow[matrix2D . {x[t], y[t]} - {x[t], y[t]}, 
            Tail -> {x[t], y[t]}, VectorColor -> pointcolor[t], 
            HeadSize -> 0.25], {t, tlow, thigh - jump, 
            jump}];\)
\)
\(\(before = 
        Show[hitplotter[IdentityMatrix[2]], 
          hitpointplotter[IdentityMatrix[2]], PlotLabel -> "Before", 
          DisplayFunction -> $DisplayFunction];\)
\)
\(\(Show[before, actionarrows[A . B], 
        PlotLabel -> "Action plot", 
        DisplayFunction -> $DisplayFunction];\)
\)
Show[hitplotter[A . B], hitpointplotter[A . B], 
        PlotLabel -> "After the hit", 
        DisplayFunction -> $DisplayFunction];

Exactly as predicted.
You can view this in three stages:

stage1 = Show[before]

Hitting this circle with A.B is the same as hitting the circle with B and then hitting the result with A. Here's what you get when you hit the circle with B:

stage2 = 
        Show[hitplotter[B], hitpointplotter[B], 
          PlotLabel -> "After the hit with B", 
          DisplayFunction -> $DisplayFunction];

Here's what you get when you hit the ellipse with A:

stage3 = 
        Show[hitplotter[A . B], hitpointplotter[A . B], 
          PlotLabel -> "After the hit with A.B", 
          DisplayFunction -> $DisplayFunction];

B.5.a.v)  Why you can't expect that A.B = B.A

Stay with the same matrices A and B as in the last part and look at the result of hitting the unit circle with B.A

BAhitplot = 
        Show[hitplotter[B . A], hitpointplotter[B . A], 
          PlotLabel -> "After the hit by B.A", 
          DisplayFunction -> $DisplayFunction];

Compare what you get when you hit the unit circle with A.B

ABhitplot = 
        Show[hitplotter[A . B], hitpointplotter[A . B], 
          PlotLabel -> "After the hit by B.A", 
          DisplayFunction -> $DisplayFunction];

See them both:

Show[ABhitplot, BAhitplot, PlotLabel -> " A.B and B.A", 
        PlotRange -> All];

Describe what you see and explain why it happened and explain what it means.

Take another look:

Show[ABhitplot, BAhitplot, 
        PlotLabel -> "Both hits"];

One of these ellipses results from hitting the unit circle with A.B; the other results from hitting the unit circle with B.A.
Because these ellipse are not the same, you are left with the vivid conclusion that 
          A.B ≠ B.A:

MatrixForm[A . B]

MatrixForm[B . A]

This is natural because:
-> The hit with B stretches out along the x and y -axes.
-> The hit with A rotates.
Consequently: 
-> The hit with A.B stretches and then rotates, 
but
-> The hit with B.A rotates and then stretches. 
And the results are not the same.