>
CS 1323 Honors, Fall 1996
Individual Project 4
Ecology Simulation
Due Wednesday, October 2, 4:30pm
DELAY: now due Friday, October 4, 4:59pm
What to Hand In (see also:
example project solution)
- Four projects are described below.
Team members listed first on their team's
roster
must do Project 4A; those listed second, Project 4B;
third, Project 4C; fourth, Project 4D.
If your team has five members, the member listed last
on the roster must do Project 4A, independently of the
other team member working on that project.
- Turn in a
listing
of the Haskell script you write for your
project, following the required
standards.
- Turn in a
session transcript
in which you show
that your function operates correctly on arguments
chosen to demonstrate the function's capabilities.
- Explain (handwritten on the transcript) what
aspects of the function's behavior are illustrated by each of
your choices of
demonstration examples.
Project 4A
Rabbits eat grass. Coyotes eat rabbits. There's plenty of grass,
so coyotes are the primary obstacle to
increases in the rabbit population.
The coyote population increases with the food supply (rabbits).
The following equations simulate the monthly changes in the
rabbit population (R) and the coyote population (C).
- R[next month] = (1 + i)R - eCR [this month]
- C[next month] = (1 - s)C + egRC [this month]
These equations are a simplified form of the
Lotka-Volterra model
for predator-prey ecologies.
The coefficients have the following meaning in the model:
- i - fractional increase in rabbit population from births in a month
- s - fractional decrease in coyote population from starvation
- e - likelihood that a particular coyote will eat a particular
rabbit
- g - fractional increase in coyote population caused by eating
one rabbit
Your task (at long last):
Define a function called "rabbitCoyotePopulationTrajectory" that
delivers a sequence recording the monthly populations of rabbits
and coyotes.
The type of the function will be
rabbitCoyotePopulationTrajectory :: [Float] -> [Float] -> [[Float]]
The first argument of the population function will be the
sequence [i, s, e, g]
of coefficients prescribing the model.
The second argument will be
the sequence [R, C], which gives the
populations of rabbits and coyotes in the first month.
The function delivers the sequence of
population
figures for successive months, as determined by the equations
of the model. Each population figure in this sequence will have
the form [R, C], where R and C
are the populations of rabbits and coyotes for one of the months
in the simulation.
Project 4B
Define a function called "makeChart" that charts a sequence of
points, given the two-dimensional Cartesian coordinates of the
points.
The type of the function will be
makeChart :: Char -> Int -> Int -> [[Float]] -> ([Float], [String])
The first argument will be the character to be used to chart
the points. The second argument will be the width w of the
picture representing the chart,
measured in character positions across a line of text.
(Read the description of Project 4C to find out what "picture"
means, for purposes of this project.)
The third argument will be the height h of the
picture representing the chart, measured
in lines down a page of text. The fourth argument will be
the sequence of points. Each point in the fourth argument
will be represented by a sequence of two numbers
[x, y],
giving the horizontal and vertical coordinates of the point.
The function delivers a tuple whose first component is a
sequence of four numbers [minH, maxH,
minV, maxV], where
minH and maxH are the minimum and maximum
values among the horizontal coordinates in the fourth
argument and
minV, maxV and the minimum and maximum
values among the vertical coordinates in the fourth argument.
The second component of the tuple delivered by makeChart
is a picture, in the sense of Project 4C, representing the
sequence of coordinates in the fourth argument.
The left border of the picture corresponds to the value
minH, the right border to maxH,
the top border to minV and the bottom
border to maxV. A horizontal coordinate half way
between minH and maxH would be represented
in the picture by a dot located half way across the picture;
vertical coordinates are charted similarly, but down from
the top of the picture rather than across.
The exact position of the dot will be computed by the
function digitize, which you can acquire from
NumericUtilities.
To get access to this function, copy the
NumericUtilities.lhs
file to your file space, and put the directive
import NumericUtilities
at the beginning of your script.
Note: You no longer have to worry about loading the
script containing the imported functions separately.
Hugs chases down the imported
files automatically. Just load your script, and the
import directive will trigger an automatic load
of NumericUtilities.
The invocation
digitize w minH maxH x
converts the horizontal coordinate x
to the appropriate character
position in the range [0 .. w - 1], where w
is the width of the picture.
Similarly, the invocation
digitize h minV maxV y
converts the
vertical coordinate y to the
appropriate line number in the range
[0 .. h - 1], where h
is the height of the picture.
You will also need to use the function updatePicture,
described in Project 4C. I will send you by email
a Haskell definition
for this function that you can copy into your script.
Of course, since some of your classmates will be
defining updatePicture as their project,
you must not share the definition I send you with
any of your classmates.
Project 4C
Define a function called "updatePicture" that
inserts a dot into a picture at a specified point.
The type of the function will be
updatePicture :: Char -> [Int] -> [String] -> [String]
The first argument will be the character c to used to mark
the new dot in the picture.
The second argument will be
the coordinates [i, j] of the position of the new dot,
where i is the distance from the left border, measured
in character positions across a line of text, and j is the
distance from the top border, measured in lines down
a page of text.
The third argument will be the picture itself in its
current form. This will be a sequence of strings.
There will be h strings in all, where h
is some integer greater than zero.
Each string will be a line of text used to represent
one horizontal cross-section of the picture. All of the
strings in the sequence will be of the same length,
w, where w is an integer greater than
zero. You may assume that 0 <= i < w
and that 0 <= j < h.
The value delivered by update will be identical to its
third argument, except that element j in the
sequence of strings
(numbering the strings from zero up,
so that the first string in the sequence is element zero)
will have the character c in position i
(numbering the positions from zero up,
so that the first position in the string is position zero).
Project 4D
Define a function called "displayChart" that
constructs a string which, if printed as text,
would exhibit, graphically,
the information in a chart delivered by the function
makeChart from Project 4C.
The type of your function will be
displayChart :: [String] -> ([Float], [String]) -> String
The first argument will be a sequence
[labelH, labelV] of two strings to be
used as labels for the horizontal and vertical axes.
The second argument is a tuple with the same structure
as one that could be delivered by the function makeChart
from Project 4B.
The function displayChart delivers a string containing
the lines from the picture in the second argument enclosed
in a frame of appropriate visible characters and marked
with the numeric ranges represented by the horizontal
and vertical axes. Optionally, you may also label axes
with the labels given in the first argument, but this is
not a required characteristic of your function (that is,
your function can ignore its first argument if you choose
not to display labels on the axes).
Take care to reorient the picture so that smaller values
along the vertical scale appear at the bottom of the
display and larger values at the top.
The display below provides an example to show how a string
delivered by displayChart could look when printed. Yours
need not look exactly like this, but should communicate
the same information in a reasonable way
(except that the labels on the axes, Coyotes and Rabbits
in the example, are optional and may be omitted).
50.8894|------------------------------|
| **** *** * |
| ** * * |
| * * |
| * * |
| ** * |
| * * |
| * * |
| * * |
|* * |
|* * |
Coyotes|* *|
|* *|
|* *|
|* *|
|* *|
|* **|
|* ** |
|** * ** |
| ** *** ***** |
| ****************** |
4.96911|------------------------------|
|718.247 Rabbits |3022.52
You may want to use one or more of the functions
leftJustify, rightJustify, and reps,
which you can acquire from
SequenceUtilities.
To get access to these functions, copy the
SequenceUtilities.lhs
file to your file space, and put the directive
import SequenceUtilities
at the beginning of your script.
Note: You no longer have to worry about loading the
script containing the imported functions separately.
Hugs chases down the imported
files automatically. Just load your script, and the
import directive will trigger an automatic load
of SequenceUtilities.
Ground Rules
- You may use any aspects of Haskell discussed in
Lessons 1-15 of the Haskell text, in class, or
in previous projects.
You may also use the function head, which delivers
the first element of a non-empty sequence
(head will choke on an empty sequence).
- head :: [a] -> a
- head[x, y, z, ...] = x
Some of the problems also permit
the use of other functions supplied on the
CS1323 Honors Web site (see problem description).
- Read the
Code of Conduct
for ground rules that apply to all
projects.
- The
Project Style Guide
doesn't contain any new requirements for this project.
Use the same style as for Individual Project 3.