New Mathematica Tools for Linear Algebra

by
Stephen Hughes, Elizabeth Koopman, Shari Prevost, and Barry Tesman
Department of Mathematics and Computer Science
Dickinson College
Carlisle, PA

Mathematica in Education
Vol.3 No.3
Summer 1994
(c) TELOS/Springer-Verlag

Introduction

Dickinson College is integrating Mathematica-based assignments (either as in-class or homework assignments) into many of its core mathematics classes.  In the three years since we began this process, we have seen that Mathematica can be a powerful learning tool for students in undergraduate mathematics classes.  However, most students are not familiar with Mathematica's language and capabilities.  In addition, it can be very difficult for them to learn both Mathematica and the concepts of the mathematics at the same time.  This motivated us to design packages that allow students to concentrate on the mathematical concepts rather than Mathematica's syntax and programming language.  In this article, we will discuss two new Mathematica packages.  The first package, ElementaryRowOps, is designed to help reduce the frustration most of us encounter while putting a matrix into reduced row echelon form, but retain the strategy used to place a matrix in this form.  The second package, PictureThis, allows the user to visualize the effects of a linear transformation (represented by a 2 ´ 2 matrix) on a set of points in the plane.

ElementaryRowOps

After students become familar with the basic algebraic operations associated with matrices, they are introduced to the notion of the reduced row echelon form of a matrix.  As the course progresses they learn that this form of a matrix contains a wealth of information about the original matrix.  Before the value of the reduced row echelon form is unveiled to the students, they spend time learning how to take a matrix and put it into its reduced row echelon form via the elementary row operations.  Row reducing matrices is often a tedious process and it is easy to make arithmetic errors.  This very often leads to unnecessary frustration.

Mathematica can be used to relieve this frustration:  Mathematica can automatically put a matrix into its reduced row echelon form by using the command RowReduce.  For example if we take the matrix M,

M={{0,0,1,5},{0,2,0,2},{1,2,0,4}};
MatrixForm[M]

and ask Mathematica to give us the reduced row echelon form for M, we obtain:

MatrixForm[RowReduce[M]]

With this Mathematica function at our disposal you might well ask why we should ask our students to perform the row reduction by hand.  Our response would be to ask, "What if we are  required to keep track of the elementary row operations used along the way to obtain the reduced row echelon form?"  For example, this would be necessary if we needed to write our invertible matrix as a product of elementary matrices.  In this case Mathematica's RowReduce let's us verify that we have obtained the correct reduced row echelon form, but it doesn't give us a clue as to how we got there.  In the event our "hand-computed" reduced row echelon form for our matrix is deemed incorrect by Mathematica, we are sentenced to either repeat the entire process (with no guarantee of a correct result) or perform a painstaking check of the arithmetic at each step.  Such mistakes fuel frustration and divert attention from the actual concept of row reduction.  This motivated us to create a Mathematica package, ElementaryRowOps, to perform the elementary row operations.

The ElementaryRowOps package contains three commands:  RowOp1, RowOp2, and RowOp3.

?RowOp1

?RowOp2

?RowOp3

Using the matrix M introduced above, we demonstrate how the ElementaryRowOps package can be used to obtain the reduced row echelon form for M:

MatrixForm[M]

RowOp1[M,1,3]

RowOp2[%,1/2,2]

RowOp3[%,-2,2,1]

As seen above, students who use this package for row reduction are still responsible for understanding the strategy required to put a matrix into its reduced row echelon form.  However, this package offers a tool which allows students to keep track of the elementary row operations performed and to verify the arithmetic involved in each step.  The code for ElementaryRowOps can be found at the end of this article.

PictureThis

