a
A4.~
b
Appendices:
Al: The cdf of Rho4
The cdf of Rho4 is derived from the desired behavior of the method
on a planar slope.
Without loss of generality, consider a slope
whose true aspect is some angle t (we here adopt the convention
that 0 degrees is east, 90 degrees is north, etc.) between 0 and 90
degrees.
In this case the two greatest descents will be to the east and to
the north.
Let P(N) be the
probability of choosing to flow north,
and P(E) be the probability of choosing to flow east.
P(N)+P(E) =
1, i.e. a trial consists of either moving one step to the N or one
step to the E. Take EW to be the x axis, and NS to be the y axis. Let
E[delx] be the expected change in x due to one trial, and E[dely] the
expected change in y. Since a move to the N increases x by none and
y by one, while a move to the E increases x by one and y by none,
E[dely]/E[delx]
= P(N)/P(E) = P(N)/(1-P(N))
34
Since we wish the expected value of the flowline direction to be
the same as the true aspect, we set E[dely]/E[delx] = tan(t), and we
have
tan(t) = P(N)/(1-P(N)),
which implies
P(N) = tan(t)/(tan(t)+1)
Let p be a given pixel, Pe the pixel to the east of p, and Pn the pixel
to the north of p. The value z(p)-z(pe) will be positive and
identical for all pixels p on a slope of aspect t between 0 and 90
degrees.
Similarly, the value z(p)-z(pn) will be positive and
identical for all p. Since the algorithm chooses the greater of
rho*(z(p)-z(pn)) and z(p)-z(pe),
the probability of choosing to flow
north is
P(N) = P(rho*(z(p)-z(pn)) > z(p)-z(pe))
= P(rho > (z(p)-z(pe))/(z(p)-z(pn)) )
Simple geometrical considerations show that on a planar slope
35
(z(p)-z(pe))/(z(p)-z(pn)) = 1/tan(t)
Summarizing, we have
P( rho > 1/tan(t) ) = P(N) = tan(t)/(tan(t)+1)
Let x = 1/tan(t), and we have
P( rho <= x) = 1 - P( rho > x ) = 1 - (1/x)/((1/x)+1) = x/(x+1), 0<=x.
which is the desired cdf.
Let r be a uniformly distributed
random
variable between 0 and 1. Then the inverse of the cdf, rho = 1/(1/r
- 1), generates rho appropriately.
A2: The cdf of Rho8
The cdf of Rho8 is derived from th(e desired behavior of the method
on a planar slope.
Without loss of generality, consider a slope
whose true aspect is some angle t (we here adopt the convention
that 0 degrees is east, 90 degrees is north, etc.) between 0 and 45
36
degrees.
In this case the two greatest descents will be to the east and to
the northeast.
Let P(NE) be the
probability of choosing to flow
northeast, and P(E) be the probability of choosing to flow east.
P(NE)+P(E) = 1, i.e. a trial consists of either moving one step to the
NE or one step to the E. Take EW to be the x axis, and NS to be the y
axis. Let E[delx] be the expected change in x due to one trial, and
E[dely] the expected change in y. Since a move to the NE increases
both x and y by one, while a move to the E increases x by one and y
by none,
E[dely]/E[delx] = P(NE)/(P(NE)+P(E)) = P(NE)
Since we wish the expected value of the flowline direction to be
the same as the true aspect, we set E[dely]/E[delx] = tan(t), and we
have
tan(t) = P(NE)
Let p be a given pixel, Pe the pixel to the east of p, and pne the
pixel to the northeast of p.
The value z(p)-z(pe) will be positive
37
and identical for all pixels p on a slope of aspect t between 0 and
45 degrees.
Similarly, the value z(p)-z(pne) will be positive and
identical for all p. Since the algorithm chooses the greater of
rho*(z(p)-z(pne)) and z(p)-z(pe),
the probability of choosing to
flow northeast is
P(NE) = P(rho*(z(p)-z(pne)) > z(p)-z(pe))
= P(rho > (z(p)-z(pe))/(z(p)-z(Pne)))
Simple geometrical considerations show that on a planar slope
(z(p)-z(pe))/(z(p)-z(Pne))
= cos(t)/(cos(t)+sin(t))
Summarizing, we have
tan(t) = P(NE) = P( rho > cos(t)/(cos(t)+sin(t)) )
Let x=cos(t)/(cos(t)+sin(t)), and we have
P( rho <= x) = 1 - P( rho > x ) = 1 - tan(t) = 1 - (1/x - 1) = 2-1/x,
0.5<=x<=1
38
which is the desired cdf.
Let r be a uniformly distributed
random
variable between 0 and 1. Then the inverse of the cdf, rho = 1/(2r), generates rho appropriately.
A3: The variance of the stochastic methods Rho4 and Rho8.
Fig. Al portrays the variability in the descent line produced by the
stochastic behavior of the
Rho grids.
To save presentation space,
Fig. Ala is the superposition of three independent
experiments,
that show method Rho4 on three perfect slopes, the first with
aspect 20 N of E (these figures use the convention E = 00°, N = 900°,
etc.) the second with aspect 26.5650 (atan(1/2)), and the third
with aspect 450°.
Fig. Alb is the superposition of three independent
experiments, that
show method Rho8 on three perfect slopes, the
first with aspect 20, the second with aspect 26.5650 (atan(1/2)),
and the third with aspect 430°.
In each of these experiments, 1500 independent Rho grids descents
were simulated, and the point of arrival was plotted after 20
steps, 40 steps, 60 steps, etc., through 200 steps.
Because of the
stochastic decisions, the points plotted after n steps don't all fall
39
at the same place, but rather cluster about an approximate
position.
However one sees from Fig. Ala that these clusters are
linear, and that the clusters in Fig. Ala form slanted lines, while
those in Fig. Alb form vertical lines.
phenomena follows.
The explanation for these
Each step of the Rho4 algorithm, for aspects
between 0 and 90 degrees, will generate either a N decision (add 1
to y) or an E decision (add 1 to x), so the points reached after k
steps in Fig. Ala satisfy the equation y + x = k. Each step of the
Rho8 algorithm, for aspects between 0 and 90 degrees, will
generate either a NE decision (add 1 to y and 1 to x) or an E
decision (add 1 to x), so the points reached after k steps in Fig. Alb
satisfy the equation
x=k.
Rho4 follows perfect slopes with aspects that are multiples of 900
perfectly.
Rho8 does the same for multiples of 450°.
One sees from
Fig. Ala that the variability (the looseness of the clusters) for
method Rho4 is much greater near 45 degrees than it is near 0
degrees.
Indeed, the variability is greatest at 45 degrees, when
the P(N) = P(E) = 1/2.
Fig. Alb illustrates that the variability for
method Rho8 is greatest near atan(1/2), when P(NE) = P(E) = 1/2.
Table 1 summarizes the standard deviation (std) from these
40
experiments, for the worst cases.
For both Rho4 and Rho8 the
growth in std is sub-linear in N, the number of steps downhill (or
length); it appears greater than log(N) but less than
the path
sqrt(N).
Notice that the std of x and y in Table 1.a are equal, and
that the std of x in Table 1.a equals that of x in Table 1.b.
This is
as it should be given the constraints mentioned above (y+x=k for
Table 1.a, x=k for 1.b).
In what way is method Rho8 better than the other methods
presented?
Let "better than" be defined as follows.
Let S be the
set of planar surfaces (linear functions z(x,y)), and A and B be two
methods for finding lines of descent.
direction taken by method
Let D(M,o,n,s) be the
M during a trial on planar surface s, in
which one begins at point o and runs the method for n steps, to
determine where the method ends.
The direction is determined by
the beginning and ending points of the trial.
expected value of D(M,o,n,s).
deviation of D(M,o,n,s).
Let E[D(M,o,n,s)] be the
Let STD[D(M,o,n,s)] be the standard
Let a(s) be the aspect of planar surface s.
Let Method A be judged "better than" method B iff for all o and all
n, there exists s in S for which
I E[D(A,o,n,s)]-a(s) | < I E[D(B,o,n,s)]-a(s)
41
and for all s in S
I E[D(A,o,n,s)]-a(s) I <
(E[D(A,o,n,s)]-a(s)
E[D(B,o,n,s)]-a(s) I
or
= 0 and STD[D(A,o,n,s)] <= STD[D(B,o,n,s)]
)
Then for this rather strong notion of "better than", method Rho8 is
better than methods D8 and Rho4.
A4:
The Root algorithm:
A paged virtual memory system divides memory up into pieces of
about 1K that are called pages.
The virtual memory space actually
exists on the disk, which has much more memory space than the
internal (RAM) memory of the computer.
Whenever the program
starts working on a page of the array that is not currently in
internal memory (this event is called a "page fault"), the virtual
memory system reads the needed page from the disk, and brings it
42
into RAM.
However it first has to free up some space to copy the
new page into, i.e. it has to select some older page in RAM, and if
that page has been modified during its sojourn in RAM, copy it out
to its place on the disk. Only then can it read the new needed page
and put it in the RAM that had been occupied by the old page.
Selecting which "old" page to cull is a problem.
Nearly all virtual
memory systems either select the page that has been resident in
RAM the longest, or the page which has been used least recently.
To the best of our knowledge, the best previously published
algorithm for connected components for paged virtual memory
computers is that in Lumia et al. (1983).
This algorithm does two
complete scans of the array (here called "basin").
When the array
is larger than the amount of internal memory available to the
computer, each scan completed by the algorithm causes
a complete
10 scan of the array on the disk by the automatic virtual memory
system.
Worse, if the array is being modified by the algorithm (as is the
case for the algorithm in Lumia et al. (1983)), each page must be
both read and later written, and the disk head is kept shuttling
43
back and forth between the place where it is reading new parts of
the array, and writing old parts.
There's usually enough internal
memory so that at least a reasonable stretch of the array is kept in
RAM at a time, and here that actually works against you, because it
means that the place on the disk where the new pages are being
read is reasonably far from the place where the old pages are being
written.
You can think of the array as being mostly out on disk,
with only a horizontal slab of a dozen or so rows of the array being
held in RAM.
If the scan is from top down, new pages add rows to
the bottom of the slab, and space is scavenged from the top rows
of the slab.
(In a simple scan, the "longest resident" and the "least
recently used" strategies both select the same page.)
By "reasonably far", we mean that when a page fault occurs, the
page being written out and the page being read in are not likely to
be on the same disk track, so that the disk head has to move, which
takes a lot of time. Thus every page fault causes the disk head to
shuttle back and forth.
A single scan done in this shuttling fashion
is much slower than two scans done with no shuttling.
The interest of algorithm Root is that though it visits (reads or
writes) each element of the basin array up to five times,
44
all of the
visits to a given element occur quite close to one another in time.
In technical terms, this means that algorithm Root has good
"locality of reference".
Given reasonable assumptions about the
amount of real memory, it is very likely that the repeated visits do
not increase the amount of paging.
The first visit brings the pixel
into memory, and the subsequent visits will find it already in
memory.
By the time it is swapped out of memory, the algorithm is
done with it. Thus Root causes only one complete modifying scan.
Another algorithm with excellent locality of reference is the depth
first search algorithm used in Section IV.
Algorithm Root works only on a particular kind of graph, one where
each node (in our case, nodes are pixels) points to a node. The
number of pointers is equal to the number of nodes. In such a
structure every connected component has exactly one loop: we call
them looped trees (a tree is a connected component that has no
loops).
In our case the loop usually occurs where a node, the pit
pixel, points to itself, since all of its neighbors are higher than it.
But DEM's often contain perfectly level areas, and in such areas
more extended loops are common.
That these loops present no
difficulty is a very convenient feature of algorithm Root.
45
Now for the code of algorithm Root. The language is C. The
conceptually two-dimensional basin array is implemented as a
one-dimensional array.
root(basin)
mnt *basin;
j
mnt
i,j,k,l,pit,end,empty,loop;
empty=TRUE; loop=O;
for (i=N*M-1; i>=O; i--)
k=basinli];
if ((l=basin[k])!=k)
empty=FALSE;
j=i;
do
{
basino]
=k
--
j=k; k=l; l=basin[l];
} while (!(k==,l11 1<0));
if(l<0) loop++;
pit= k ;end =j;
j=i;
while (j!=end)
46
I
k= --,basinu];
bas in[j] =pit;
j=k;
fprintf(stderr,"No problem, but %d loops found in
root. \n" ,loop);
return (!empty);
47
Table 1.a
Worst case variability for Rho4, aspect 450, 1500 trials:
k steps
avg(x)
avg(y) std(x)
std(y)
atan(avg(y)/avg(x))
20
10.00
9.99
2.3
2.3
44.98
40
19.87
20.12
3.3
3.3
45.35
60
29.93
30.06
3.9
3.9
45.11
80
39.84
40.15
4.5
4.5
45.22
100
49.87
50.13
5.1
5.1
45.15
120
59.84
60.15
5.5
5.5
45.15
140
69.80
70.19
5.9
5.9
45.16
160
79.86
80.14
6.4
6.4
45.10
180
89.83
90.17
6.9
6.9
45.11
200
99.81
100.19
7.3
7.3
45.11
48
© Copyright 2026 Paperzz