In this lecture, we'll continue our formal treatment of asymptotic notation. We've
already discussed big O notation, which is by far the most important and ubiquitous
concept that's part of asymptotic notation, but, for completeness, I do want to tell you
about a couple of close relatives of big O, namely omega and theta. If big O is
analogous to less than or equal to, then omega and theta are analogous to greater
than or equal to, and equal to, respectively. But let's treat them a
little more precisely. The formal definition of omega notation closely
mirrors that of big O notation. We say that one function, T of N, is big omega of
another function, F of N, if eventually, that is for sufficiently large
N, it's lower bounded by a constant multiple of F of N. And we quantify the ideas of a
constant multiple and eventually in exactly the same way as before, namely via
explicitly giving two constants, C and N naught, such that T of N is bounded below by
C times F of N for all sufficiently large N. That is, for all N at least N naught.
There's a picture just like there was for big O notation. Perhaps we have a function
T of N which looks something like this green curve. And then we have another
function F of N which is above T of N. But then when we multiply F of N by one half,
we get something that, eventually, is always below T of N. So in this picture,
this is an example where T of N is indeed big Omega of F of N. As far as what the
constants are, well, the multiple that we use, C, is obviously just one half. That's
what we're multiplying F of N by. And as before, N naught is the
crossing point between the two functions. So, N naught is the point after which C
times F of N always lies below T of N forevermore. So that's Big Omega. Theta
notation is the equivalent of equals, and so it just means that the
function is both Big O of F of N and Omega of F of N. An equivalent way to think
about this is that, eventually, T of N is sandwiched between two different constant
multiples of F of N. I'll write that down, and I'll leave it to you to verify that
the two notions are equivalent. That is, one implies the other and vice versa. So
what do I mean by T of N is eventually sandwiched between two multiples of F of N?
Well, I just mean we choose two constants. A small one, C1, and a big constant, C2,
and for all N at least N naught, T of N lies between those two constant multiples.
One way that algorithm designers can be quite sloppy is by using O notation instead of theta notation.
So that's a common convention and I will follow that convention often in this class.
Let me give you an example. Suppose we have a subroutine, which does a linear scan
through an array of length N. It looks at each entry in the array and does a constant amount of work
with each entry. So the merge subroutine would be more or less an example of a subroutine of that type.
So even though the running time of such an algorithm, a subroutine, is patently
theta of N, it does constant work for each of N entries, so it's exactly theta of N,
we'll often just say that it has running time O of N. We won't bother
to make the stronger statement that it's theta of N. The reason we do that is because
you know, as algorithm designers, what we really care about is upper bounds.
We want guarantees on how long our algorithms are going to run,
so naturally we focus on the upper bounds and not so much on the lower bound side.
So don't get confused. Once in a while, there will a quantity which is obviously theta of F of N,
and I'll just make the weaker statement that it's O of F of N.
The next quiz is meant to check your understanding of these three concepts:
Big O, Big Omega, and Big Theta notation.
So the final three responses are all correct, and I
hope the high level intuition for why is fairly clear. T of N is definitely a
quadratic function. We know that the linear term doesn't matter much as it
grows, as N grows large. So since it has quadratic growth, then the third response
should be correct. It's theta of N squared. And it is omega of N. So Omega
of N is not a very good lower bound on the asymptotic rate of growth of T of N,
but it is legitimate. Indeed, as a quadratic growing function, it grows
at least as fast as a linear function. So it's Omega of N. For the same reason, big
O of N cubed, it's not a very good upper bound, but it is a legitimate one, it is
correct. The rate of growth of T of N is at most cubic. In fact, it's at most
quadratic, but it is indeed, at most, cubic. Now if you wanted to prove these
three statements formally, you would just exhibit the appropriate constants. So for
proving that it's big Omega of N, you could take N naught equal to one, and
C equal to one-half. For the final statement, again you could take N naught
equal to one. And C equal to say four. And to prove that it's theta of N squared you
could do something similar just using the two constants combined. So N naught would
be one. You could take C1 to be one-half and C2 to be four. And I'll leave it to you to
verify that the formal definitions of big omega, big theta, and big O would be
satisfied with these choices of constants. One final piece of asymptotic notation,
we're are not going to use this much, but you do see it from time to time so I
wanted to mention it briefly. This is called little O notation, in contrast to
big O notation. So while big O notation informally is a less than or equal to type
relation, little O is a strictly less than relation. So intuitively it means that one
function is growing strictly less quickly than another. So formally we say that a
function T of N is little O of F of N, if and only if for all constants C, there is
a constant N naught beyond which T of N is upper bounded by this constant multiple C
times by F of N. So the difference between this definition and that of Big-O notation, is
that, to prove that one function is big O of another, we only have to
exhibit one measly constant C, such that C times F of N is upper bound,
eventually, for T of N. By contrast, to prove that something is little O of
another function, we have to prove something quite a bit stronger. We have to
prove that, for every single constant C, no matter how small, for every C, there
exists some large enough N naught beyond which T of N is bounded above by C times F
of N. So, for those of you looking for a little more facility with little O
notation, I'll leave it as an exercise to prove that, as you'd expect for all
polynomial powers K, in fact, N to the K minus one is little O of N to the K. There
is an analogous notion of little omega notation expressing that one function
grows strictly quicker than another. But that one you don't see very often, and I'm
not gonna say anything more about it. So let me conclude this video with a quote
from an article, back from 1976, about my colleague Don Knuth, widely regarded as
the grandfather of the formal analysis of algorithms. And it's rare that you can
pinpoint why and where some kind of notation became universally adopted in the
field. In the case of asymptotic notation, indeed, it's very clear where it came
from. The notation was not invented by algorithm designers or computer
scientists. It's been in use in number theory since the nineteenth century. But
it was Don Knuth in '76 that proposed that this become the standard language for
discussing rate of growth, and in particular, for the running time of
algorithms. So in particular, he says in this article, "On the basis of the issues
discussed here, I propose that members of SIGACT," this is the special
interest group of the ACM, which is concerned with theoretical computer
science, in particular the analysis of algorithms. So, "I propose that the members
of SIGACT and editors in computer science and mathematics journals adopt the O,
omega, and theta notations as defined above unless a better alternative can be
found reasonably soon. So clearly a better alternative was not found and ever since
that time this has been the standard way of discussing the rate of growth of
running times of algorithms and that's what we'll be using here.