When we teach students about real-valued functions of one variable, we spend large amounts of time studying the graph of the function.  As students go on and take third semester calculus, the graphs associated with functions of two variables become harder and harder to visualize, but we still spend a good portion of the semester drawing and classifying the resulting surfaces.  Then in linear algebra we introduce a new type of function:  the linear transformation.  We emphasize the algebraic properties of these maps and spend little, if no time, discussing the geometric properties.  The Mathematica package PictureThis was written to help students "discover" the geometric properties of linear transformations from Â2 to Â2.  The usage statement for PictureThis is displayed below.

?PictureThis

For example students could be invited to determine the effects of applying a linear transformation T: Â2 ® Â2 represented by matrices of the form

where r is any nonzero real number.  To further aid the student in this process, one can pre-define regions in the plane so that the student is not faced with the cumbersome task of selecting and typing in large sets of points.  We will use four such subsets of the plane entitled Region1, Region2, Region3, and Region4.  (The code for these lists may be found at the end of the article.)

The student could be asked to replace r in the first matrix by the scalars 2, 1/2, and -3, and describe in each case how the linear transformation T(x)=Ax changes each of the four given regions.  The tool they are to use is PictureThis.  For example, when r=2, we would type and evaluate the following cells:

A={{2,0},{0,1}};

PictureThis[Region1,A]

PictureThis[Region2,A]

PictureThis[Region3,A]

PictureThis[Region4,A]

After observing the four sets of graphics above, it is not hard to see that the linear transformation T(x)=Ax sends any point (x,y) to the point (2x,y), thus causing a horizontal expansion by a factor of 2.

Besides plotting both the domain and image of the given points, PictureThis also automatically breaks the sets of points into as many as four color-coordinated subsets.  The colored sets in the domain and image are "linked" to one another in the sense that points in the domain of a certain color are sent to points in the image of the same color (e.g., red points go to red points).  This feature allows the student to recognize such actions as reflections and rotations which otherwise may not be so apparent if all of the points were depicted in the same color.  To illustrate, consider the linear transformation T(x)=Ax with

This transformation takes the plane and rotates it 90û in a counterclockwise direction.  If all of the points were drawn in the same color the output provided by PictureThis may mislead an inexperienced student to believe that this linear transformation fixes Region3.  However since PictureThis supplies color coordination between a point and its image, this pitfall should be avoided.

A={{0,-1},{1,0}};
PictureThis[Region3,A]

The code for PictureThis is found at the end of this article.

Conclusion

The two packages presented provide valuable tools for the linear algebra student which are relatively simple to use.  They allow the student to benefit from the vast capabilities of the computer algebra system Mathematica with a minimal understanding of how to use Mathematica.  This permits the student to focus on the mathematical concepts being presented via Mathematica and not the enormous task of first becoming proficient in Mathematica.

Code for ElementaryRowOps and PictureThis

ElementaryRowOps

BeginPackage["`ElementaryRowOps`"];

RowOp1::usage="RowOp1[M,a,b] Interchanges rows 'a' and 'b' of
Matrix 'M'.";

RowOp2::usage="RowOp2[M,s,a] Replaces row 'a' with the scalar
multiple 's' times row 'a'.";

RowOp3::usage="RowOp3[M,s,a,b] Replaces row 'b' with 
 ('s' * row 'a') + row 'b'.";

Begin ["`ElementaryRowOps`Private`"];

RowOp1[M_List, RowA_, RowB_]:=
   Module[{M1},
        If[ MatrixQ[M],
          M1=M;
          M1[[RowA]] = M[[RowB]];
          M1[[RowB]] = M[[RowA]];
          Print[MatrixForm[M1]];
          M1;
          ,(*else*)
          Print["A Matrix was not entered."];
          Print["Check your Matrix and try again."]
          ]
          
         ]
         
         
RowOp2[M_List, Sclr_, RowA_]:=
   Module[{M1},
        If[ MatrixQ[M],
          If [Sclr != 0,
       	     M1= M;
       	     M1[[RowA]] = Sclr*M[[RowA]];
       	     Print[MatrixForm[M1]];
       	     M1;
       	   ,(*else*)
       	     Print["Scalar needs to be non-zero"] ] 
       	 ,(*else*)
          Print["A Matrix was not entered."];
          Print["Check your Matrix and try again."]
          ]
         ]

