0:00

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.

3:29

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.