by William Shoaff with lots of help
You can download a postscript version of this file (which is prettier) at
Alice, of course, is Lewis Carroll's Alice from ``Through the Looking-glass'' and ``Alice's Adventures in Wonderland.'' In `Queen Alice' from ``Through the Looking-glass,'' the Red and White Queen are speaking with Alice about ``manners'' and ``lessons'' when
`Can you do Addition?' the White Queen asked.What's one and one and one and one and one and one and one and one and one and one?'
`I don't know,' said Alice. 'I lost count.'
`She can't do Addition,' the Red Queen interrupted.
`Can you do Subtraction? Take nine from eight.'
Counting single operations that occur repeatedly is the most fundamental problem
in algorithm analysis. Fortunately, we've learned to count and add many, many years
ago. To count one operation over and over we use summation notation:
for (int k=0; k < n; k++) { ip += u[k] * v[k]; }
The most simple answer is to say that ip += u[k] * v[k]
is one operation, in which case the time complexity (or running time) is
Associated with the sum is the sequence of values to be added,
in this case
We'd like add all the terms in the Alice sequence, but of course
we can't because the result is infinite. However, if we multiply
each term in the sequence by a power of variable z we can formally
evaluate the infinite sum (or series).
A (singly-nested) for loop usually gives rise to a a summation of a constant value (which we can assume is normalize to the value 1).
for (int k=0; k < n; k++) { do one thing; }
You should be able to identify the similarity between the for loop and the summation.
The Gauss sum is named for a story that's described in E.T. Bell's ``Men of Mathematics.'' Carl Friedrich Gauss (1777-1855) is considered the greatest mathematician of his time and the equal of Archimedes and Isaac Newton.
It seems that Gauss' third grade teacher needed a break so she assigned the class the problem of totaling the sum of the first 100 integers thinking that this would occupy the students for most of the afternoon.More generally, we haveGauss of course was able to tabulate the sum in a matter of seconds to the chagrin of his teacher. What Gauss needed to compute is:
![]()
It should come as no surprise that doubly-nested for loop give rise to a Gauss sum. Consider the doubly-nested loops:
int t1 = 1 - t;
for (j=1; j<= n; j++) {
for (i=0; i<= n - j; i++) {
c[i]= t1 * c[i] + t * c[i+1] ;
}
}
which are from the de Casteljau algorithm for evaluating points
on a Bézier curve.
To count the operations, we declare
c[i]= t1 * c[i] + t * c[i+1] to be
one operation, and count how many times it executes inside the
inner loop using an Alice sum:
Associated with the Gauss sum is the sequence of values to be added,
in this case
We'd like add all the terms in the Gauss sequence, but of course
we can't because the result is infinite. However, if we multiply
each term in the sequence by a power of variable z we can formally
evaluate the infinite sum (or series).
A double-nested for loop usually gives rise to a a summation of natural numbers
for (int k=0; k < n; k++) {
for (int j=0; j < k; j++) { do one thing; }
}
You should be able to identify the similarity between the for loops and the summations. Notice that things are a little more complex since the loop bounds on the inner loop may depend on the loop index of the outer loop.
The Zeno sum is named for Zeno of Elea, a Greek philosopher, who argued that he could never be killed by and arrow since one would always have to travel halfway from its current position toward his heart, and so could never reach its target. This is an experiment Zeno should not have tried!
If the original distance is 2 units from 0, then the halfway point is 1,
and the next halfway point is 1/2, the next is 1/4, and so on.
Thus Zeno argues that you can only add up a finite number of these term
and the result is always less than two, but we know you can sum
the series
The Zeno sum would truncate the series at some finite upper bound nyielding:
Zeno-type sums arise naturally from recursive algorithms. Consider the inorder binary tree traversal algorithm below.
public void inorderTreeWalk(x) {
if (x != null) {
inorderTreeWalk(x.left());
x.print();
inorderTreeWalk(x.right());
}
}
And assume that the binary tree is balanced so that one-half of the
nodes are in the left subtree and the other half are in the right subtree.
We'll find that the time complexity of this algorithm is (roughly) described by the
recurrence relation
To traverse a binary tree, take two walks: one down the left half and one down the right half, stopping in between to print the information at the current node.In any event, there are several ways which we will learn later that allow us to write the recurrence relation as:
Associated with the Zeno sum is the sequence of values to be added,
in this case
We'd like add all the terms in the Zeno series, and
we can because the result is finite. However, following the
established custom, we multiply
each term in the sequence by a power of variable z we formally
evaluate the infinite sum (or series).
Geometric sums often arise when analyzing recursive algorithms.
This analysis leads to recursion relations with
initial conditions such as:
The best book I know for the topics discussed in these notes is Concrete Mathematics: A Foundation for Computer Science by Ron Graham, Don Knuth, and Oren Patashnik [3]. However, you may be want to start with a more elementary book. Most discrete mathematics books have a section on sums, sequences, and generating functions, for example, see [4]. Finally, most books on the analysis of algorithms have information on sums, sequences, and series, see, for example, [2] or [1].
public int binomialCoefficient(int n, int j) {
int r=0;
for (int i = 1; i < n; i++) {
for (j = i+1; j <= n; j++) {
for (int k = 1; k <= j; k++) { r = r+1; }
}
}
return r;
}
public void decompose(double c) {
int h = c.length/2;
for (int i = 1; i < h; i++) {
scratch[i] = (c[2i-1] + c[2i])/2.0;
scratch[h+i] = (c[2i-1] - c[2i])/2.0;
}
c = scratch;