RowOp3[M_List, Sclr_, RowA_, RowB_] :=
       Module[{M1},
        If[ MatrixQ[M],
          If [Sclr != 0,
             M1 = M;
       	     M1[[RowB]] = Sclr*M[[RowA]] + M[[RowB]];
       	     Print[MatrixForm[M1]];
       	     M1;
       	  ,(*else*)
       	     Print["Scalar needs to be non-zero."]]  
       	,(*else*)
          Print["A Matrix was not entered."];
          Print["Check your Matrix and try again."]
          ] 
         ]

End[];

Protect[ElementaryRowOps];

EndPackage[];

PictureThis

BeginPackage["`PictureThis`"];

PictureThis::usage="PictureThis[{{x1,y1},...,{xn,yn}},A] plots
 the points {x1,y1}, {x2,y2}, ... , {xn,yn} and their image 
 under the linear transformation represented by the 2 x 2 
 matrix A.";

Begin["`PictureThis`Private`"];

PictureThis[list1_List,list2_List,opts___Rule]:=
  Module[{x1,x2,z1,z2,plotsize1,plotsize2,a1,a2,b1,b2,y1,
          w1,y2,w2,c1,c2,d2,d1,p11,p1,A,Alist,p21,p2,
          size,part,remain,num,lista, listb, listc,listd,
          plota, plotb, plotc, plotd,alist, alistb, alistc, 
          alistd,aplota, aplotb, aplotc, aplotd,Dom,Ima},
  size = Length[list1];  
  
  If [size > 3,
  part = Floor[size/4];   (* size of each division *)
  remain = Mod[size,4];
  num = 1;
  lista = Range[num, part];
  
  (* These while loop blocks divide the main list (list1)
     into four lists of size part.  If the list does not
     divide evenly by four, the extra points are put into
     the last list 
   *)
   
  While[num <= part,     
        lista[[num]] = list1[[num]];
        num = num+1;
       ];
  
  num = 1;
  listb = Range[num, part];
  While[num <= part,
        listb[[num]] = list1[[num+part]];
        num = num+1;
       ];
       
  num = 1;
  listc = Range[num, part];
  While[num <= part,
        listc[[num]] = list1[[num+(2*part)]];
        num = num+1;
       ];
  
  num = 1;
  listd = Range[num, part+remain];
  While[num <= (part+remain),
        listd[[num]] = list1[[num+(part*3)]];
        num = num+1;
       ];  
       
  (* Here we plot, but do not show the entire list1 to 
     ascertain the size of the plotrange for the domain.
  *)
  
  p11=ListPlot[list1,AspectRatio->1,
         PlotStyle->{PointSize[.015],RGBColor[1,0,0]},
         DisplayFunction->Identity];
  plotsize1=PlotRange[p11];
  x1=plotsize1[[1,1]];
  x2=plotsize1[[1,2]];
  a1=Min[x1,x2,-x1,-x2];
  b1=Max[x1,x2,-x1,-x2];
  y1=plotsize1[[2,1]];
  y2=plotsize1[[2,2]];
  c1=Min[y1,y2,-y1,-y2];
  d1=Max[y1,y2,-y1,-y2];
  (* Now we apply the transformation matrix to the lists*)
  A=list2;
  Alist=Map[A.#&,list1];
  alista = Map[A.#&,lista];
  alistb = Map[A.#&,listb];
  alistc = Map[A.#&,listc];
  alistd = Map[A.#&,listd];
  (* Again we plot but do not show the entire Alist (after
     the transformation matrix has been applied) to 
     ascertain the size of the plotrange for the image. 
  *)
  p21=ListPlot[Alist,
         AspectRatio->Automatic,
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Image",
         DisplayFunction->Identity];
  plotsize2=PlotRange[p21];
  z1=plotsize2[[1,1]];
  z2=plotsize2[[1,2]];
  a2=Min[z1,z2,-z1,-z2];
  b2=Max[z1,z2,-z1,-z2];
  w1=plotsize2[[2,1]];
  w2=plotsize2[[2,2]];
  c2=Min[w1,w2,-w1,-w2];
  d2=Max[w1,w2,-w1,-w2];
  a=Min[a1,a2];
  b=Max[b1,b2];
  c=Min[c1,c2];
  d=Max[d1,d2];
  
  (* Here we plot the divided lists over the maximum plot
     ranges. Each list has a different color.
  *)
  plota=ListPlot[lista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Domain",
         DisplayFunction->Identity];
  plotb=ListPlot[listb,AspectRatio->Automatic,PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Domain",
         DisplayFunction->Identity]; 
  plotc=ListPlot[listc,AspectRatio->Automatic,PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[1,0,1]},
         PlotLabel->"Domain",
         DisplayFunction->Identity];  
  plotd=ListPlot[listd,AspectRatio->Automatic,PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Domain",DisplayFunction->Identity];   
  aplota=ListPlot[alista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Image",DisplayFunction->Identity];
  aplotb=ListPlot[alistb,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Image",DisplayFunction->Identity]; 
  aplotc=ListPlot[alistc,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[1,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity];  
  aplotd=ListPlot[alistd,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity];
  
  (*Merges the original list with different colors *)
  Dom=Show[{plota,plotb,plotc,plotd},DisplayFunction->Identity];        
  
  (*Merges the transformed matrix with differnt colors*)
  Ima=Show[{aplota,aplotb,aplotc,aplotd},DisplayFunction->Identity]; 
  
  Show[GraphicsArray[{Dom,Ima}],DisplayFunction->$DisplayFunction],
   
   (* This is for 3 points  *)
  
  If[size == 3,

  (* Assign each point to a separate list  *)
  
   lista = Range[1];
   listb = Range[1];
   listc = Range[1]; 
      
  lista[[1]] = list1[[1]];
  listb[[1]] = list1[[2]];
  listc[[1]] = list1[[3]];
  
  (* Here we plot, but do not show the entire list1 to 
     ascertain the size of the plotrange for the domain.
  *)
  
  p11=ListPlot[list1,AspectRatio->1,
         PlotStyle->{PointSize[.015],RGBColor[1,0,0]},
         DisplayFunction->Identity];
  plotsize1=PlotRange[p11];
  x1=plotsize1[[1,1]];
  x2=plotsize1[[1,2]];
  a1=Min[x1,x2,-x1,-x2];
  b1=Max[x1,x2,-x1,-x2];
  y1=plotsize1[[2,1]];
  y2=plotsize1[[2,2]];
  c1=Min[y1,y2,-y1,-y2];
  d1=Max[y1,y2,-y1,-y2];
  (* Now we apply the transformation matrix to the lists*)
  A=list2;
  Alist=Map[A.#&,list1];
  alista = Map[A.#&,lista];
  alistb = Map[A.#&,listb];
  alistc = Map[A.#&,listc];
  
  (* Again we plot but do not show the entire Alist (after
     the transformation matrix has been applied) to 
     ascertain the size of the plotrange for the image. 
  *)
  p21=ListPlot[Alist,
         AspectRatio->Automatic,
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity];
  plotsize2=PlotRange[p21];
  z1=plotsize2[[1,1]];
  z2=plotsize2[[1,2]];
  a2=Min[z1,z2,-z1,-z2];
  b2=Max[z1,z2,-z1,-z2];
  w1=plotsize2[[2,1]];
  w2=plotsize2[[2,2]];
  c2=Min[w1,w2,-w1,-w2];
  d2=Max[w1,w2,-w1,-w2];
  a=Min[a1,a2];
  b=Max[b1,b2];
  c=Min[c1,c2];
  d=Max[d1,d2];
  
  (* Here we plot the divided lists over the maximum plot
     ranges. Each list has a different color.
  *)
  plota=ListPlot[lista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Domain",DisplayFunction->Identity];
  plotb=ListPlot[listb,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Domain",DisplayFunction->Identity]; 
  plotc=ListPlot[listc,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[1,0,1]},
         PlotLabel->"Domain",DisplayFunction->Identity]; 
   
  aplota=ListPlot[alista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Image",DisplayFunction->Identity];
  aplotb=ListPlot[alistb,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Image",DisplayFunction->Identity]; 
  aplotc=ListPlot[alistc,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[1,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity]; 
  
  (*Merges the original list with different colors *)
  Dom=Show[{plota,plotb,plotc},DisplayFunction->Identity];        
  
  (*Merges the transformed matrix with differnt colors*)
  Ima=Show[{aplota,aplotb,aplotc},DisplayFunction->Identity];                                            
  
  Show[GraphicsArray[{Dom,Ima}],DisplayFunction->$DisplayFunction];
  ,
 
  (* This is for two points *)  
  
  If[size == 2,
  
  (* Assign each point to a separate list  *)
  
   lista = Range[1];
   listb = Range[1];
   
  lista[[1]] = list1[[1]];
  listb[[1]] = list1[[2]];
  
  (* Here we plot, but do not show the entire list1 to 
     ascertain the size of the plotrange for the domain.
  *)
  
  p11=ListPlot[list1,AspectRatio->1,
         PlotStyle->{PointSize[.015],RGBColor[1,0,0]},
         DisplayFunction->Identity];
  plotsize1=PlotRange[p11];
  x1=plotsize1[[1,1]];
  x2=plotsize1[[1,2]];
  a1=Min[x1,x2,-x1,-x2];
  b1=Max[x1,x2,-x1,-x2];
  y1=plotsize1[[2,1]];
  y2=plotsize1[[2,2]];
  c1=Min[y1,y2,-y1,-y2];
  d1=Max[y1,y2,-y1,-y2];
  (* Now we apply the transformation matrix to the lists*)
  A=list2;
  Alist=Map[A.#&,list1];
  alista = Map[A.#&,lista];
  alistb = Map[A.#&,listb];
  
  (* Again we plot but do not show the entire Alist (after
     the transformation matrix has been applied) to 
     ascertain the size of the plotrange for the image. 
  *)
  p21=ListPlot[Alist,
         AspectRatio->Automatic,
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity];
  plotsize2=PlotRange[p21];
  z1=plotsize2[[1,1]];
  z2=plotsize2[[1,2]];
  a2=Min[z1,z2,-z1,-z2];
  b2=Max[z1,z2,-z1,-z2];
  w1=plotsize2[[2,1]];
  w2=plotsize2[[2,2]];
  c2=Min[w1,w2,-w1,-w2];
  d2=Max[w1,w2,-w1,-w2];
  a=Min[a1,a2];
  b=Max[b1,b2];
  c=Min[c1,c2];
  d=Max[d1,d2];
  
  (* Here we plot the divided lists over the maximum plot
     ranges. Each list has a different color.
  *)
  plota=ListPlot[lista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Domain",DisplayFunction->Identity];
  plotb=ListPlot[listb,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Domain",DisplayFunction->Identity]; 
   
  aplota=ListPlot[alista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Image",DisplayFunction->Identity];
  aplotb=ListPlot[alistb,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[0,.4,0]},
         PlotLabel->"Image",DisplayFunction->Identity]; 
         
  (*Merges the original list with different colors *)
  Dom=Show[{plota,plotb},DisplayFunction->Identity];        
  
  (*Merges the transformed matrix with differnt colors*)
  Ima=Show[{aplota,aplotb},DisplayFunction->Identity];                                            
  
  Show[GraphicsArray[{Dom,Ima}],DisplayFunction->$DisplayFunction];
  ,
  
  (* This is for one point *)
 
  (* Assign each point to a separate list  *)
  
  lista = Range[1];

  lista[[1]] = list1[[1]];
       
  (* Here we plot, but do not show the entire list1 to 
     ascertain the size of the plotrange for the domain.
  *)
  
  p11=ListPlot[list1,AspectRatio->1,
         PlotStyle->{PointSize[.015],RGBColor[1,0,0]},
         DisplayFunction->Identity];
  plotsize1=PlotRange[p11];
  x1=plotsize1[[1,1]];
  x2=plotsize1[[1,2]];
  a1=Min[x1,x2,-x1,-x2];
  b1=Max[x1,x2,-x1,-x2];
  y1=plotsize1[[2,1]];
  y2=plotsize1[[2,2]];
  c1=Min[y1,y2,-y1,-y2];
  d1=Max[y1,y2,-y1,-y2];
  (* Now we apply the transformation matrix to the lists*)
  A=list2;
  Alist=Map[A.#&,list1];
  alista = Map[A.#&,lista];
 
  (* Again we plot but do not show the entire Alist (after
     the transformation matrix has been applied) to 
     ascertain the size of the plotrange for the image. 
  *)
  p21=ListPlot[Alist,
         AspectRatio->Automatic,
         PlotStyle->{PointSize[.015],RGBColor[0,0,1]},
         PlotLabel->"Image",DisplayFunction->Identity];
  plotsize2=PlotRange[p21];
  z1=plotsize2[[1,1]];
  z2=plotsize2[[1,2]];
  a2=Min[z1,z2,-z1,-z2];
  b2=Max[z1,z2,-z1,-z2];
  w1=plotsize2[[2,1]];
  w2=plotsize2[[2,2]];
  c2=Min[w1,w2,-w1,-w2];
  d2=Max[w1,w2,-w1,-w2];
  a=Min[a1,a2];
  b=Max[b1,b2];
  c=Min[c1,c2];
  d=Max[d1,d2];
  
  (* Here we plot the divided lists over the maximum plot
     ranges. Each list has a different color.
  *)
  plota=ListPlot[lista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Domain",
         DisplayFunction->Identity];
  aplota=ListPlot[alista,AspectRatio->Automatic,
         PlotRange->{{a,b},{c,d}},
         PlotStyle->{PointSize[.015],RGBColor[.8,0,0]},
         PlotLabel->"Image",DisplayFunction->Identity];
         
  (*Merges the original list with different colors *)
  Dom=Show[{plota},DisplayFunction->Identity];        
  
  (*Merges the transformed matrix with differnt colors*)
  Ima=Show[{aplota},DisplayFunction->Identity];        
  
  Show[GraphicsArray[{Dom,Ima}],DisplayFunction->$DisplayFunction];
   ]]]]

End[];

Protect[PictureThis];

EndPackage[];

Region1=Flatten[Table[{.5i,.5j},{i,0,10},{j,0,10}],1];

Region2=Flatten[Table[Table[{.5i,.5j},{j,0,i}],{i,0,10}],1];

Region3=Table[{Cos[(2Pi/90)*i],Sin[(2Pi/90)*i]},{i,1,90}];

Region4=Table[{-1+(3t)/30,-2+(6t)/30},{t,0,30}];

About the authors

Stephen Hughes is a junior majoring in computer science at Dickinson College.

Elizabeth Koopman is a senior at Dickinson College.  She is a major in both mathematics and computer science.

Shari Prevost is an assistant professor of mathematics in the Department of Mathematics and Computer Science at Dickinson College.

Barry Tesman is an assistant professor of mathematics in the Department of Mathematics and Computer Science at Dickinson College.

The Dana Internship Program and Dickinson College provided funding for this project.