====== - #2 Big Oh ====== In this lesson we will introduce our first asymptotic notation: the Big Oh, which can be used for expressing an upper bound for an algorithm's running time. In the previous lesson [[01_the_need_for_asymptotic_notation_a_case_study]] we proved theoretically that for sufficiently large $n$, the running time of the second algorithm satisfies $T_2(n) < dn$ where $d$ is some constant. Here is the figure of measured running times again: {{ asymptotics:readNumbers2.png?300 }} As said in the previous lesson, the figure confirms that we didn't make a mistake when calculating the theoretical upper bound: for example, from the figure one sees that $T_2(n) < 0.0021n$ if $n > 150$. Why bother with theoretical analysis at all if one can measure running times in practice? Well, sometimes we want to have a rough estimate on the running time to decide whether to implement an algorithm at all; estimating worst-case running time (as opposed to average running time) based on measurements only is also not reliable (there could be some possible inputs taking a very long time but it might happen that we don't hit any of them in our benchmark). It can be quite hard to theoretically make claims with explicitly computed constants like “$T_2(n) < 0.0021n$ if $n > 150$”, but it is much easier to prove weaker statements like “for sufficiently large $n$, $T_2(n) < dn$ where $d$ is some constant”, which still give a rough idea. In computer science, such weaker statements are used so often that a shorter way for writing them has been invented: instead of “for sufficiently large $n$, $T_2(n) < dn$ where $d$ is some constant”, one writes \[T_2 \in O(n).\] This is what is called the //Big Oh notation//. Before going to the general definition of Big Oh, let us note that in this and the following lessons, we will only talk about **positive functions**, i. e. functions whose values are positive real numbers. This is in order to simplify our definitions and properties of asymptotic notations a little. We will also assume that the function arguments are natural numbers. We will not demand the function to be defined and positive on all natural numbers, but only starting from some point (like $\log n$, which is defined and positive for $n \geq 2$). The function we are interested in will usually be the running time or memory consumption of an algorithm for given input size, which obviously satisfies these requirements (its value, i. e. running time or memory usage, is a positive real number, and the argument, i. e. the input size, is a natural number). **Definition (Big Oh).** Let $f$ and $g$ be two positive functions. We say that **$f$ grows asymptotically no faster than $g$** and write **$f\in O(g)$** if there exist constants $c\geq 0$ and $n_0$ such that for all $n \geq n_0$, we have that $f(n)\leq c\cdot g(n)$. {{:asymptotics:Big_Oh.png|size=200}} **Figure (Big Oh)**. $f\in O(g)$ means that there exist some constants $c$ and $n_0$ such that for all $n \geq n_0$, $f(n) \leq cg(n)$. We will sometimes also use the phrase **sufficiently large**: when saying “$P(n)$ for all sufficiently large $n$”, we mean “there exists $n_0$ such that $P(n)$ for all $n \geq n_0$”. So the definition of Big Oh can be rephrased like this: $f \in O(g)$ if and only if there exists a constant $c \geq 0$ such that $f(n) \leq c g(n)$ for all sufficiently large $n$. The Big Oh notation has two characteristic properties: - it ignores the values of $f$ and $g$ for small $n$ and - it also ignores constant factors: if, e. g. a function $f$ is linearly bounded, i. e. $f(n) \leq dn$ for a constant $d$, then we can simply write $f \in O(n)$ without factor $d$. If $f(n)$ is the running time of an algorithm for input size $n$, then this is usually indeed the most important information one needs about the algorithm's performance: - one really does not care how a running time behaves if it is sufficiently small; - multiplying the algorithm's running time by a moderate constant will not dramatically change the maximal input size for which the algorithm is usable — in contrast, replacing it with a more efficient algorithm can give an improvement of several orders of magnitude((Consider e. g. the algorithm ''readNumbers1'', which, with its quadratic running time, could within one second only handle inputs smaller than 3000 ($T_1(3000) \approx 1.3 \cdot 10^{-4} \cdot 3000^2 \text{ ms} \approx 1.2 \text{ s}$), and even if ''readNumbers1'' ran 100 times faster than it actually does, it could handle in a second only inputs smaller than 30,000 (i. e., 10 times larger inputs than before, since the running time is quadratic and $10^2=100$). On the other hand, ''readNumbers2'' with its linearly bounded running time is much faster, being able to handle $500,000$ elements in a second.)). The Big Oh is the oldest in a family of mathematical notations, called //asymptotic notations//, which can be used to express how a function behaves when its argument grows to infinity. The Big Oh was taken into use by mathematician Paul Bachmann in the end of the 19th century, but is sometimes called //the Landau symbol// for another mathematician, Edmund Landau, who soon adopted it (the name //Landau symbol// is actually also used for a related asymptotic notation, the //little oh//; the latter was indeed introduced by Landau). For analyzing the performance of algorithms, the Big Oh has been popularized by the great computer scientist Donald Knuth, who also invented some other asymptotic notations (like the Big Omega, which we will meet later). Following Knuth, the Big Oh should actually be called the Big Omicron (a Greek letter that looks like the Latin O) — but most people still use Oh since this is easier to say and type. Which of the following statements is true? (Justify your answer.) - $n \in O(2n+1)$ ++Solution| True. Obvious (as the constant $c$ and $n_0$ in the definition of Big Oh we may take e. g. $c = 1$ and $n_0 = 0$).++ - $2n+1 \in O(n)$ ++Solution| True. Indeed, $2x+1 \leq 3x$ for all $x \geq 1$ (i. e., we can take $n_0 = 1$ and $c = 3$ in the definition of Big Oh).\\ {{:asymptotics:2n_plus_1_and_n.png}} ++ - $3n \in O(2n^2)$ ++Solution| True. Note that for $x > 0$, the inequality $3x \leq 2x^2$ is equivalent to $1.5 \leq x$ (we divided both sides of the inequality by the positive number $2x$). So, $3n \leq 2n^2$ for all natural numbers $n \geq 2$, Q. E. D.((“Q. E. D.” reads “quod erat demonstrandum” which means in Latin “which was to be proven”, indicating the end of a proof.))\\ \\ Geometrically, the graph of the function $y = 2x^2$ is an upwards-oriented parabola and the graph of $y = 3x$ is a line with positive slope. Actually, it is a rather intuitive geometrical fact that an upwards-oriented parabola through the origin always intersects twice a line with positive slope going through the origin, so that the second intersection point lies to the right of the origin and to the right of that point, the parabola lies higher than the line.\\ {{:asymptotics:parabola_and_line.png}} ++ - $2n^2 \in O(3n)$ ++Solution| False. Let's suppose that $2n^2 \in O(3n)$ and show that this would give a contradiction. Indeed, $2n^2 \in O(3n)$ would mean that there exist $c$ and $n_0$ such that $2n^2 \leq 3cn$ for all $n \geq n_0$. Obviously then $c > 0$. Now take $m = \max \{2c,\ n_0\}$. Then $2m^2 \geq 4cm > 3cm$ (thanks to the inequalities $m \geq 2c$, $c > 0$ and $m > 0$), but at the same time $2m^2 \leq 3cm$ (since $m \geq n_0$) — a contradiction, Q. E. D.++ - $2\in O(1)$. ++Solution| True. This statement should be interpreted as $f \in O(g)$ where $f$ and $g$ are the constant functions $f(n)=2$, $g(n)=1$. It is obviously true: as the constant $c$ and $n_0$ in the definition of Big Oh we may take $c = 2$ (or any larger number) and $n_0 = 0$ (or any other natural number). ++ - $\log_2 n\in O(n)$. ++Solution| True. Indeed, for all natural numbers $n > 0$, $\log_2 n \leq n$. To get this inequality, take the logarithm of the more obvious inequality $n \leq 2^n$. If the latter inequality is not obvious to you, use mathematical induction to convince yourself: $n \leq 2^n$ holds for $n = 0$, so we only have to prove that if it holds for some $n$, then it also holds for $n+1$. But that is easy to see: if we increase $n$ by $1$, then the left side of the inequality grows by $1$ but the right side doubles; since the right side is $\geq 1$, its doubling means it grows at least by $1$, so it must remain larger than the left side.\\ {{:asymptotics:log_and_n.png}} ++ ===== - Ways to estimate asymptotic complexity ===== Given two functions $f$ and $g$, how to determine whether $f \in O(g)$ or not? We have already done it, using straightforwardly the definition of Big Oh, for some pairs of functions (we proved that $T_2 \in O(n)$ and some more such statements in the exercises), but actually there is a general approach which turns out very useful: this is to look at how their ratio $\frac{f(n)}{g(n)}$ behaves. Indeed, $f \in O(g)$ means that there exists some $c$ such that $f(n) \leq cg(n)$ for sufficiently large $n$; dividing this inequality by $g(n)$ (and recalling that we assume $g(n) > 0$), we get an equivalent inequality $\frac{f(n)}{g(n)} \leq c$. So we get the following criterion: **Criterion 1 (Big Oh means bounded ratio).**. Let $f$ and $g$ be positive functions. We have $f \in O(g)$ if and only if the ratio $\frac{f(n)}{g(n)}$ is bounded for sufficiently large $n$ (i. e., there exists some constants $c$ and $n_0$ such that $\frac{f(n)}{g(n)} \leq c$ for all $n \geq n_0$). For example, let's check whether $T_1(n) \in O(n^2)$ where $T_1(n)$ is the running time of our algorithm ''readNumbers1'' in lesson [[01_the_need_for_asymptotic_notation_a_case_study]]. In that lesson, we got the formula $T_1(n) = \frac{c}2n^2 + (d-\frac{c}2)n + e$ where $c$, $d$ and $e$ are some constants. The ratio is $\frac{T_1(n)}{n^2} = \frac{c}2 + (d-\frac{c}2)\frac1n + \frac{e}{n^2}$. Obviously we can make the last two terms as small as we like by choosing $n$ large enough. For example, there exist a number $n_0$ such that for all $n \geq n_0$, we have $(d-\frac{c}2)\frac1n < 0.1$ and $\frac{e}{n^2} < 0.1$. So $\frac{T_1(n)}{n^2} \leq \frac{c}2 + 0.2$ for sufficiently large $n$. Therefore, we have proven that $T_1 \in O(n^2)$. As the following diagram shows, measurements agree that ratio is indeed bounded: it appears that starting from $n \geq 50$ we have $\frac{T_1(n)}{n^2} < 2 \cdot 10^{-4}$. {{:asymptotics:readNumbers1_n2_ratio.png}} Now let's check whether $T_1(n) \in O(n)$. The ratio is $\frac{T_1(n)}{n} = \frac{c}2 n + (d-\frac{c}2) + \frac{e}{n}$. The first term grows to infinity as $n \to \infty$, the second term is a constant and the third one goes to $0$ as $n \to \infty$, therefore the whole sum grows to infinity as $n \to \infty$. So the ratio $\frac{T_1(n)}{n}$ is not bounded in the process $n \to \infty$ (for any $c$ and $n_0$ there exists $n \geq n_0$ such that $\frac{T_1(n)}{n} > c$) and therefore we have proven that $T_1(n) \not\in O(n^2)$. The following diagram shows that measurements agree with the analysis: the ratio appears not to be bounded by any number but grow linearly to infinity. {{:asymptotics:readNumbers1_n_ratio.png}} Actually, often we can make our life even easier using the concept of limit. (To recall the definition and properties of the limit of a function, see page [[:limit:Limit]].) Namely, if the limit $\lim_{n \to \infty} \frac{f(n)}{g(n)}$ exists then the ratio $\frac{f(n)}{g(n)}$ is bounded for sufficiently large $n$ if and only if the limit is finite; so, in order to determine whether $f \in O(g)$, it suffices to calculate the limit of the ratio of the functions. For example, let's recheck the statements $T_1 \in O(n^2)$ and $T_1 \in O(n)$. Since $\lim \frac{T_1(n)}{n^2} = \lim \frac{c}2 + \lim (d-\frac{c}2)\frac1n + \lim \frac{e}{n^2} = \frac{c}2 + 0 + 0 = \frac{c}2 < \infty$ but $\lim \frac{T_1(n)}{n} = \lim \frac{c}2 n + \lim (d-\frac{c}2) + \lim \frac{e}{n} = \infty + (d-\frac{c}2) + 0 = \infty$, we can immediately conclude that the first ratio is bounded for sufficiently large $n$ but the second one is not; hence $T_1 \in O(n^2)$ but $T_1 \not\in O(n)$. Looking at the $\frac{T_1(n)}{n^2}$ ratio diagram once more, we notice that measurements agree with the analysis that the ratio converges: from the diagram it looks like $\lim \frac{T_1(n)}{n^2} \approx 1.3 \cdot 10^{-4}$. {{:asymptotics:readNumbers1_n2_ratio_limit.png}} So we found the following general criterion for determining whether $f \in O(g)$. **Criterion 2 (Finite limit of ratio implies Big Oh).** Let $f$ and $g$ be positive functions. If $\lim_{n \to \infty} \frac{f(n)}{g(n)}$ exists, then $f \in O(g)$ if and only if $\lim_{n \to \infty} \frac{f(n)}{g(n)} < \infty$. In some nasty cases, Criterion 2 cannot be applied since the limit does not exist. It turns out that an example is our function ''readNumbers2'': {{:asymptotics:readNumbers2_n_ratio.png}} The diagram suggests that the ratio $\frac{T_2(n)}{n}$ does not converge to any particular number but keeps oscillating somewhere between 0.0021 and 0.0018; hence Criterion 2 cannot be used.((To be honest, we cannot be sure whether a function converges only by looking at a diagram, since we do not see how the function behaves at the very large values of $n$ which were left out of the plot. Actually in this case theoretical analysis can confirm that $\frac{T_2(n)}{n}$ indeed doesn't converge, but we won't do it here.)) Nevertheless, the ratio appears to be bounded for sufficiently large $n$ (the diagram suggests that $\frac{T_2(n)}{n} < 0.0021$ for $n > 150$) and this, by Criterion 1, means that $T_2 \in O(n)$. So this diagram agrees with our theoretical calculations in the first chapter that $T_2 \in O(n)$. For most functions one encounters, however, the limit $\frac{f(n)}{g(n)}$ exists and Criterion 2 is useful. Which of the following statements is true? (Justify your answer.) - $n^{23}\in O(n^{24})$. ++Solution| True. Indeed, $\lim_{n \to \infty} \frac{n^{23}}{n^{24}} = 0 < \infty$. Alternatively, this statement is also obvious from the definition of $Big Oh$, since for any $n \geq 1$, $n^{23} \leq n^{24}$.++ - $n^{23}\in O(n^{22})$.++Solution| False. Indeed, $\lim_{n \to \infty} \frac{n^{23}}{n^{22}} = \infty$. ++ - $n^{23}+n^3\in O(n^{23}+4)$. ++Solution| True. To calculate the limit of the ratio, we do a little trick: namely we divide both the nominator and the denumerator by $n^{23}$, finding that $\frac{n^{23}+n^3}{n^{23}+4} = \frac{\frac{n^{23}}{n^{23}}+\frac{n^3}{n^{23}}}{\frac{n^{23}}{n^{23}}+\frac4{n^{23}}} = \frac{1+\frac1{n^{20}}}{1+\frac4{n^{23}}}$. Since $\lim 1+\frac1{n^{20}} = \lim 1 + \lim \frac1{n^{20}} = 1 + 0 = 1$ and $\lim 1+\frac4{n^{23}} = 1$, we have $\lim \frac{n^{23}+n^3}{n^{23}+4} = \lim \frac{1+\frac1{n^{20}}}{1+\frac4{n^{23}}} = \frac{\lim 1+\frac1{n^{20}}}{\lim 1+\frac4{n^{23}}} = \frac{1}{1} = 1$.++ - $12034273842374923+n^{23}+10+n^3\in O(12034273842374923)$. (The long number is the same on both sides.) ++Solution| False. Denoting $a = 1/12034273842374923$, we see that the ratio $\frac{12034273842374923+n^{23}+10+n^3}{12034273842374923} = an^{23} + an^3 + 10a + 1$ converges to infinity as $n \to \infty$.++ - $n \in O(\log_2 n)$. ++Solution| False. It is a well known fact that $\lim_{x \to \infty} \frac{x^d}{(\log_a x)^b} = \infty$ for any constants $a > 0, b > 0, d > 0$. (This can be proven using L'Hospital's rule. You may also consult Wolfram Alpha for difficult limits, [[http://www.wolframalpha.com/input/?i=limit+n%2Flog%282%2Cn%29+as+n-%3Einfinity|like this]].) Therefore, $\lim_{n \to \infty} \frac{n}{\log_2 n} = \infty$. ++ - $n \in O(3^n)$. ++Solution| True. It is a well known fact that $\lim_{x \to \infty} \frac{x^d}{a^{x}} = 0$ for any constants $a > 0, d > 0$. (This can be proven using L'Hospital's rule. You may also consult Wolfram Alpha for difficult limits, [[http://www.wolframalpha.com/input/?i=limit+n%2F3^n+as+n-%3Einfinity|like this]].) Therefore, $\lim_{n \to \infty} \frac{n}{3^n} = 0 < \infty$. ++ - $3^n \in O(n)$. ++Solution| False. In the solution of the previous statement, we used the fact that $\lim_{n \to \infty} \frac{n}{3^n} = 0$. This implies that $\frac{3^n}{n} = \frac1{\frac{n}{3^n}}$ converges to $\infty$. ++ **Lemma (Some properties of big Oh).** - If $f\in O(g)$ and $a > 0$ then $a\cdot f\in O(g)$. ++ Proof | Suppose $f\in O(g)$. By the definition of Big Oh, this means that there exist numbers $c$ and $M$ such that for all $n \geq M$, we have $f(n) \leq c g(n)$.\\ {{asymptotics:O_multiplication_by_constant_1.png}}\\ We have to show that $a \cdot f\in O(g)$, i. e. that there exists some numbers $d$ and $N$ such that for all $n \geq N$, we have $a \cdot f(n) \leq d g(n)$. Obviously this is true if we take $N = M$ and $d = ac$, Q. E. D. The picture below illustrates the situation.\\ {{asymptotics:O_multiplication_by_constant_2.png}} ++ - If $f_1\in O(g_1)$ and $f_2\in O(g_2)$ then $f_1+f_2\in O(g_1+g_2)$. ++Proof | Suppose $f_1\in O(g_1)$ and $f_2\in O(g_2)$. By the definition of Big Oh, this means that there exist numbers $c_1$, $c_2$, $M_1$ and $M_2$ such that for all $n \geq M_1$, $f_1(n) \leq c_1 g_1(n)$ and for all $n \geq M_2$, $f_2(n) \leq c_2 g_2(n)$.\\ {{asymptotics:O_addition_1.png}} {{asymptotics:O_addition_2.png}}\\ We have to show that there exist numbers $c_3$ and $M_3$ such that for all $n \geq M_3$, $f_1(n) + f_2(n) \leq c_3 (g_1(n) + g_2(n))$. We will show that one way to choose these two numbers is as follows: $c_3 := \max(c_1, c_2)$ and $M_3 := \max(M_1, M_2)$. Since $f_1(n) \leq c_1 g_1(n)$ for all $n \geq M_1$ and $c_3 \geq c_1$ and $M_3 \geq M_1$, the equality $f_1(n) \leq c_3 g_1(n)$ holds for all $n \geq M_3$. Analogously $f_2(n) \leq c_3 g_2(n)$ for all $n \geq M_3$. Adding these two inequalities, we have $f_1(n) + f_2(n) \leq c_3 g_1(n) + c_3 g_2(n)$ for all $n \geq M_3$.\\ {{asymptotics:O_addition_3.png}}\\ Q. E. D. ++ - If $f_1\in O(g_1)$ and $f_2\in O(g_2)$ then $f_1\cdot f_2\in O(g_1\cdot g_2)$. - If $f_1,f_2\in O(g)$ then $f_1+f_2\in O(g)$. - If $f_1 \in O(f_2)$ and $f_2\in O(g)$, then $f_1\in O(g)$. - If $g_1 \in O(g_2)$, then $g_1+g_2 \in O(g_2)$. - If $f\in O(g)$ and $\lim_{n \to \infty} b(n) = \infty$ then $\sum_{i=1}^{b(n)} f(i)\in O(\sum_{i=1}^{b(n)} g(i))$. The following exercise demonstrates the power of asymptotic notation: using Big Oh estimates, one can get some idea about an algorithm's performance even if the exact expression for the running time is too difficult to calculate. (Of course, for some applications we might need the precise number of steps — in such cases, we cannot use asymptotic notation. But otherwise, asymptotics make life easier.) Assume that you are analyzing the running time of an algorithm. Your analysis reveals: * The subroutine $f(a)$ does at most $a^2$ multiplications of integers of length $a$. * Besides that, $f(a)$ does some additional stuff. This additional stuff takes less time than $a$ multiplications, except if $a **Lemma (Big Oh relations of some well-known functions).** - $p(n) \in O(n^k)$ if $p$ is a polynomial of degree $k$. - $n^k \in O(a^n)$ for any constant real numbers $a > 1$ and $k > 0$. - $(\log_a n)^k \in O(n^l)$ for any constant real numbers $a > 1$, $k > 0$ and $l > 0$. - $\log_a n \in O(\log_b n)$ for any constant real numbers $a > 1$ and $b > 1$. - $a^n \in O(b^n)$ for any constant real numbers $b \geq a > 0$. [[asymptotics:03_big_omega]] ------------------------------------------------------------------------------------------------------------------------------