eProgramming in Maple, Part 1:
Functions, iteration and graphics
Integrated, First-Year Curriculum in Science, Engineering, and Mathematics
Based on a notebook by Claude Anderson
Revised by Kurt Bryan and David Mutchler
Format of today's session
Overview of programming in Maple. Why Maple? Why ME!?!
Turn to your partner or a neighbor and discuss (45 seconds):
--- What is the difference between "programming" and merely entering some Maple code to get an answer?
--- Can you think of some examples of things we have done in previous sessions or in your homework
that could be called "programming"?
Large group discussion (2 minutes):
--- Overview of programming in IFYCSEM.
--- Why we begin our programming experience with Maple.
Vectors: what are they?
From your calculus textbook (Larson, Hostetler, Edwards):
Many quantities in geometry and physics, such as area, volume, temperature, mass and time,
can be characterized by single real numbers ... called scalars .
Other quantities, such as force, velocity and acceleration, involve both magnitude and direction
and cannot be characterized completely by single real numbers. A directed line segment is used
to represent such a quantity... The line segment is called a vector in the plane.
A vector in the plane can be represented by many different line segments --- all pointing in
the same direction and all of the same length. ... The directed line segment whose initial point
is the origin is often the most convenient such representation.
[For such a representation, the vector] can be uniquely represented by the coordinates
of its terminal point.
Summary: vectors are very useful and you will use them LOTS this year.
In today's lab, we will draw pictures described by points (which can be thought of as vectors).
-- You can enlarge a picture by multiplying every point in the picture by a constant.
-- You can move a picture by adding a fixed vector to every point in the picture.
You'll find this handy today. Details below about how to do such vector arithmetic .
There are three key ideas to the use of functions in any programming language:
--- formal parameters
--- actual arguments
--- returned values
For example, in the following,
is the formal parameter while 3 and
are actual arguments.
h := x -> x^2 + 5*x + 3;
h( 3 );
h( w^2 );
By the way, note that I typed the separate lines within one execution group by using Shift-Enter (instead of just Enter ) at the end of lines. You'll use this lots in today's lab, so get used to it!
Note the use of the returned value from Maple function
> cos( h(3) + h(2.7) ) * h(-4);
One can have Maple functions of two (or more) variables, as we saw in previous sessions.
Here is a simple example:
> twoArgFun := (s, t) -> 2*s + 3*t;
The names and are not defined globally by this definition, they are merely the parameters ("dummy arguments") of the definition of twoArgFun . To see this, evaluate the following code:
When we apply twoArgFun to the numbers 1.4 and 100 in the following example, 1.4 and 100 are called the "actual arguments". The first actual argument (1.4) is substituted for the first parameter ( s ) , and the second actual argument (100) is substituted for the second parameter ( t ).
> twoArgFun( 1.4, 100 );
If we try to call twoArgFun with only one argument, it doesn't fit the pattern of twoArgFun 's definition, so Maple can't evaluate it. Here is an example (this example causes an error message):
> twoArgFun( 6 );
In-class exercise 1 : Write a Maple function vectorLength that has two parameters and returns the length of a vector represented by those parameters. For example, vectorLength(1, 2) should return .
vectorLength := (xa,ya) -> sqrt(xa^2+ya^2);
There are two key ideas to
--- using s to create a list
--- using s to obtain a particular element of a list.
a := [x, y, 3, h];
That last example illustrates both lists and Maple functions.
If it doesn't make sense to you, ask about it now!
Another example, in which a Maple function
returns a list
d := (x, y) -> [x^2, x*y + 8, y^2];
d(-1, 4) ;
Do you understand the notation of the last item above? If not, discuss it with someone who does understand it: your partner, a classmate, a lab assistant or your instructor.
In-class exercise 2 : Write a Maple function AnotherVectorLength that has ONE parameter that is a list of two elements and returns the length of a vector represented by that list. For example, AnotherVectorLength([1, 2]) should return .
When you are done with this exercise, shout "I need a Red Card!" and someone will come check your work.
AnotherVectorLength := b -> sqrt(b^2+b^2);
b := [8,1/3,6]:
Here's something you probably have not noticed about lists: Maple can see them as vectors and Maple knows about vector arithmetic. For example:
u := [3, 4];
v := [9, 1];
u + v;
You'll find this handy today --- remember it!
Recall that the
command creates sequences. Here's some examples:
seq( 3*i, i = 1 .. 9 );
seq( (2*i - 1)^2, i = 2 .. 6 );
seq( Pi/(6 - k), k = 0 .. 5 );
points := [ seq( [x, sin( Pi * x / 6 )], x = 0 .. 12 ) ];
plot( points );
In-class exercise 3: Use seq to generate a list of 7 points on the graph of , with x -coordinates 0 through 6. Plot the lines generated by those points (as in the above example). As above, a "point" is a list of two numbers.
> points := [ seq( [x, x^2] ,x=0..6 ) ];
Suppose that we want to generate a list of the points that divide the interval [0,
] into 8 equal intervals:
> [ seq(2 * Pi * (i / 8), i = 0 .. 8) ];
There's nothing special about 8; we can write a Maple function that does this for any integer
> intervals := n -> [ seq(2 * i * Pi / n, i = 0 .. n) ];
Warning, `i` in call to `seq` is not local
As before, don't worry about the warning message. We'll talk about its meaning when we get further into programming. You can now use this
Now let's use the same idea to generate a list of equally spaced points around a circle with radius
. The key idea is that the coordinates of the point at angle
-axis are (
circlePoints := (n, r) ->
seq( [r * cos(2* Pi * i / n), r * sin(2 * Pi * i / n)],
i = 0 .. n ) ) ];
> c := circlePoints( 13, 3 );
> plot( c );
In-class exercise 4: Use circlePoints (don't write circlePoints, just use it!) to produce a list of 10 equally spaced points on a circle of radius 2. Plot the lines between those points as above.
When you are done with this exercise, shout "I need a Yellow Card!" and someone will come check your work.
> ex4 := circlePoints(10,2);
Sequences of sequences
Later in the lab you will use sequences of sequences. Here are some examples to help you understand that idea. For each example, first decide what you think it will produce, then execute it to check your answer.
> seq( [1, j], j = 1 .. 3 );
> seq( [k, j], j = 1 .. 3 );
seq( seq( [k, j], j = 1 .. 3 ),
k = 1 .. 4 );
Notice that for each value of
(outer range), we go through all of the values of
seq( seq( [j, k], j = 1 .. k ),
k = 1 .. 4 );
Maple graphics --- PLOT and CURVES
So far, the only graphics we have generated have been via the high-level command
. The pictures that it builds are based on graphics primitives like PLOT, CURVES and TEXT. We examine the basics of some of these primitives here and others in your homework. These primitives should be used when you want to draw specific pictures or enhance your function plots by adding such pictures.
You've Gotta Draw The Line Somewhere
. Try these commands:
myline := CURVES( [ [3,1], [6,6], [7,3] ] );
PLOT( myline );
The CURVES command generates a graphic primitive that defines a "curve" joining the list of points that the command is fed. The points are joined with straight line segments (connect the dots). The PLOT command (it must be in all capitals) creates the actual graph from the graphics primitives that you supply.
You can do multiple lines with the same
myline1 := CURVES( [ [3,2], [5,5] ] ):
myline2 := CURVES( [ [0,3], [5,1] ] ):
PLOT( myline1, myline2);
, the default behavior is to draw axes unless you specify otherwise. You can specify otherwise like this:
> PLOT( myline1, myline2, AXESSTYLE(NONE) );
In-class exercise 5: Write code to draw a "house" like the one shown as Picture A in your Pictures handout. (I'll give you paper copy of the Pictures handout, but electronic copy is in the same place from which you obtained this file.) The total height of the house (including the roof) should be the same as its width (3 units), the roof should be 1 unit tall (thus the rectangle is 2 units tall), and the lower left corner of the house should be the origin.
Use the PLOT command to draw your house, first with axes (as in the left side of Picture A), then without the axes (as in the right side of Picture A).
> house := CURVES( [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );
> PLOT( house, SCALING(CONSTRAINED), AXESSTYLE(NONE) );
Make sure your plots produce output exactly like Picture A in the Pictures handout, including the numbers. If they don't, get help NOW.
By the way, notice that the high-level plot function (lower-case) really uses PLOT and CURVES (upper-case).
p1 := plot( x^2, x = 2 .. 4 ):
(Scroll up to see that the above output starts with "PLOT" and "CURVES", as promised.)
Putting it all together: using functions with parameters to encapsulate ideas .
Here is a picture. You'll do a more interesting picture shortly.
rectangle1 := CURVES( [ [1,1], [4,1], [4,3], [1,3], [1,1] ] );
PLOT( rectangle1, SCALING(CONSTRAINED), AXESSTYLE(NONE) );
I did the SCALING(CONSTRAINED) to ensure that 1 unit in the x -direction is the same physical distance on the screen as 1 unit in the y -direction. This makes today's pictures look prettier. You'll use SCALING(CONSTRAINED) in all the pictures you draw in the rest of this lab.
Here is the same code as in
above, but this time as a
of no parameters. As usual, the -> indicates that we are defining a Maple function. The ( ) in front of the -> means there are no parameters.
rectangle2 := ( ) ->
CURVES( [ [1,1], [4,1], [4,3], [1,3], [1,1] ] );
> PLOT( rectangle2(), SCALING(CONSTRAINED) );
Self-test: why is it necessary to use rectangle2() in the above PLOT command instead of simply rectangle2 ?
By encapsulating the code into a Maple function, we have used the single most important concept in computer science ( and perhaps in problem-solving in general), abstraction . We give a name (" rectangle2 ") to this collection of code, so that when we use it, we don't think, "I am drawing four lines", but rather, "I am drawing a rectangle."
This brings us to a key followup idea:
using parameters to reuse code
. Let's convert our Maple function to permit a single parameter that specifies the length of the rectangle:
rectangle3 := (length) ->
CURVES( [ [1, 1],
[1 + length, 1],
[1 + length, 3],
[1, 1] ] );
PLOT( rectangle3(3), rectangle3(5), rectangle3(8),
Similarly, we could have a Maple function that has a single parameter that specifies the amount by which to stretch the rectangle (in both directions):
rectangle4 := (size) ->
CURVES( size * [ [1, 1], [4, 1], [4, 3], [1, 3], [1, 1] ] );
PLOT( rectangle4(3), rectangle4(5), rectangle4(8),
Note the use of vector arithmetic in the above: multiplying size times the list multiplies it times each element in the list.
Each element is itself a list, so the multiplication works its way inside each two-element list.
Finally, add another key idea ---
(doing things over and over) --- and our pictures start getting hot:
PLOT( seq( rectangle4(k), k = 1 .. 20 ),
In-class exercise 6: ABSTRACTING a house function.
code you wrote earlier to write a
with no parameters that returns a graphics object representing the house. Test your function with the following command. (The TEXT graphics primitives puts the requested text at the requested place.) The output should look like Picture B in the
(If it doesn't, get help.)
> house1 := () -> CURVES( [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );
TEXT( [1.5, 0.5], "Our house is a very very very plain House"),
By encapsulating the code into a Maple function, we have used the most important tool known to the programmer (or to the problem-solver in general),
. We give a name ("
") to this collection of code, so that when we use it, we don't think, "I am drawing six lines", but rather, "I am drawing a house".
In-class exercise 7: adding a PARAMETER to make the code more useful.
Write another Maple function house2 (copy-and-paste from house1 as needed) that has a single parameter ( roofHeight ) that determines how big the house is. A roofHeight of 1 draws the house above (Picture B). A roofHeight of 2 draws all of the dimensions twice as big, etc. Test your function with the following command. The output should look like Picture C in the Pictures handout. (If it doesn't, get help.)
One hint: using vector arithmetic simplifies the code for house2 nicely. Use vector arithmetic if you can (but if you can't, that's OK).
> house2 := (roofHeight) -> CURVES( roofHeight * [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] );
> PLOT( house2(1), house2(0.5), house2(3), SCALING(CONSTRAINED) );
When you are done with in-class exercise 7, shout "I need a Green Card!" and someone will come check your work.
In-class exercise 8: adding another PARAMETER to make the code still more useful.
We still have a problem; it would be nice if the houses could be in different locations. (My real estate agent said that location is everything in the real estate market!) Write another Maple function house3 (copy-and-paste from house2 as needed) that has two parameters. The first is the size as above and the second (a vector, that is, a list of two numbers) specifies the location of the lower left corner of the house.
As before, using vector arithmetic simplifies the code for house3 nicely. Use vector arithmetic if you can (but if you can't, that's OK).
Test your function with the following command. The output should look like Picture D in the
(If it doesn't, get help.)
house3 := (roofHeight, V) ->
CURVES( roofHeight * [ [0,2], [0,0], [3,0], [3,2], [0,2], [1.5,3], [3,2] ] + [V,V,V,V,V,V,V] );
PLOT( house3( 2, [0,0] ), house3( 3, [7,2] ),
In-class exercise 9: Ega litarian's Neighborhood --- where all houses are created equal.
What power do we have at our disposal now that we have a house
Let's take it for a test drive and see what it'll do!
Throughout this exercise, if your output differs from the specified picture in the Pictures handout, get help !
First, draw Picture E, a row of houses:
PLOT( seq( house3( 1, [4*k, 0] ), k = 0 .. 8 ),
Or we can draw Picture F, row-houses:
PLOT( seq( house3( 1, [3*k, 0] ), k = 0 .. 8 ),
Before we create a subdivision, we'd better work on "double iterations" (sequences of sequences) a bit. Try to predict the value of each piece of code before you evaluate it. (They are the same examples you did earlier in the session..) If you don't understand why the results are what they are, ask!
> seq( [1, j], j = 1 .. 3 );
> seq( [k, j], j = 1 .. 3 );
seq( seq( [k, j], j = 1 .. 5 ),
k = 1 .. 4 );
seq( seq( [j, k], j = 1 .. k ),
k = 1 .. 4 );
Next, we draw Picture G, a whole subdivision of tract-houses (make sure that this works for you):
PLOT( seq( seq( house3( 0.5, [2*j, 2*k] ),
j = 0 .. 5 ),
k = 0 .. 4 ),
Or Picture H, a wedge of houses. Study this one carefully; it differs from the previous command by only one letter. Try to figure out what the picture should look like. Then execute the code. If your prediction was incorrect, be sure you understand why before going on to the next one.
PLOT( seq( seq( house3(0.5, [2*j, 2*k]),
j = 0 .. k),
k = 0 .. 4),
Or even a picture of 25 random houses ( rand(0 .. 99) generates a Maple function which provides a pseudo-random integer from 0 to 99 each time it is called).
randomNumberProcedure := rand( 0 .. 99 );
PLOT( seq( house3( randomNumberProcedure() / 10,
randomNumberProcedure() ] ),
j = 1 .. 25 ),
Now are you convinced of how much power we gain by defining house3 as a function with parameters?
In-class exercise 10: Auntie Em! Auntie Em!
After you have successfully completed the last house function from the above exercises, evaluate the following inputs. When the plot appears, click on it to bring up the animation controls (buttons). (Get help if you don't understand what I am saying in this exercise, it is more easily shown than written.) Click on the "play" button --- pretty neat, huh?! Click the rightmost animation control button to change to "Cyclic mode" and "play" some more. Try out the other buttons too.
houses := [ seq( PLOT( house3( 0.5,
evalf( [ 4 * cos(2 * Pi * k / 40),
4 * sin(2 * Pi * k / 40) ] )
k = 0 .. 40 ) ]:
with( plots ):
display( houses, insequence=true );
Notice that the "spinning house" animation is not smooth (there's a pause) at the point where it reaches the starting point again. Can you figure out why and how to fix it?
By the way, the evalf is necessary in the above because display and PLOT (unlike plot ) do not automatically convert symbolic expressions like Pi to numbers when they attempt to display the plot.
In-class exercise 11: Auntie Em! Auntie Em! (continued)
Now look again at the tornado-to-Oz animation example from the previous section. Think about the circlePoints example from earlier in the session. Explain to your partner how the tornado pictures are generated. Do you follow what is going on? Do you think it would be reasonable to do this if we had not first defined a house function with parameters?
Summary statement (so far): Maple programming = Designing and writing good functions.
Tell your instructor or a lab assistant that you have completed this lab exercise. He will ask you to show him your pictures from house3 in Exercises 8 and 9. He will then give you a cover sheet (each partner gets one) that record the competencies you earned today.
If you do not complete the lab before you leave, see your instructor for special instructions.
When you have completed this worksheet, begin working on the post-lab problems. Beginning the post-lab problems is part of this lab. You can do the post-lab problems with your partner, with someone else, or by yourself --- your choice.